Skip to content

feat(workspace): name tonight's first harmonic explanation on the map - #1003

Open
seonghobae wants to merge 25 commits into
developfrom
feat/workspace-first-harmonic-explanation
Open

feat(workspace): name tonight's first harmonic explanation on the map#1003
seonghobae wants to merge 25 commits into
developfrom
feat/workspace-first-harmonic-explanation

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Product outcome

The mounted rehearsal workspace now names tonight's first owned harmonic explanation so the room can play from that reason before starting. Open moves to the matching rendered map section. The next action is to play from that explanation at that time, not to guess from a function label, groove, cue, or confirmed chord.

Exact current identity

Buyer-visible contract

  • Name the owning part when an active section-local graph node corroborates it, the owned harmonicExplanation copy, the labeled section, and the time.
  • Do not invent that copy from groove, cue text, setupNote, simplification, overlap warnings, range copy, harmony.chord, harmony.functionLabel, confirmed overrides, or confidence notes.
  • Open scrolls the renderer-owned song-structure child by data-section-index. Analysis section.id is never DOM-ID authority.
  • Keep the unavailable state guidance-only.
  • Korean copy stays particle-safe ({role} 파트) and localizes the section form label.
  • Reduced motion uses immediate scroll; otherwise smooth scroll.
  • Distinct from first-confirmed-harmony, first-ear-check, first-overlap, first-groove, and first-form-label work.
  • Design contract: docs/design-system/component-contract.md (workspace next-action pattern). Figma 19-239 remains the Storybook token surface (feat(workspace): Storybook tokens for rehearsal components #897).

Security Notes

Attack surface

  • Untrusted input: song, section, time-range, role, harmonicExplanation, and section-local graph metadata.

Trust boundary

  • Own-data record guards, dense array checks, renderer-owned navigation targets, one-shot copy interpolation, 180 code-point explanation bound.

Mitigations

Test points

  • Resolver skips blank, inherited, accessor-backed, inactive, duplicate-id, unbounded, and function-label-only explanations.
  • Callout names Bass Guitar at 0:10 on the demo song, scrolls renderer-owned index 0, arms the next action, and stays particle-safe in Korean.

Dependency and Supply Chain

  • No new direct dependency was added
  • If a new dependency was added, this PR explains why it is needed
  • runtime / dev / build / test classification is recorded
  • alternatives were considered
  • maintainer trust and update health were checked
  • license fit was checked
  • known security issues were checked
  • transitive footprint impact was considered
  • SBOM or supplemental inventory impact was recorded

i18n impact

  • No user-visible string changed
  • Korean and English locale impact was updated

Merge gate

Keep unmerged until one unchanged exact head has every applicable repository/central CI, security, SAST, SBOM, coverage, and review gate terminal-success; zero valid unresolved findings; a qualifying independent non-author last-push approval; and ordinary protected-branch acceptance. Queued, pending, skipped, cancelled, predecessor-head, protected-base, model-only, self/author, or administrative-bypass evidence is non-passing. Do not self-approve or bypass protection.

Verification

  • Targeted Vitest: firstHarmonicExplanation, inherited-metadata, FirstHarmonicExplanationCallout (including particle and reduced-motion), Workspace, and i18n — 66 passed.
  • python3 scripts/checks/verify_docs.py passed.
  • python3 scripts/checks/verify_security_notes.py passed.

Open in Devin Review

Summary by CodeRabbit

  • 새로운 기능

    • 리허설 화면에서 곡의 첫 번째 화성 설명을 역할, 섹션, 시간과 함께 표시합니다.
    • 버튼을 누르면 해당 위치로 이동하며, 기기 설정에 따라 부드럽거나 즉시 스크롤합니다.
    • 설명이 없는 경우 안내 상태를 표시합니다.
    • 영어와 한국어 표시 및 섹션 라벨 현지화를 지원합니다.
  • 버그 수정

    • 잘못되거나 신뢰할 수 없는 설명 데이터를 안전하게 처리합니다.
    • 한국어 역할명 조사와 접근성 레이블을 올바르게 표시합니다.

Name the owning part, owned harmonicExplanation copy, labeled section, and
time so the room can play from that reason before rehearsal. Open scrolls
the renderer-owned map section. Do not invent the copy from function labels,
groove, cues, setup, simplification, overlap, range, chords, confirmed
overrides, or confidence notes.
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

Next included review available in 57 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: de251b07-c9f6-4784-8a9b-cba516cd5904

📥 Commits

Reviewing files that changed from the base of the PR and between e88f7dd and e402084.

📒 Files selected for processing (10)
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.sections-accessor.test.tsx
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.test.tsx
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.tsx
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.workspace-scope.test.tsx
  • apps/desktop/src/features/workspace/firstHarmonicExplanation.inherited-metadata.test.ts
  • apps/desktop/src/features/workspace/firstHarmonicExplanation.proxy-authority.test.ts
  • apps/desktop/src/features/workspace/firstHarmonicExplanation.time-authority.test.ts
  • apps/desktop/src/features/workspace/firstHarmonicExplanation.ts
  • apps/desktop/src/features/workspace/harmonicExplanationCoverageContract.test.ts
  • apps/desktop/vite.config.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3f956475-130e-4ea9-aebd-140a977c1031

📥 Commits

Reviewing files that changed from the base of the PR and between ea7d685 and e88f7dd.

📒 Files selected for processing (4)
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.accessibility.test.tsx
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.memoization.test.tsx
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.tsx
  • apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.workspace-scope.test.tsx

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

첫 번째 harmonic explanation을 해석하는 모듈과 워크스페이스 callout을 추가했습니다. callout은 현지화된 설명을 표시하고, 사용자가 곡 구조의 해당 섹션으로 이동하도록 지원합니다. 런타임 검증, reduced-motion 처리, 테스트 및 관련 문서를 추가했습니다.

Changes

첫 번째 harmonic explanation

Layer / File(s) Summary
설명 선택 및 런타임 검증
apps/desktop/src/features/workspace/firstHarmonicExplanation.ts, apps/desktop/src/features/workspace/firstHarmonicExplanation.test.ts, apps/desktop/src/features/workspace/firstHarmonicExplanation.inherited-metadata.test.ts, AGENTS.md, ARCHITECTURE.md
활성 그래프 노드와 유효한 역할 설명을 검증합니다. 역할 우선순위, 섹션 시작 시간, 안정적인 ID 순서로 첫 번째 설명을 선택합니다. 런타임 접근자와 잘못된 데이터는 null로 처리합니다.
워크스페이스 표시 및 섹션 이동
apps/desktop/src/features/workspace/FirstHarmonicExplanationCallout.tsx, apps/desktop/src/features/workspace/Workspace.tsx, apps/desktop/src/features/workspace/*test*, apps/desktop/src/i18n/*, apps/desktop/src/locales/*
워크스페이스에 callout을 렌더링합니다. 역할, 섹션, 시간을 현지화해 표시합니다. 버튼은 현재 workspace의 renderer가 소유한 섹션으로 이동하고 성공 상태를 기록합니다. 일반 환경에서는 smooth, reduced-motion 환경에서는 auto 스크롤을 사용합니다.
기능 계약 및 문서 반영
docs/design-system/component-contract.md, docs/doctoring/reduced-motion-first-harmonic-explanation-navigation.md, CHANGELOG.md, CLAUDE.md
컴포넌트 계약, reduced-motion 탐색 규칙, 아키텍처 설명 및 변경 기록을 갱신합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🟡 Moderate · up to e88f7

The new map-opening action can select a section from another mounted workspace, taking users to the wrong location, while incomplete test cleanup can make CI results order-dependent. Merge should wait for workspace-scoped navigation and reliable test cleanup, or explicit owner acceptance.

Sequence Diagram(s)

sequenceDiagram
  participant Workspace
  participant Callout as FirstHarmonicExplanationCallout
  participant Resolver as resolveFirstHarmonicExplanation
  participant Renderer as SongStructureRenderer

  Workspace->>Callout: RehearsalSong 전달
  Callout->>Resolver: 첫 번째 harmonic explanation 조회
  Resolver-->>Callout: 역할, 설명, 섹션, 시간 반환
  Callout->>Renderer: 현재 workspace의 대상 섹션 조회
  Renderer-->>Callout: 렌더링된 섹션 반환
  Callout->>Renderer: scrollIntoView 실행
Loading

Possibly related PRs

  • ContextualWisdomLab/bandscope#955: 유효한 음악 섹션을 선택하고 현지화된 workspace callout과 renderer 섹션 탐색을 추가한 관련 변경입니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 워크스페이스 지도에서 첫 번째 harmonic explanation을 명명하는 주요 변경 사항을 정확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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-harmonic-explanation

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.

coderabbitai[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[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[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Repair only canonical PR #1003 branch feat/workspace-first-harmonic-explanation if the live head is still exactly ede2187359abaad7fb35c41129cda30b3fbbd6b1; if it moved, inspect the intervening delta and stop rather than overwriting another writer. This is a verified current-head RED, not speculative review prose: CI run 32756754592, ci / build-and-test job 97525962608, actual merge checkout 771905a3a5f0ff4831e9edae097c3dcbe17c783d failed exactly firstHarmonicExplanation.time-authority.test.ts with expected 20 to be 10. The committed regression wraps the owned timeRange in a Proxy whose get("start") substitutes 20 while the own data descriptor remains 10. Current production validates timeRange/start/end through hasOwnData(...) but then reads them with normal property access (section.timeRange, timeRange.start, and finally section.timeRange.start), allowing Proxy get authority to replace the descriptor-backed value.

Use systematic-debugging/TDD and keep the existing RED regression. Implement the narrowest root-cause repair by snapshotting the section's owned timeRange data descriptor once, snapshotting owned start/end descriptors from that object, validating those snapshotted numbers, and carrying that validated snapshot through candidate construction so atSeconds never re-reads a Proxy/getter-backed property. The already-green firstRiffPlan.ts current-head pattern (ownedBoundedTimeRange + candidate-carried timeRange) is the working-path comparator; mirror the trust model without copying unrelated riff behavior. Do not weaken/delete the regression, do not trust accessor/inherited values, and keep descriptor-trap failures fail-closed under the existing outer boundary. Run the focused time-authority/proxy/inherited/base resolver tests, TypeScript typecheck, desktop owned statement/branch/function/line coverage, then full quickcheck. Resolve only thread PRRT_kwDORjvEXs6byn1e after the exact successor head is GREEN. Do not touch #783 dependency/security authority or unrelated workspace copy/navigation.

@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 thread apps/desktop/vite.config.ts
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