Skip to content

feat(workspace): name tonight's first part handoff on the map - #1094

Closed
seonghobae wants to merge 14 commits into
developfrom
feat/workspace-first-handoff
Closed

feat(workspace): name tonight's first part handoff on the map#1094
seonghobae wants to merge 14 commits into
developfrom
feat/workspace-first-handoff

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Buyer-visible gap

The ready rehearsal map named tonight's first playable range, but a player could not reliably tell which following section a real part-to-part pass prepared. The UI must use transition evidence, not a same-section role lookup or a heuristic/demo-shaped relation.

Product outcome

  • Ready workspace reads a corroborated source-section partGraph.handoff_to and names the immediately following destination section: Bass Guitar hands off to Lead Vocal in chorus. Lock that pass before the chorus.
  • Activity-derived transitions resolve the giver from source active roles and the entering receiver from destination active roles, matching the analysis engine's deactivate/activate topology.
  • Selecting the giver or receiver keeps that pass. Selecting an unrelated part asks the player to pick who receives the next entrance.
  • A one-section song, malformed destination, blank destination label, or receiver missing from the destination role list fails closed.
  • Heuristic fallback topology now leaves handoff_to / handoff_from empty. It no longer fabricates Bass Guitar → Lead Vocal transition authority when no signal-derived activity transition exists.
  • Copy is bilingual (en/ko) and does not expose local paths. This is the musical pass, not the metadata-handoff export artifact.

Cites Figma 19-239 and docs/design-system/component-contract.md.

Protected base: develop@749511c3ad4000090048718f685c6bee6b3d2c25.
Exact current head: c0837562f246ab83176646447f3788ca6b392e93.

Root-cause repairs

The first defect was renderer-side: the destination-label repair still looked up both role names from the source section. Real compute_handoffs topology writes a deactivating source role's handoff_to toward a role that becomes active in the next section, so the receiver can legitimately be absent from source active roles. The branch now resolves the receiver from the destination role collection and requires a valid following destination.

Fresh current-code inspection then found a deeper analysis-engine consistency defect. Heuristic _build_topology() hard-coded bass-guitar -> lead-vocal in the first fallback section even though both roles were active there and Lead Vocal became inactive in the following fallback section. That relation contradicted the production compute_handoffs() transition meaning and could become buyer-visible synthetic transition evidence.

TDD repair sequence for that owning-layer defect:

  1. 460ac8887a2fe7cdf334fe5b01fe52e1586e5f8c changes the fallback regression to reject invented Bass Guitar → Lead Vocal handoff authority.
  2. d89f92e1b5d75473e9588179fe7268f7aafdc17c also requires truthful fallback provenance: Extracted roles using heuristic fallback; handoffs unavailable.
  3. 99e2d2dc09f16a0b7d7e9f0970fe35882bae9c79 removes the hard-coded heuristic handoff and changes only fallback provenance/docstring semantics; real activity topology and compute_handoffs() are unchanged.
  4. 9086344323bb00d1af5b5ff7a0aec09650c36976 restores canonical source formatting/newline only.
  5. c0837562f246ab83176646447f3788ca6b392e93 makes doctoring explicit that heuristic fallback has no transition authority.

Predecessor checks/reviews do not transfer to this successor head.

Security / scientific-integrity boundary

  • Untrusted input: RehearsalSong JSON, source/destination labels, role ids/names, partGraph nodes, activity flags and handoff ids.
  • Signal-derived activity is the only analysis path that computes transition handoffs. Heuristic fallback may describe provisional active roles but cannot manufacture cross-section collaboration truth.
  • Workspace transition admission remains fail-closed: meaningful source giver, immediately-following destination, meaningful destination receiver, and non-self relation are required.
  • No filesystem, URL, IPC, WebView, subprocess, model, dependency, lockfile, credential, or vulnerability-suppression authority is added.
  • Canonical fix(security): establish canonical npm, PDF.js, Nanoid, and Undici baseline #783 remains protected develop dependency-security truth.

Verification

  • RED-first fallback regression and provenance contract are committed before the causal source repair.
  • Real activity-derived compute_handoffs() semantics are intentionally unchanged and remain the transition authority.
  • Fresh exact-head repository/central CI, analysis-engine coverage, Ruff/mypy, security/SAST/SBOM/package/release and independent review must become terminal-success on c0837562… before merge. Queued/pending/skipped-required/cancelled/neutral/failed/predecessor evidence is non-passing.

Merge gate


Devin Review

Surface the first active part-to-part pass from existing partGraph
handoff_to evidence so the ready rehearsal map names who gives and
who receives before the next section. Fail closed on inherited,
inactive, blank, self, or unknown receivers.
@seonghobae seonghobae added area: ui-ux Frontend, interaction, design, or user experience priority: medium Normal-priority or P2 work type: feature New or expanded product capability scope: product-gap Customer-visible product gap labels Aug 30, 2026 — with Grok (by xAI)
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

준비 작업공간이 partGraph에서 첫 번째 유효한 파트 간 핸드오프를 계산합니다. Workspace는 선택 역할에 맞는 현지화 안내를 표시합니다. 잘못된 입력과 누락된 핸드오프는 안전하게 처리합니다. 관련 테스트와 문서를 추가했습니다.

Changes

첫 파트 핸드오프

Layer / File(s) Summary
핸드오프 선택 로직
apps/desktop/src/features/workspace/firstHandoff.ts, apps/desktop/src/features/workspace/firstHandoff.test.ts
firstHandoff가 활성 상태이고 같은 섹션에 있는 유효한 수신자를 선택합니다. 상속된 속성, 빈 값, 자기 자신, 알 수 없는 역할, 손상된 입력은 무시합니다.
Workspace 표시와 현지화
apps/desktop/src/features/workspace/Workspace.tsx, apps/desktop/src/features/workspace/Workspace.test.tsx, apps/desktop/src/locales/*/common.json, apps/desktop/src/i18n/index.test.ts
Workspace에 첫 파트 핸드오프 영역을 추가합니다. 성공 및 누락 문구를 영어와 한국어로 제공합니다. 선택 역할별 표시와 현지화를 테스트합니다.
제품 계약 및 문서화
AGENTS.md, ARCHITECTURE.md, CLAUDE.md, docs/design-system/component-contract.md, docs/doctoring/first-part-handoff.md, CHANGELOG.md
준비 작업공간의 첫 핸드오프 요구사항, 선택 규칙, 안전한 실패 동작, 다음 작업을 문서화합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: 🟡 Moderate · up to ecc8d

The new guidance can name the wrong section for a part handoff, which may cause players to prepare and lock the pass at the wrong point in the song. Merge should wait until the destination section is used correctly.

Sequence Diagram(s)

sequenceDiagram
  participant Workspace
  participant firstHandoff
  participant Localization
  Workspace->>firstHandoff: 현재 곡과 activeRole 조회
  firstHandoff-->>Workspace: FirstHandoff 또는 null 반환
  Workspace->>Localization: 핸드오프 데이터로 문구 생성
  Localization-->>Workspace: 현지화된 안내 문구 반환
```}

</details>

<!-- walkthrough_end -->
<!-- pre_merge_checks_walkthrough_start -->

<details>
<summary>🚥 Pre-merge checks | ✅ 5</summary>

<details>
<summary>✅ Passed checks (5 passed)</summary>

|         Check name         | Status   | Explanation                                                                                                                                                                                               |
| :------------------------: | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|     Docstring Coverage     | ✅ Passed | Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 5 files. (8 skipped: 8 u… |
|     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.                                                                                                                                  |
|      Description Check     | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                                                                                                               |
|         Title check        | ✅ Passed | 제목은 기존 partGraph 데이터에서 오늘 밤의 첫 파트 간 핸드오프를 준비 작업공간 지도에 표시하는 주요 변경 사항을 정확하고 간결하게 설명합니다.                                                                                                                     |

</details>

<details>
<summary>Full details: Docstring Coverage</summary>

**Explanation**

Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 5 files. (8 skipped: 8 unsupported.)

</details>

</details>

<!-- pre_merge_checks_walkthrough_end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

<details>
<summary>📝 Generate docstrings</summary>

- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch

</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>

- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Commit unit tests in branch `feat/workspace-first-handoff`

</details>

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=ContextualWisdomLab/bandscope&utm_content=1094)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>


<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>

<!-- tips_end -->
Loading

devin-ai-integration[bot]

This comment was marked as resolved.

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.

Copy link
Copy Markdown
Collaborator Author

Canonicalization update: fresh comparison against #1007 exact current head 27dcf0f968d1b13bf031bb3a6b65a97aea3f3d98 confirms the unique selected-role behavior from this lane is now executable there. firstPartHandoff.role-scope.test.ts requires giver/receiver selections to retain the pass and unrelated/unknown selections to fail closed; FirstPartHandoffCallout.role-scope.test.tsx preserves the corresponding guidance-only UI. #1007 also retains the stronger bidirectional handoff_from corroboration, destination activation/deactivation checks, deterministic ranking, bounded Unicode copy, scoped navigation, reduced-motion handling, and hostile-runtime defenses. Do not close this PR yet: #1007's current hosted checks are queued, so its integrated behavior is not merge-grade evidence. Once the unchanged #1007 head passes its required hosted verification, this PR can be closed as superseded without transferring any predecessor check/review evidence.

seonghobae commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator Author

Writer note: this dispatch is superseded. The BandScope maintainer claimed the unchanged lane before any agent acknowledgement and applied the TDD repair directly. Do not start a second writer from this comment. The successor branch head and its exact-head checks are the only current evidence.

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.

Devin Review

Comment thread services/analysis-engine/src/bandscope_analysis/roles/extractor.py

Copy link
Copy Markdown
Collaborator Author

Supersession evidence (fresh 2026-09-01 comparison): canonical #1007 remains open at exact head 5261b1cbb15fd6587425c954c3480991394afc74 against protected develop@749511c3ad4000090048718f685c6bee6b3d2c25. The analysis-engine repair is preserved at the owning source boundary: services/analysis-engine/src/bandscope_analysis/roles/extractor.py has the same blob (82ed7fdd27c71f47057df9dc5586f0480db554bb) on #1007 and this PR, so heuristic fallback emits no fabricated handoff and reports handoffs unavailable. #1007 also retains the executable fallback regression in services/analysis-engine/tests/test_roles.py and is stricter at the buyer boundary: it requires source handoff_to plus receiver-side handoff_from corroboration, giver deactivation/receiver activation in the immediately following destination, selected-role scoping, mounted Workspace wiring, stale-role protection, fail-closed hostile-metadata handling, destination navigation, and reduced-motion coverage. This PR's destination-label, role-scoping, bilingual-copy, malformed/one-section fail-closed, and heuristic-authority requirements are therefore represented by the surviving canonical lane. No check, review, approval, or predecessor evidence is transferred. Closing unmerged as superseded by #1007; #1007 still requires its own unchanged-head required checks and qualifying independent approval before merge.

@seonghobae seonghobae closed this Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ui-ux Frontend, interaction, design, or user experience priority: medium Normal-priority or P2 work scope: product-gap Customer-visible product gap type: feature New or expanded product capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant