Skip to content

feat(workspace): name tonight's first tuning plan on the map - #1010

Open
seonghobae wants to merge 15 commits into
developfrom
feat/workspace-first-tuning-plan
Open

feat(workspace): name tonight's first tuning plan on the map#1010
seonghobae wants to merge 15 commits into
developfrom
feat/workspace-first-tuning-plan

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Buyer next action

The mounted rehearsal workspace now names tonight's first tuning plan so a part can lock the owned tuning before rehearsal starts.

Demo: Bass Guitar still has Tune the E string down to D so the verse riff sits on the open fifth. Open is the next action: it moves to the matching rendered song-structure section.

Protected base: develop@acdbea6344fe1231c39535b575f4de35e4c607c9.
Exact current head: 8c4f173230bc0323ed63afa72f761494f983a267 on feat/workspace-first-tuning-plan.

What the player sees

  • The callout names the owning part when an active graph node corroborates it, the owned tuningPlan copy, the labeled section, and the time.
  • Open scrolls the renderer-owned song-structure section and arms the next action: lock that tuning before the room starts.
  • If no part owns rehearsal-facing tuning copy, the card stays guidance-only. Stay on tonight's map.

Authority boundary

Docs

AGENTS.md, CLAUDE.md, ARCHITECTURE.md, CHANGELOG.md, and docs/design-system/component-contract.md name this next action. Reduced-motion Open uses behavior: "auto".

Security Notes

  • Attack surface: untrusted rehearsal-song runtime metadata (sections, roles, partGraph, identity accessors) plus DOM navigation against the mounted song-structure renderer.
  • Trust boundary: only own data properties on dense collections are read. Inherited/accessor/sparse/hostile getters fail closed to null and keep the callout guidance-only.
  • Navigation authority is the renderer-owned section index, not analysis ids.
  • Logging/privacy: no path, filename, or rejected-metadata echo.
  • Test points: inherited-metadata suite, particle-safe Korean copy, reduced-motion scroll, workspace-scope renderer selection, Workspace navigation. Shared-types 20/20 at 100%. Desktop 241/241 at 100% gated coverage. Typecheck clean.

Dependency / merge gate

  • fix(security): establish canonical npm, PDF.js, Nanoid, and Undici baseline #783 remains the canonical protected JavaScript dependency-security owner. Inherited pdfjs-dist / nanoid / undici HIGH findings are not copied or suppressed here. No lockfile change.
  • Keep unmerged until the unchanged then-current head has every applicable repository/central CI, cross-platform build, exact owned statement+branch coverage, docstring, SAST/security/SBOM/supply-chain/package/release gate terminal-success; zero valid unresolved findings; a qualifying independent non-author last-push approval; and ordinary branch-protection acceptance.
  • Queued, pending, skipped, cancelled, failed, predecessor-head, protected-base, model-only, self/author, or administrative-bypass evidence is not success.
  • Never bypass protection or transfer predecessor evidence.
  • Do not self-approve.

Open in Devin Review

Name the owning part, owned tuningPlan copy, labeled section, and time
so a player can lock that tuning before rehearsal. Open scrolls the
renderer-owned song-structure section.
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

Next included review available in 58 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 77292df5-7cbc-4df2-a5d8-8ac489b491ae

📥 Commits

Reviewing files that changed from the base of the PR and between acdbea6 and 9ec453d.

📒 Files selected for processing (26)
  • AGENTS.md
  • ARCHITECTURE.md
  • CHANGELOG.md
  • CLAUDE.md
  • apps/desktop/src/features/workspace/FirstTuningPlanCallout.memoization.test.tsx
  • apps/desktop/src/features/workspace/FirstTuningPlanCallout.particle.test.tsx
  • apps/desktop/src/features/workspace/FirstTuningPlanCallout.reduced-motion.test.tsx
  • apps/desktop/src/features/workspace/FirstTuningPlanCallout.test.tsx
  • apps/desktop/src/features/workspace/FirstTuningPlanCallout.tsx
  • apps/desktop/src/features/workspace/FirstTuningPlanCallout.workspace-scope.test.tsx
  • apps/desktop/src/features/workspace/Workspace.test.tsx
  • apps/desktop/src/features/workspace/Workspace.tsx
  • apps/desktop/src/features/workspace/firstTuningPlan.inherited-metadata.test.ts
  • apps/desktop/src/features/workspace/firstTuningPlan.proxy-authority.test.ts
  • apps/desktop/src/features/workspace/firstTuningPlan.test.ts
  • apps/desktop/src/features/workspace/firstTuningPlan.ts
  • apps/desktop/src/features/workspace/tuningCoverageContract.test.ts
  • apps/desktop/src/i18n/index.test.ts
  • apps/desktop/src/i18n/index.ts
  • apps/desktop/src/locales/en/common.json
  • apps/desktop/src/locales/ko/common.json
  • apps/desktop/vite.config.ts
  • docs/design-system/component-contract.md
  • docs/doctoring/reduced-motion-first-tuning-plan-navigation.md
  • packages/shared-types/src/index.ts
  • packages/shared-types/test/index.test.ts
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/workspace-first-tuning-plan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

Open in Devin Review

Comment on lines +63 to +76
function resolveTuningPlanRenderer(origin: HTMLElement): HTMLElement | null {
const selector = '[data-testid="song-structure-grid"]';
const localScope = origin.closest("aside")?.parentElement ?? null;
const localRenderers = localScope?.querySelectorAll<HTMLElement>(selector) ?? [];
if (localRenderers.length === 1) {
return localRenderers[0] ?? null;
}
if (localRenderers.length > 1) {
return null;
}

const globalRenderers = document.querySelectorAll<HTMLElement>(selector);
return globalRenderers.length === 1 ? (globalRenderers[0] ?? null) : null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Renderer scoping fails closed on ambiguity

resolveTuningPlanRenderer returns null when the callout's local scope holds 0 or more than one song-structure-grid. Only Workspace.tsx emits that testid today, so scoping holds. Adding a second grid to the same CardContent would make Open silently do nothing.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant