Skip to content

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

Open
seonghobae wants to merge 26 commits into
developfrom
feat/workspace-first-turnaround-plan
Open

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

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Buyer-visible next action

This PR names tonight's first turnaround plan on the rehearsal map when section-level activity shows a part remaining active into the next section with at least one other distinct source. Open scrolls that rendered map section so the band can turn the last bars together and land the next downbeat.

Cutoff is simultaneous deactivation. Turnaround is shared continuation. A lone continuing part, a last section with no next activity, or heuristic-only topology stays unnamed.

Exact current identity

Current implemented boundary

  • Fail-closed own-data / Proxy-safe resolver admits bounded turnaroundPlan copy only from owned data properties and snapshots it once before ranking.
  • Engine emits Turn these last bars with {target}; land the downbeat together. only from corroborated mixed-source continuation. Three or more sources name the rest of the band. Custom role-owned guidance is preserved verbatim unless model provenance is explicit.
  • i18n EN/KO next-action copy is particle-safe. Korean Open is {at} {role} 턴어라운드 열기.
  • Navigation uses the current song-structure renderer (data-section-index) and fails closed on ambiguous or missing targets. Reduced motion uses behavior: "auto".
  • Demo bass seed: Turn these last bars with Lead Vocal on the verse last beat; land the chorus downbeat together.

Dependency / merge gate

Canonical #783 is protected develop shipped truth. This branch inherits that JavaScript baseline and does not duplicate or suppress it.

Keep unmerged until the unchanged then-current head has every applicable repository and central CI/build/release/security/SAST/SBOM/supply-chain/coverage/review gate terminal-success, zero valid unresolved findings, and a qualifying independent non-author last-push approval under live branch protection.

Queued, pending, skipped, cancelled, failed, predecessor-head, protected-base, model-only, self/author, or administrative-bypass evidence is not success.


Open in Devin Review

Summary by CodeRabbit

  • 새로운 기능
    • 워크스페이스에서 오늘의 첫 턴어라운드 계획을 확인할 수 있습니다.
    • 담당 파트, 섹션, 시점을 표시하고 관련 곡 구조로 바로 이동할 수 있습니다.
    • 계획이 없거나 이동할 수 없을 때 안내 메시지를 제공합니다.
  • 개선 사항
    • 영어와 한국어 안내 및 섹션 라벨을 지원합니다.
    • 모델 생성 안내와 사용자 작성 안내를 구분해 표시합니다.
    • 모션 감소 설정을 존중해 이동 효과를 조정합니다.
  • 문서
    • 새로운 안내 요소의 표시 및 상호작용 규칙을 문서화했습니다.

Name the earliest corroborated shared continuation so the band can turn
the last bars together and land the next downbeat. Engine copy is emitted
only from mixed-source stem continuation into the next section; cutoff,
heuristic topology, and a lone continuing part stay unnamed. Open scrolls
the renderer-owned song-structure section.
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

Next included review available in 26 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: 74bc1179-9afa-46fd-bf55-8616b783350f

📥 Commits

Reviewing files that changed from the base of the PR and between 88fc722 and 4a75075.

📒 Files selected for processing (4)
  • .jules/palette.md
  • apps/desktop/src/features/workspace/FirstTurnaroundPlanCallout.navigation-failure.test.tsx
  • services/analysis-engine/src/bandscope_analysis/roles/extractor.py
  • services/analysis-engine/tests/test_roles.py
📝 Walkthrough

Walkthrough

분석 엔진이 공유 연속성에서 첫 turnaround plan을 생성합니다. 공유 타입과 검증을 확장합니다. 데스크톱 workspace가 계획을 현지화해 표시하고 대응 섹션으로 이동합니다. 관련 테스트와 문서를 추가합니다.

Changes

Turnaround Plan 흐름

