Skip to content

feat: import rehearsal handoffs for focused reanalysis - #740

Open
seonghobae wants to merge 53 commits into
developfrom
feat/handoff-import-roundtrip
Open

feat: import rehearsal handoffs for focused reanalysis#740
seonghobae wants to merge 53 commits into
developfrom
feat/handoff-import-roundtrip

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

What

Complete the metadata handoff round trip in the desktop app and analysis engine. The user can import a validated handoff JSON file, inspect its workspace and role scope, explicitly pair a fresh local audio source, and receive a result projected onto the requested rehearsal roles.

Product outcome

An exported handoff becomes directly usable by another BandScope user. Audio remains local and source selection remains explicit. Importing or replacing a handoff clears any previously selected audio so unrelated source context cannot be reused accidentally; clearing the handoff preserves audio selected after that handoff.

The engine caches the complete reusable analysis and applies roleFocus only to each response. This prevents recipient-specific cache poisoning while removing unrelated roles and out-of-scope part-graph links from focused results.

Verification

  • Bounded file-size checks before decoding.
  • Strict UTF-8, JSON, artifact-kind, and artifact-version validation.
  • Localized payload-free errors.
  • Accessible import, replace, progress, summary, and clear controls.
  • Ordered role deduplication and focused request construction.
  • Explicit source re-selection regression coverage.
  • Engine tests for role filtering, part-graph link filtering, all-role empty focus, and full-cache reuse.
  • Frontend lint, strict typecheck, measured tests, production build, Python tests, and Ruff before the generated integration commit.
  • Full repository CI and independent review before merge.

Security Notes

The imported file is untrusted. The implementation uses bounded allocation, strict schema validation, no path or URL dereference, no payload echo, no automatic analysis start, no implicit reuse of a source chosen before the imported handoff, and non-mutating projection over complete cached results.

Closes #739

Summary by CodeRabbit

  • 새로운 기능

    • 검증된 BandScope 메타데이터 핸드오프 JSON 파일을 가져오고 교체할 수 있습니다.
    • 핸드오프에 포함된 역할을 기준으로 집중 분석 결과를 확인할 수 있습니다.
    • 핸드오프 가져오기 후 로컬 오디오를 명시적으로 선택해 분석을 시작할 수 있습니다.
    • 파일 형식, 크기, 인코딩 및 내용 검증 오류를 안내합니다.
  • 개선 사항

    • 새 핸드오프를 가져오면 기존 오디오 선택이 초기화됩니다.
    • 분석 완료 또는 프로젝트 변경 시 핸드오프 상태가 정리됩니다.
    • 핸드오프 가져오기 워크플로와 제한 사항을 문서화했습니다.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e79ad94-23db-41d3-9b3c-a00bde15bb11

📥 Commits

Reviewing files that changed from the base of the PR and between c31a90e and 4fe7348.

📒 Files selected for processing (7)
  • apps/desktop/src/App.handoff.test.tsx
  • apps/desktop/src/App.tsx
  • apps/desktop/src/features/import/HandoffImportControl.test.tsx
  • apps/desktop/src/features/import/HandoffImportControl.tsx
  • apps/desktop/src/lib/handoff.ts
  • docs/workflows/metadata-handoff-import.md
  • services/analysis-engine/tests/test_role_focus.py
📝 Walkthrough

Walkthrough

검증된 BandScope 메타데이터 핸드오프를 가져오는 데스크톱 UI와 파일 검증 로직을 추가했습니다. 사용자는 로컬 오디오를 명시적으로 선택한 뒤 역할 집중 재분석을 시작합니다. 분석 엔진은 요청 역할과 관련된 결과만 반환하고 전체 결과는 캐시에 보존합니다.

Changes

메타데이터 핸드오프 왕복

Layer / File(s) Summary
핸드오프 검증 및 요청 계약
apps/desktop/src/lib/handoff.ts, apps/desktop/src/lib/handoff.test.ts
JSON 확장자, 1 MiB 크기, 실제 바이트 길이, UTF-8, JSON, artifact 계약을 순서대로 검증합니다. 검증된 artifact에서 중복 없는 역할 초점을 추출하고 분석 요청을 생성합니다.
핸드오프 가져오기 컨트롤
apps/desktop/src/features/import/HandoffImportControl.tsx, apps/desktop/src/features/import/HandoffImportControl.test.tsx
파일 선택, 비동기 검증, 오류 전달, workspace·song·role 표시, 교체, 삭제, 비활성화 상태를 구현하고 테스트합니다.
앱 상태 및 분석 흐름 연결
apps/desktop/src/App.tsx, apps/desktop/src/App.handoff.test.tsx, apps/desktop/src/locales/*/common.json, apps/desktop/vite.config.ts, docs/workflows/metadata-handoff-import.md, CHANGELOG.md
핸드오프와 로컬 오디오 선택을 연결하고 상호 배타적으로 처리합니다. 분석 전 로컬 오디오 선택을 요구하며 완료·프로젝트 로드 후 핸드오프를 정리합니다. 오류 메시지, 문서, 커버리지 설정, 변경 로그를 갱신합니다.
역할 집중 결과 및 캐시 처리
services/analysis-engine/src/bandscope_analysis/api.py, services/analysis-engine/tests/test_role_focus.py
요청 역할과 관련된 역할, part-graph 노드, handoff 관계, focusSections만 반환합니다. 캐시에는 전체 결과를 저장하고 응답에는 요청별 필터링 결과를 사용합니다.

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

Sequence Diagram(s)

sequenceDiagram
  participant 사용자
  participant HandoffImportControl
  participant App
  participant AnalysisAPI
  participant AnalysisCache
  사용자->>HandoffImportControl: 핸드오프 JSON 선택
  HandoffImportControl->>App: 검증된 artifact 전달
  사용자->>App: 로컬 오디오 선택
  App->>AnalysisAPI: 로컬 오디오와 역할 초점이 포함된 분석 요청
  AnalysisAPI->>AnalysisCache: 전체 분석 결과 조회 또는 저장
  AnalysisAPI-->>App: 역할 집중 분석 결과 반환
Loading

Possibly related PRs

Suggested labels: codex, aardvark

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.47% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 메타데이터 핸드오프 가져오기와 역할 집중 재분석이라는 주요 변경을 명확하게 설명합니다.
Linked Issues check ✅ Passed [#739]의 가져오기, 검증, 로컬 오디오 선택, 역할 집중 재분석, 오류 처리, 테스트 요구사항을 변경 사항이 충족합니다.
Out of Scope Changes check ✅ Passed 문서, 로컬라이제이션, 프론트엔드, 분석 엔진 및 테스트 변경이 모두 핸드오프 왕복 지원 목표와 관련됩니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/handoff-import-roundtrip

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

@seonghobae
seonghobae enabled auto-merge (squash) August 3, 2026 04:07
@opencode-agent

opencode-agent Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 4fe7348987551937ea88ef2ef324348274837e79
  • Workflow run: 30951152154
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 4fe7348987551937ea88ef2ef324348274837e79.

  • Head SHA: 4fe7348987551937ea88ef2ef324348274837e79

  • Workflow run: 30951152154

  • Workflow attempt: 1

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 4

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (11 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (11 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Docs: metadata-handoff-import.md"]
  S2 --> I2["operator or user guidance"]
  I2 --> R2["Review risk: Docs: metadata-handoff-import.md"]
  R2 --> V2["docs review"]
  Evidence --> S3["Test: test_role_focus.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_role_focus.py"]
  R3 --> V3["targeted test run"]
Loading

@opencode-agent
opencode-agent Bot disabled auto-merge August 3, 2026 21:28
@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 03:33
@opencode-agent
opencode-agent Bot disabled auto-merge August 4, 2026 04:38
@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 06:17
@opencode-agent
opencode-agent Bot disabled auto-merge August 4, 2026 07:20
@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 07:54
@opencode-agent
opencode-agent Bot disabled auto-merge August 4, 2026 10:11
@seonghobae
seonghobae dismissed opencode-agent[bot]’s stale review August 4, 2026 11:01

Dismissed because the requested change is an infrastructure-only coverage failure from the superseded central sandbox, not an unresolved product-code finding. Repository CI, security, SBOM, release, and build checks succeeded on this exact head; a fresh independent approval remains mandatory.

@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 11:02

Copy link
Copy Markdown
Collaborator Author

@cwl-noema-review @opencode-agent Please independently review exact head 4fe7348987551937ea88ef2ef324348274837e79. Exact-head repository checks succeeded and all review threads are resolved. Verify bounded untrusted-file intake, strict/payload-free errors, source re-selection, reading-state race prevention, role-focused projection, and complete-result cache integrity; approve only if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 10 minutes and 10 seconds before sending another message.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 4fe7348987551937ea88ef2ef324348274837e79. All nine repository-local workflows succeed and the only current inline finding is resolved. Verify bounded pre-decode size checks, strict UTF-8/JSON/kind/version validation, payload-free localized failures, validation-state interlock with audio/YouTube selection, explicit fresh local-source consent after import or replacement, ordered role deduplication, non-mutating role/part-link projection, complete-result cache storage on both hit and miss paths, recipient-specific cache-poisoning prevention, accessible progress/summary/clear controls, and no path/URL dereference or automatic analysis. Submit APPROVE only if no blocker remains.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='4fe7348987551937ea88ef2ef324348274837e79'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"
git diff-tree --no-commit-id --name-status -r "$expected"

ast-grep outline apps/desktop/src/lib/handoff.ts --items all
ast-grep outline apps/desktop/src/features/import/HandoffImportControl.tsx --items all
ast-grep outline apps/desktop/src/App.tsx --items all --match 'App|handle|select|handoff|analysis'
ast-grep outline services/analysis-engine/src/bandscope_analysis/api.py --items all --match 'focus|cache|analy|song'

printf '\n--- handoff implementation ---\n'
cat -n apps/desktop/src/lib/handoff.ts
printf '\n--- import control implementation ---\n'
cat -n apps/desktop/src/features/import/HandoffImportControl.tsx
printf '\n--- App handoff references ---\n'
rg -n -C 8 -e 'handoff|Handoff|selectedSource|selectSource|createAnalysisRequestForSelection|YouTube' apps/desktop/src/App.tsx
printf '\n--- engine focus/cache references ---\n'
rg -n -C 12 -e '_focus_rehearsal_song|roleFocus|cache|cached|partGraph|handoff' services/analysis-engine/src/bandscope_analysis/api.py

Length of output: 57500


🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='4fe7348987551937ea88ef2ef324348274837e79'
base="$(git merge-base "${head}^" "$head" 2>/dev/null || true)"
printf 'COMMIT=%s\nPARENT=%s\n' "$head" "$base"
git diff --stat "${head}^" "$head"
git diff --find-renames --unified=45 "${head}^" "$head" -- apps/desktop/src/lib/handoff.ts

printf '\n--- App handlers and accessibility UI ---\n'
sed -n '390,535p' apps/desktop/src/App.tsx
sed -n '700,890p' apps/desktop/src/App.tsx

printf '\n--- desktop handoff tests ---\n'
cat -n apps/desktop/src/lib/handoff.test.ts
cat -n apps/desktop/src/features/import/HandoffImportControl.test.tsx
cat -n apps/desktop/src/App.handoff.test.tsx

printf '\n--- locate parser and reanalysis constructor ---\n'
rg -n -C 12 -g '*.{ts,tsx}' \
  -e 'function parseMetadataHandoffArtifact\b|const parseMetadataHandoffArtifact\b|parseMetadataHandoffArtifact\s*=' \
  -e 'function createReanalysisRequestFromHandoff\b|const createReanalysisRequestFromHandoff\b|createReanalysisRequestFromHandoff\s*=' \
  .

printf '\n--- all metadata-handoff field access and dereference-related calls ---\n'
rg -n -C 4 -g '*.{ts,tsx,py}' \
  -e 'MetadataHandoffArtifact|parseMetadataHandoffArtifact|createReanalysisRequestFromHandoff' \
  -e '\.workspace\.|\.song\.|\.sections\.' \
  apps services packages 2>/dev/null || true

printf '\n--- analysis-engine role focus regression tests ---\n'
cat -n services/analysis-engine/tests/test_role_focus.py

Length of output: 122649


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- artifact schema validator ---'
sed -n '270,325p' packages/shared-types/src/index.ts
sed -n '830,955p' packages/shared-types/src/index.ts

printf '%s\n' '--- reanalysis request constructor ---'
sed -n '140,185p' apps/desktop/src/lib/export.ts

printf '%s\n' '--- selection error and progress/summary accessibility markup ---'
rg -n -C 10 -e 'selection-error|role="alert"|aria-live|progressbar|Progress' apps/desktop/src/App.tsx
sed -n '875,960p' apps/desktop/src/App.tsx

printf '%s\n' '--- artifact field names passed to filesystem, URL, fetch, or IPC APIs ---'
rg -n -P -C 5 \
  '(readFile|readTextFile|readBinaryFile|writeFile|writeTextFile|fetch\s*\(|axios|XMLHttpRequest|open\s*\(|Path\s*\(|urlopen|requests\.)' \
  apps/desktop/src packages/shared-types/src services/analysis-engine/src \
  -g '*.{ts,tsx,py}' | head -n 500

printf '%s\n' '--- direct imported artifact/sourceAssets accesses outside parser/export/import UI ---'
rg -n -P -C 4 \
  '(sourceAssets|artifactKind|artifactVersion|createdAt|workspace\.|song\.|roleBuckets)' \
  apps/desktop/src packages/shared-types/src services/analysis-engine/src \
  -g '*.{ts,tsx,py}' | head -n 600

Length of output: 83798


@seonghobae I reviewed exact head 4fe7348987551937ea88ef2ef324348274837e79.

No blocker remains.

The implementation enforces bounded pre-decode intake, strict UTF-8/JSON/schema validation, and payload-free localized errors. It prevents competing source actions during handoff validation. A validated import clears the prior source and requires fresh local-source selection.

The role-focus projection does not mutate cached complete results. Both cache-hit and cache-miss paths retain complete cache values and return recipient-specific projections. Static inspection found no handoff path, URL, or asset dereference.

The import, replacement, clear, status, error, summary, and progress controls include the required accessible labels and live regions.

[approve]

You are interacting with an AI system.

@seonghobae
seonghobae marked this pull request as draft August 4, 2026 12:46
auto-merge was automatically disabled August 4, 2026 12:46

Pull request was converted to draft

@seonghobae
seonghobae marked this pull request as ready for review August 4, 2026 12:46

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 4fe7348987551937ea88ef2ef324348274837e79.

  • Head SHA: 4fe7348987551937ea88ef2ef324348274837e79

  • Workflow run: 30951152154

  • Workflow attempt: 1

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 4

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (11 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (11 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Docs: metadata-handoff-import.md"]
  S2 --> I2["operator or user guidance"]
  I2 --> R2["Review risk: Docs: metadata-handoff-import.md"]
  R2 --> V2["docs review"]
  Evidence --> S3["Test: test_role_focus.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_role_focus.py"]
  R3 --> V3["targeted test run"]
Loading

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Please review exact current head 4fe7348987551937ea88ef2ef324348274837e79. All repository workflows succeeded and the prior handoff-reading race was addressed. Focus on bounded file intake, strict UTF-8/schema validation, parent-visible reading state, explicit local source reselection, no automatic analysis/network action, complete-result cache preservation, role/part-graph projection, localized payload-free errors, and removal of temporary write automation.

@opencode-agent Please rerun exact-head review after central npm-workspace coverage ownership is repaired; do not reuse the prior incomplete coverage evidence.

@cwl-noema-review Please independently review this exact head. Merge remains subject to current-head checks, unresolved-thread policy, and qualifying non-author approval.

@seonghobae
seonghobae enabled auto-merge (squash) August 5, 2026 12:04
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='4fe7348987551937ea88ef2ef324348274837e79'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"
test "$actual" = "$expected"

printf '\n--- changed files ---\n'
git diff-tree --no-commit-id --name-status -r "$expected"

printf '\n--- implementation outlines ---\n'
ast-grep outline apps/desktop/src/lib/handoff.ts --items all
ast-grep outline apps/desktop/src/features/import/HandoffImportControl.tsx --items all
ast-grep outline apps/desktop/src/App.tsx --items all --match 'App|handle|select|handoff|analysis'
ast-grep outline services/analysis-engine/src/bandscope_analysis/api.py --items all --match 'focus|cache|analy|song'

printf '\n--- bounded intake and request construction ---\n'
cat -n apps/desktop/src/lib/handoff.ts

printf '\n--- import control state and accessible markup ---\n'
cat -n apps/desktop/src/features/import/HandoffImportControl.tsx

printf '\n--- parent source/handoff state and source action interlock ---\n'
rg -n -C 12 -e 'handoff|Handoff|selectedSource|selectSource|createAnalysisRequestForSelection|YouTube|isReading' apps/desktop/src/App.tsx

printf '\n--- role focus and cache paths ---\n'
rg -n -C 18 -e '_focus_rehearsal_song|roleFocus|cache|cached|partGraph|handoff' services/analysis-engine/src/bandscope_analysis/api.py

printf '\n--- validator and reanalysis constructor ---\n'
rg -n -C 12 -g '*.{ts,tsx}' \
  -e 'function parseMetadataHandoffArtifact\b|const parseMetadataHandoffArtifact\b|parseMetadataHandoffArtifact\s*=' \
  -e 'function createReanalysisRequestFromHandoff\b|const createReanalysisRequestFromHandoff\b|createReanalysisRequestFromHandoff\s*=' \
  packages apps

printf '\n--- focused regression tests ---\n'
cat -n apps/desktop/src/lib/handoff.test.ts
cat -n apps/desktop/src/features/import/HandoffImportControl.test.tsx
cat -n apps/desktop/src/App.handoff.test.tsx
cat -n services/analysis-engine/tests/test_role_focus.py

printf '\n--- artifact access and possible dereference/automatic action APIs ---\n'
rg -n -P -C 4 \
  '(sourceAssets|artifactKind|artifactVersion|workspace\.|song\.|roleBuckets|readFile|readTextFile|readBinaryFile|fetch\s*\(|axios|XMLHttpRequest|urlopen|requests\.)' \
  apps/desktop/src packages/shared-types/src services/analysis-engine/src \
  -g '*.{ts,tsx,py}' | head -n 800

printf '\n--- temporary write automation candidates ---\n'
rg -n -i -C 3 \
  '(temporary|temp(orary)?|write automation|write[_ -]?automation|autofix|codemod|writeFile|writeTextFile|git\s+commit|git\s+push)' \
  .github package.json apps services packages \
  -g '!**/node_modules/**' -g '!**/dist/**' 2>/dev/null || true

Length of output: 202868


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='4fe7348987551937ea88ef2ef324348274837e79'
test "$(git rev-parse HEAD)" = "$expected"

printf '%s\n' '--- changed paths ---'
git diff-tree --no-commit-id --name-only -r "$expected"

printf '%s\n' '--- handoff intake ---'
sed -n '1,240p' apps/desktop/src/lib/handoff.ts

printf '%s\n' '--- handoff import control ---'
sed -n '1,260p' apps/desktop/src/features/import/HandoffImportControl.tsx

printf '%s\n' '--- App handoff state, handlers, and source controls ---'
rg -n -C 18 -e 'const \[handoff|const \[.*Reading|handleHandoff|onReadingChange|onImported|onError|HandoffImportControl|selectLocal|selectYouTube|startAnalysis|createAnalysisRequestForSelection' apps/desktop/src/App.tsx

printf '%s\n' '--- parser contract and reanalysis constructor ---'
rg -n -C 10 -e 'parseMetadataHandoffArtifact|createReanalysisRequestFromHandoff' packages/shared-types/src/index.ts apps/desktop/src/lib/export.ts

printf '%s\n' '--- role focus implementation and cache call sites ---'
rg -n -C 24 -e '^def _focus_rehearsal_song|_focus_rehearsal_song\(|_load_cached_analysis|_store_cached_analysis|cache_key|role_focus' services/analysis-engine/src/bandscope_analysis/api.py

printf '%s\n' '--- focused tests: stale reads, reselection, intake, and cache isolation ---'
rg -n -C 8 -e 'reading|replace|stale|race|selectedSource|roleFocus|cache|too large|UTF-8|artifact' \
  apps/desktop/src/lib/handoff.test.ts \
  apps/desktop/src/features/import/HandoffImportControl.test.tsx \
  apps/desktop/src/App.handoff.test.tsx \
  services/analysis-engine/tests/test_role_focus.py

printf '%s\n' '--- changed workflow or automation files only ---'
git diff-tree --no-commit-id --name-only -r "$expected" | \
  rg '(^|/)(\.github/|package\.json$|.*\.(sh|yml|yaml|js|cjs|mjs|ts)$)' || true

Length of output: 92449


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='4fe7348987551937ea88ef2ef324348274837e79'
test "$(git rev-parse HEAD)" = "$expected"

printf '%s\n' '--- strict metadata artifact validator ---'
sed -n '820,955p' packages/shared-types/src/index.ts

printf '%s\n' '--- complete focused projection ---'
sed -n '590,670p' services/analysis-engine/src/bandscope_analysis/api.py

printf '%s\n' '--- localized, payload-free handoff errors ---'
rg -n -C 8 -e 'function handoffErrorMessage|const handoffErrorMessage|handoffErrorMessage|handoff.*(unsupported|tooLarge|invalid|read)' \
  apps/desktop/src/App.tsx apps/desktop/src/locales/en/common.json apps/desktop/src/locales/ko/common.json

printf '%s\n' '--- imported source-assets references and operation call sites ---'
rg -n -C 5 -g '*.{ts,tsx,py}' \
  -e '\bsourceAssets\b' \
  -e '(fetch|readFile|readTextFile|readBinaryFile|open|urlopen|requests\.)\s*\(' \
  apps/desktop/src packages/shared-types/src services/analysis-engine/src | head -n 500

Length of output: 34677


@seonghobae I reviewed exact head 4fe7348987551937ea88ef2ef324348274837e79.

No blocker remains.

The handoff reader enforces the byte limit before decode. It rechecks the received byte length. It uses strict UTF-8 decoding and strict artifact validation. The artifact validator rejects unsupported kind, version, fields, and nested payload shapes.

The parent receives the reading state. During validation, the UI disables local audio selection, YouTube import, and analysis start. A successful import clears the prior local source. The user must select a new local audio source before analysis can start.

Handoff failures use fixed localized error codes. The UI does not expose file names, payload content, paths, or parser errors. The import flow does not dereference sourceAssets or start analysis automatically.

Role projection creates new focused section and part-graph structures. It filters graph links to focused roles. Cache hits retain the complete cached result and project per request. Cache misses store the complete result before returning the focused result. The regression tests cover both paths.

The exact commit contains no workflow or temporary write-automation change.

[approve]

You are interacting with an AI system.

@opencode-agent
opencode-agent Bot disabled auto-merge August 5, 2026 13:24

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently re-review exact current head 4fe7348987551937ea88ef2ef324348274837e79. All repository-local CI, build, release, npm/Python/Rust security audit, Bandit, Semgrep, Security Scan, secret scan, and SBOM workflows succeeded on this SHA; all inline findings are resolved or outdated. Central coverage still depends on both ContextualWisdomLab/.github#743 for trusted Python locks and #748 for the desktop npm workspace owner.

@seonghobae
seonghobae enabled auto-merge (squash) August 6, 2026 08:54
@opencode-agent
opencode-agent Bot disabled auto-merge August 6, 2026 10:02
@seonghobae
seonghobae enabled auto-merge (squash) August 7, 2026 10:18
@opencode-agent
opencode-agent Bot disabled auto-merge August 7, 2026 10:42
@seonghobae
seonghobae enabled auto-merge (squash) August 7, 2026 11:00
@opencode-agent
opencode-agent Bot disabled auto-merge August 7, 2026 11:37
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.

[Product Gap] Complete the rehearsal handoff round trip

2 participants