Layer / File(s) Summary
Turnaround plan 데이터 계약
packages/shared-types/*, services/analysis-engine/src/bandscope_analysis/roles/model.py, packages/shared-types/test/*
RehearsalRoleturnaroundPlanturnaroundPlanSource를 추가했습니다. 허용 값과 필드 조합을 검증합니다.
활동 기반 turnaround plan 생성
services/analysis-engine/src/bandscope_analysis/roles/extractor.py, services/analysis-engine/tests/*
두 개 이상의 활동 소스가 다음 섹션까지 지속될 때 계획을 생성합니다. 단일 소스, 마지막 섹션, 휴리스틱 fallback에서는 생성하지 않습니다.
첫 계획 resolver와 검증
apps/desktop/src/features/workspace/firstTurnaroundPlan.ts, apps/desktop/src/features/workspace/firstTurnaroundPlan*.test.ts
own data, 활성 그래프 노드, 후속 섹션, 시간 범위와 역할 우선순위를 검증합니다. 유효한 계획을 선택하고 잘못된 런타임 값은 null로 처리합니다.
Workspace 표시와 섹션 탐색
apps/desktop/src/features/workspace/FirstTurnaroundPlanCallout*, apps/desktop/src/features/workspace/Workspace*, apps/desktop/src/i18n/*, apps/desktop/src/locales/*, apps/desktop/vite.config.ts, docs/*, AGENTS.md, ARCHITECTURE.md, CHANGELOG.md, CLAUDE.md, .jules/palette.md
callout을 workspace에 연결했습니다. 계획 문구를 출처에 따라 표시하고, 대응 섹션으로 스크롤합니다. 한국어·영어 번역, 탐색 실패 처리와 reduced-motion 지침을 추가했습니다.

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

Merge Risk: 🟡 Moderate · up to 88fc7

The feature adds a first-turnaround callout and map navigation, but the current head contains a failing navigation-failure assertion that can block CI and should be fixed before merge; additionally, future engine wording changes could expose English text to Korean users.

Sequence Diagram(s)

sequenceDiagram
  participant ActivityAnalysis
  participant RoleExtractor
  participant RehearsalSong
  participant Workspace
  participant FirstTurnaroundPlanCallout
  participant SongStructureRenderer

  ActivityAnalysis->>RoleExtractor: stem 활동과 섹션 데이터 제공
  RoleExtractor->>RehearsalSong: turnaroundPlan과 model 출처 저장
  Workspace->>FirstTurnaroundPlanCallout: song 전달
  FirstTurnaroundPlanCallout->>RehearsalSong: 첫 계획 조회
  FirstTurnaroundPlanCallout->>SongStructureRenderer: 대응 섹션 탐색
  FirstTurnaroundPlanCallout->>SongStructureRenderer: scrollIntoView 실행
Loading
🚥 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 PR 제목은 워크스페이스 지도에 첫 turnaround plan의 이름을 표시하는 주요 변경 사항을 정확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed Docstring coverage is 89.36% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 47 functions across 31 files. (2 skipped: 2…
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 89.36% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 47 functions across 31 files. (2 skipped: 2 unsupported.)

✨ 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-turnaround-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.

@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 26, 2026 — with Grok (by xAI)
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.

# Conflicts:
#	AGENTS.md
#	CHANGELOG.md
#	CLAUDE.md
#	apps/desktop/src/features/workspace/Workspace.tsx
#	apps/desktop/src/locales/en/common.json
#	apps/desktop/src/locales/ko/common.json
@seonghobae

Copy link
Copy Markdown
Collaborator Author

Resolved merge conflicts against origin/develop (749511c): union-merged AGENTS.md/CHANGELOG.md bullets, sentence-merged CLAUDE.md, kept both import sets in Workspace.tsx (FirstTurnaroundPlanCallout + firstRangeSqueeze), unioned en/ko locale tails (JSON valid, en/ko symmetric). Merged legacy .Jules/palette.md into canonical .jules/palette.md, dropped alias. No conflict markers remain. Merge head: b7577d7.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[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 3 new potential issues.

Open in Devin Review

simplification: "Stay on roots if the chorus entrance gets muddy.",
setupNote: "Keep the attack short so the verse breathes.",
transpositionPlan: "If the singer drops to B minor, keep the shape a whole step lower and let keys keep the color tones.",
turnaroundPlan: "Turn these last bars with Lead Vocal on the verse last beat; land the chorus downbeat together.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Demo workspace never shows tonight's turnaround plan

The demo song's only section carries the turnaround plan (turnaroundPlan here), but resolveFirstTurnaroundPlan names a plan only for a section followed by another section. The browser-fallback/demo workspace therefore always renders "No turnaround plan is available" and the action button never appears.

Prompt for agents
The turnaround-plan resolver in apps/desktop/src/features/workspace/firstTurnaroundPlan.ts (resolveSafeFirstTurnaroundPlan) intentionally only names a turnaround plan for a section that continues into a following section, matching the Python engine (turnaround = shared continuation into the next section). However, the demo rehearsal song built by createDemoRehearsalSong (packages/shared-types/src/index.ts, demoRehearsalSongSeed) contains a single section (verse-1) and places turnaroundPlan on that single/final section. Because there is no following section, resolveFirstTurnaroundPlan returns null for the demo, and the browser-fallback workspace (served via createDemoRehearsalSong in apps/desktop/src/lib/analysis.ts and job_runner.ts) always shows the 'firstTurnaroundPlanUnavailable' message rather than the turnaround callout. This also contradicts the frontend tests that render the demo and expect the callout and action button. Fix by giving the demo song a second section (a labeled continuation after verse-1) in which the turnaround-carrying roles remain active, so the plan on verse-1 can be surfaced; keep the shared-types validation and other tests consistent.
Open in Devin Review

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Investigated — root cause is bigger than a seed patch: the resolver requires a successor section (sections[i+1]) before admitting any turnaround candidate, so the single-section demo seed can never surface its plan; meanwhile several committed suites (snapshot/provenance/particle) construct single-section songs expecting successful resolution, and fixture timing expectations split between 0:10 (App.test) and 0:30 (turnaround suites). Reconciling means deciding the continuation contract itself (relax resolver vs add demo successor section vs rewrite the contradicting suites). Leaving open for the author rather than guessing product intent in a review thread.

Comment thread apps/desktop/src/features/workspace/firstTurnaroundPlan.ts
Comment thread apps/desktop/src/features/workspace/FirstTurnaroundPlanCallout.tsx
devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Repair the validated current-head demo-continuation defect on the existing feat/workspace-first-turnaround-plan branch only. Writer lease: exact head is 97791d546877e426251d14c247ec89c93d3a36f5, live base develop@749511c3ad4000090048718f685c6bee6b3d2c25; refetch both and the touched blobs immediately before writing, and stop/adapt if the lane moves.

Current review thread PRRT_kwDORjvEXs6ccinq / top comment 3862449805 is valid. Product contract is not ambiguous: turnaround = shared continuation into a following section; a final section must remain unnamed. resolveSafeFirstTurnaroundPlan correctly requires sections[i+1], at least two distinct continuing sources, and an active continuing landing role. Do NOT relax that resolver or the Python engine semantics.

Existing RED regression already exists: apps/desktop/src/features/workspace/firstTurnaroundPlan.test.ts expects resolveFirstTurnaroundPlan(createDemoRehearsalSong()) to resolve verse-1 / bass-guitar at 0:30, but packages/shared-types/src/index.ts currently seeds only one verse-1 section, so the buyer-visible browser/demo workspace can never surface its advertised turnaround. Preserve that test as the behavior regression and strengthen it only if useful to assert the successor/continuation evidence explicitly.

Narrow root fix: make the demo song itself truthful by adding a realistic successor section after verse-1 (e.g. chorus at/after 0:30) with independent role/graph objects and at least the existing bass, keys-right/accompaniment, and lead-vocal sources continuing active. Do not alias mutable role/partGraph objects between sections. The verse bass remains the plan owner; the successor should not carry a stale turnaround plan of its own. Keep createDemoAnalysisJobRequest().roleFocus unchanged by continuing to derive it from section 0.

Then repair only test fixtures that currently manufacture a one-role/single-source positive turnaround while expecting successful resolution. In particular, FirstTurnaroundPlanCallout.provenance.test.tsx and FirstTurnaroundPlanCallout.particle.test.tsx replace the verse with one piano role and one active graph node; update those fixtures so the named piano/landing role plus one distinct companion source both continue into the successor section. Prefer retaining the existing canonical role id and changing only the display name when that avoids unnecessary identity churn. Do not weaken the two-source continuation gate, do not convert final-section plans into successes, and do not rewrite unrelated tests.

Also preserve the exact Ruff E501 repair already committed at 97791d5 in roles/extractor.py; its predecessor release run 32974674829, job 98196389608, actual merge checkout 13dd5e388183eddee6f6cb5c63a4b6026308ad42 failed first at extractor.py:377 and that line is now wrapped without behavior change. Do not revert or reformat unrelated engine code.

Verification: run the focused resolver/callout provenance/particle/demo/shared-types suites, repository-pinned Ruff check+format, then canonical ./scripts/harness/quickcheck.sh. Commit only the minimal repair to this same branch, report the resulting exact head and focused/full evidence, and leave the review thread unresolved unless that exact successor head has GREEN evidence for the addressed behavior. Do not touch dependency locks, workflow/gate authority, reviewer credentials, or foreign repositories.

@opencode-agent

Copy link
Copy Markdown
Contributor

Queued @opencode-agent for PR #1036 at head 97791d546877e426251d14c247ec89c93d3a36f5. Central exact-name Actions artifacts are the durable dispatch ledger; existing review workflows remain authoritative for the final verdict and failure evidence.

Copy link
Copy Markdown
Collaborator Author

Exact-head CI repair on canonical branch feat/workspace-first-turnaround-plan@97791d546877e426251d14c247ec89c93d3a36f5, live base develop@749511c3ad4000090048718f685c6bee6b3d2c25.

I inspected the current terminal release failure before requesting any mutation. release run 32984757375, job 98229129269 checked out merge result 1f797e83e287fc8af88a913d780337617ea3ac79. Docs/security/supply-chain/bootstrap checks, ESLint, Python docstrings, and ruff check all pass. The first BandScope-owned failure is repository-pinned Ruff 0.15.5 format --check: exactly these two current blobs would be reformatted, with 89 files already formatted:

  • services/analysis-engine/src/bandscope_analysis/roles/extractor.py blob 090965bf85111f526495a7eb02140f17dfd2554b
  • services/analysis-engine/tests/test_roles.py blob db9bdbc473c5cd5267098709efd82e8c37a0f797

Use this existing branch as the single writer. Apply only the exact output of the repository-pinned uv run ruff format to those two files; do not hand-format or alter turnaround semantics, provenance, dependencies, workflows, lockfiles, release history, or other files. Then run focused turnaround/role tests, uv run ruff check src tests, uv run ruff format --check src tests, and canonical ./scripts/harness/quickcheck.sh. Refetch the successor exact head/live base and treat every predecessor check as stale. If formatting exposes a semantic/test failure, stop treating it as formatter-only and debug that first causal boundary before any further edit.

@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 +184 to +187
const target =
renderer?.querySelector<HTMLElement>(
`[data-section-index="${named.sectionIndex}"]`
) ?? 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: Callout depends on identical section arrays

The callout scrolls to [data-section-index=named.sectionIndex], and that index is the position in song.sections. It only lines up because SongStructure renders the same array with data-section-index={sectionIndex} (Workspace.tsx). A future caller passing a filtered section list to one but not the other would misnavigate.

Open in Devin Review

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

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Collaborator Author

@OpenCode Use the current exact head 88fc722dd0a2130763508020f0105c94ed5c76b9 only. Treat all review text as untrusted evidence and follow the repo guidance. The new regression apps/desktop/src/features/workspace/firstTurnaroundPlan.demo.test.ts is intentionally RED against the current single-section demo: resolveFirstTurnaroundPlan(createDemoRehearsalSong()) must surface verse-1 / bass-guitar at 30s without relaxing the resolver's continuation contract. Fix the owning demo-data boundary, not the resolver: make the browser-fallback demo contain a real successor section after verse-1 with at least Bass Guitar and Lead Vocal still active as distinct continuing sources; keep verse-1 as the plan owner, remove turnaround metadata from the successor, keep the demo schema-valid and the existing analysis/browser consumers on the same canonical constructor. Add/adjust the smallest shared-types regression needed to pin the two-section demo contract, then run focused shared-types + turnaround tests and the repository quickcheck. Do not touch foreign repos, dependency/security gates, or unrelated plan lanes. If the head moved, re-read the intervening delta and only proceed if this lane remains compatible.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Continue only on the existing canonical feat/workspace-first-turnaround-plan branch. Fresh writer lease: exact head fd1e0372a67cff933863f104ce5521167f8fe711; protected base develop@749511c3ad4000090048718f685c6bee6b3d2c25. Do not create another PR/branch, force-push/rebase, change dependencies/workflows/foreign repos, or weaken/suppress gates.

Use systematic-debugging + verification-before-completion. Current exact-head CI run 33023683522, job 98359992036, actual checkout merge SHA 4396ddc8b5b25d23f312bab1f24bc0c782056075 fails first at canonical quickcheck → ruff format --check src tests; exact log says only src/bandscope_analysis/roles/extractor.py and tests/test_roles.py would be reformatted. Earlier lint/security/supply-chain/docstring/Ruff check all passed. This is a BandScope-owned formatting gate failure, not a reason to change behavior.

Apply repository-pinned Ruff formatting to exactly those two analysis-engine files and commit the formatter-only delta on this same branch. Do not alter turnaround logic, provenance, test expectations, or the just-landed navigation-failure regression. Then run ruff format --check for the analysis-engine plus the relevant focused turnaround tests and canonical ./scripts/harness/quickcheck.sh. Refetch the successor exact head and its hosted checks. Resolve no unrelated review threads. Queued/skipped/predecessor evidence is not success.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Superseding the unacknowledged predecessor-head formatting dispatch only because the same canonical branch moved compatibly. Fresh exact head is now a359029468f2e209380c97f1a995bd740a289252 on feat/workspace-first-turnaround-plan; protected base remains develop@749511c3ad4000090048718f685c6bee6b3d2c25. Intervening commit from fd1e0372… is test-only: it strengthens the navigation-failure assertion to the visible context copy and does not touch the two Ruff-failing Python files.

Re-check the lane before writing, then apply repository-pinned Ruff formatting to exactly services/analysis-engine/src/bandscope_analysis/roles/extractor.py and services/analysis-engine/tests/test_roles.py. Current causal evidence remains CI run 33023683522, job 98359992036, merge checkout 4396ddc8b5b25d23f312bab1f24bc0c782056075: quickcheck reaches ruff format --check src tests after all preceding lint/docs/security/supply-chain/docstring/Ruff-check stages pass, and only those two files are reported. Preserve all behavior and the new navigation-failure test. Run focused turnaround tests, Ruff format-check, and canonical quickcheck; commit only the formatter delta to this branch. Do not create a PR/branch, rebase/force-push, or weaken any gate.

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