Skip to content

feat(workspace): count in tonight's first click before the range - #1070

Draft
seonghobae wants to merge 8 commits into
developfrom
feat/workspace-first-count-in
Draft

feat(workspace): count in tonight's first click before the range#1070
seonghobae wants to merge 8 commits into
developfrom
feat/workspace-first-count-in

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Buyer-visible gap

The ready rehearsal map already names tonight's first playable range, but it did not give the player a count-in they can take before checking that span. Seeing 120 BPM is not the same as counting in four and then checking the part.

This remains a local rehearsal aid, not a song-wide beat tracker, stem player, or MIR tempo estimator. #828 continues to own #770; trusted click authority is the already-owned song.tempo field, admitted only when finite and within 20–400 BPM.

Exact current identity

  • Protected base: develop@314ddeae7b775a4957594b599358c8255617eb2e.
  • Branch: feat/workspace-first-count-in.
  • Exact current head: a2cc3f859822615c66fd102839046637a41f371c.
  • Open, Draft, mergeable, intentionally unmerged.
  • Fresh compare to protected develop: behind_by=0; exactly 17 intended count-in product/test/docs/locales/config files remain.

Non-force protected-base repair

The previous exact head 92d8ffe3df69f33f43367e610cc2ffa08105e768 was based on develop@749511c3... while protected develop had advanced through current workflow/security control and Cargo lock truth. The repair used an ordinary two-parent descendant of 92d8ffe3... and protected 314ddeae...; no force-push or destructive rebase was used.

The intervening protected delta overlapped this lane only in CHANGELOG.md. The repaired tree starts from current protected develop, overlays this PR's sixteen non-Changelog semantic blobs, and reconciles the changelog so #1165's security-backstop consolidation and the count-in product note both remain. Protected workflow/security/Cargo.lock files are not copied into this product owner.

Product outcome and current contract

When analysis is ready, the map can name tonight's first count-in and the next action:

  • trusted BPM plus named section: count in four at the trusted tempo, then check tonight's first range before that section;
  • trusted BPM without a named section: keep the trusted tempo but ask the room to name the section start;
  • missing or unusable tempo: fail closed to an ear-count instruction rather than synthesizing unsupported timing authority.

The Count in control synthesizes a four-beat click locally through Web Audio, then returns the player to the named rehearsal action. English and Korean copy remain aligned in this slice.

Repair history retained

The current product/test tree preserves the earlier test-first repairs rather than replacing them with prose:

  • 35bde907fa9b5bdb9d84b42e80c8c0e9746bef6b added regressions for stop-during-AudioContext.resume, completed node cleanup, plan-change/unmount invalidation and onset overflow before the corresponding production repair;
  • ceaff8aae22681c7fe3a4134901a08043ab9c1cc invalidated stale playback before scheduling, settled pending completion, released oscillator/gain nodes and rejected non-finite onsets;
  • fbdd543908c8137d320cce7dceef82a9a2cb6387 corrected the primary W3C Web Audio citation in the owning doctoring record;
  • 79a863b3fa0dd4ece183f0254276bf83bfc8af76 added the equivalent-plan regression;
  • predecessor head 92d8ffe3... keyed lifecycle cleanup to semantic timing/guidance rather than object identity.

Historical predecessor check results remain historical after this restack and do not transfer to a2cc3f85....

Security Notes

  • Untrusted input: runtime song.tempo and section labels.
  • Trust boundary: React state → bounded tempo/section resolver → local AudioContext oscillator graph.
  • Safe failure: out-of-range/non-finite tempo, malformed song data, invalid onset arithmetic or unavailable Web Audio do not start an unsupported click.
  • No filesystem, URL, subprocess, IPC, WebView, model, export, dependency, network or persistent permission authority is added by this slice.
  • Stop, unmount, semantic-plan change and playback replacement invalidate stale async work and release tracked audio nodes.
  • No raw media, local path, credential or secret-bearing payload is logged or rendered.

Verification boundary

The protected-base restack changed the exact head. Every check, review and approval attached to 92d8ffe3... or earlier is predecessor evidence only. Re-evaluate repository/central CI, Windows/macOS build, security/SAST/dependency/SBOM/coverage/review and live protection on unchanged a2cc3f859822615c66fd102839046637a41f371c only.

UI Delivery Gate

FAIL until this exact head has terminal-success applicable checks, zero valid actionable findings, qualifying independent non-author last-push approval, and current-head keyboard/pointer/accessibility evidence. Source behavior is preserved, but it is not shipped UI truth yet.

Merge gate

Keep Draft and unmerged until one unchanged exact head satisfies every applicable repository and central gate, exact required owned coverage/docstring evidence, zero valid unresolved findings, a qualifying independent non-author approval and ordinary protected-branch acceptance without bypass. Queued, pending, skipped-required, cancelled, failed, stale, predecessor/base, model-only, self/author or administrative-bypass evidence is non-passing.

Play a local four-beat click from a trusted 20–400 BPM so the ready map
names a next action a player can take before checking tonight's first
range. Missing tempo or AudioContext fails closed to an ear count.

This is not song playback, stem isolation, or a parallel MIR product.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: 5f279b7d-bfe4-49c1-9372-c9235ec3c8ec

📥 Commits

Reviewing files that changed from the base of the PR and between 64576f2 and 92d8ffe.

📒 Files selected for processing (8)
  • apps/desktop/src/features/workspace/CountInClick.semantic-plan.test.tsx
  • apps/desktop/src/features/workspace/CountInClick.test.tsx
  • apps/desktop/src/features/workspace/CountInClick.tsx
  • apps/desktop/src/features/workspace/countInClickEngine.test.ts
  • apps/desktop/src/features/workspace/countInClickEngine.ts
  • apps/desktop/src/features/workspace/firstCountIn.test.ts
  • apps/desktop/src/features/workspace/firstCountIn.ts
  • docs/doctoring/workspace-first-count-in-click.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/doctoring/workspace-first-count-in-click.md

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


📝 Walkthrough

Walkthrough

BandScope 데스크톱 워크스페이스에 신뢰된 곡 템포 기반의 4비트 로컬 카운트인 클릭 기능이 추가되었습니다. Web Audio 재생 엔진, 상태별 UI, 입력 검증, 번역, 테스트와 문서가 포함됩니다.

Changes

첫 카운트인 클릭 기능

Layer / File(s) Summary
카운트인 계획 및 입력 검증
apps/desktop/src/features/workspace/firstCountIn.ts, apps/desktop/src/features/workspace/firstCountIn.test.ts
20–400 BPM의 유한한 템포에서 4비트 계획을 생성합니다. 첫 번째 의미 있는 섹션 라벨과 onset 배열을 계산합니다. 잘못된 입력은 null 또는 빈 배열로 처리합니다.
Web Audio 클릭 엔진
apps/desktop/src/features/workspace/countInClickEngine.ts, apps/desktop/src/features/workspace/countInClickEngine.test.ts
첫 박을 강조한 클릭을 예약합니다. 일시 중지된 컨텍스트를 재개하고, 재생 중인 oscillator와 gain node를 중지·해제합니다. 비동기 중지와 완료 상태를 재생 세대로 관리합니다.
워크스페이스 UI 통합
apps/desktop/src/features/workspace/Workspace.tsx, apps/desktop/src/features/workspace/CountInClick.tsx, apps/desktop/src/features/workspace/*test.tsx, apps/desktop/src/locales/*/common.json, apps/desktop/vite.config.ts
워크스페이스가 카운트인 계획을 계산하고 UI를 렌더링합니다. 재생, 완료, 중지, 오디오 불가, 템포 누락 상태를 표시합니다. 중복 실행과 오래된 비동기 완료를 차단합니다.
기능 문서 및 프로젝트 설명
AGENTS.md, ARCHITECTURE.md, CHANGELOG.md, CLAUDE.md, docs/doctoring/workspace-first-count-in-click.md
카운트인 클릭 기능과 신뢰 경계, Web Audio API 사용 기준을 프로젝트 문서와 변경 로그에 반영합니다.

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

Merge Risk: 🟡 Moderate · up to 92d8f

The PR adds a short local four-beat count-in before the first rehearsal range without expanding data or system access. No material runtime or security risk remains, but the current head should not merge until required checks and approvals reach terminal success; the architecture document also retains a 2026-08-30 update date, which needs explicit correction or acceptance relative to August 29, 2026.

Sequence Diagram(s)

sequenceDiagram
  participant 연주자
  participant Workspace
  participant CountInClick
  participant CountInClickEngine
  participant WebAudio
  연주자->>Workspace: 워크스페이스 열기
  Workspace->>CountInClick: 곡 기반 카운트인 계획 전달
  연주자->>CountInClick: 카운트인 재생 선택
  CountInClick->>CountInClickEngine: 계획으로 play 호출
  CountInClickEngine->>WebAudio: 박별 oscillator와 gain node 예약
  WebAudio-->>CountInClickEngine: 클릭 재생 완료
  CountInClickEngine-->>CountInClick: 완료 반환
  CountInClick-->>연주자: 첫 구간 확인 안내 표시
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
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 12 functions across 10 files. (1 skipped: 1…
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 제목은 작업공간에 오늘 밤 첫 음역 전에 카운트인 클릭을 추가하는 주요 변경 사항을 정확하고 간결하게 설명합니다.
✨ 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-count-in

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.

coderabbitai[bot]

This comment was marked as resolved.

Pin the current review findings before changing production behavior: a stop during suspended AudioContext resume must prevent oscillator creation, completed nodes must disconnect, plan replacement/unmount must invalidate stale completion, and finite onset multiplication must fail closed on overflow.
devin-ai-integration[bot]

This comment was marked as resolved.

Invalidate plays that are stopped while AudioContext resume is pending, settle pending completion waits, disconnect oscillator and gain nodes after completion, reset component state across plan/engine changes and unmount, and fail closed if onset multiplication overflows. Add required JSDoc on the touched local handlers.
devin-ai-integration[bot]

This comment was marked as resolved.

Pin the current-head review finding: recreating an equivalent count-in plan must not stop active playback or clear completion state when timing and section authority are unchanged.
Key the lifecycle reset to the count-in plan's semantic timing and section fields instead of object identity so unrelated song updates cannot stop a still-valid click or clear its completion guidance.
devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Please perform the required independent formal review on exact current head b35d8b0ca01db56276e22c6929b79e4750bacdac against independently resolved develop@749511c3ad4000090048718f685c6bee6b3d2c25. Revalidate the regression-first repairs for stop-during-AudioContext-resume cancellation, completed oscillator/gain cleanup, plan-change and unmount invalidation, finite onset arithmetic, and equivalent-plan lifecycle preservation; also verify the local Web Audio trust boundary, 20–400 BPM admission, unlabeled-section product contract, current JSDoc/coverage/security evidence, and the corrected Web Audio 1.1 primary citation. Post an authenticated APPROVED or CHANGES_REQUESTED verdict anchored to this exact head; do not reuse predecessor reviews or mutate the branch.

@opencode-agent

Copy link
Copy Markdown
Contributor

Queued @opencode-agent for PR #1070 at head 92d8ffe3df69f33f43367e610cc2ffa08105e768. 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

Succession control (fresh 2026-09-02 comparison): #971 is the canonical #961 Active Player owner. Its current RehearsalPlayer already owns the single transport state machine, local Tauri-asset playback, loop timing, playback-rate changes, cue navigation, and count-in phase progression. However, the current #971 implementation advances count-in beats with timers and mutes song audio until loop entry; it does not synthesize an audible click. This PR still uniquely contains the bounded Web Audio oscillator/gain click behavior and lifecycle regressions (stop/unmount/resume invalidation and node cleanup). Therefore this PR is not superseded and must not be closed yet. Keep further product work on #971; transfer/reconstruct the audible-click behavior and its tests into #971 without introducing a second transport store, then re-compare exact heads before closing this preservation PR. Predecessor checks/reviews do not transfer.

Copy link
Copy Markdown
Collaborator Author

Succession update: the canonical #971 branch now carries source-order RED 4534e842da9e9c0167c62cd6fb1d9e833fb09965 for an audible transport count-in, a bounded local Web Audio engine with lifecycle coverage (e21a6cc9bc52d126490d5c6201a189c334bd0fb8, 07c001c728a69ba1807d21a549b184694e9b150b, a3bc430bf310a89052c291d9748f46ef1951d5cb), and production integration at exact #971 head effb2376cf952ffbfc10f92b5612eed75d4c5056. The integration reuses #971's existing transport/count-in clock rather than introducing a second state machine; first beat is accented, subsequent beats are taps, rate changes do not replay the current beat, and pause/stop/unmount invalidate live nodes. Exact-head hosted workflows for effb2376… are currently queued, therefore no GREEN/approval/check evidence is being transferred or claimed. Keep #1070 open as a preservation source until fresh semantic comparison proves its remaining unsupported-host/failure-copy and lifecycle contracts are either preserved by #971 or deliberately retired under the canonical product contract.

@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 reviewed the current-head product diff. Coverage is a separate gate.

Changed files

  • AGENTS.md — repository behavior
  • ARCHITECTURE.md — repository behavior
  • CHANGELOG.md — repository behavior
  • CLAUDE.md — repository behavior
  • apps/desktop/src/features/workspace/CountInClick.semantic-plan.test.tsx — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/CountInClick.test.tsx — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/CountInClick.tsx — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/Workspace.test.tsx — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/Workspace.tsx — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/countInClickEngine.test.ts — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/countInClickEngine.ts — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/firstCountIn.test.ts — TypeScript or JavaScript runtime
  • apps/desktop/src/features/workspace/firstCountIn.ts — TypeScript or JavaScript runtime
  • apps/desktop/src/locales/en/common.json — repository behavior
  • apps/desktop/src/locales/ko/common.json — repository behavior
  • apps/desktop/vite.config.ts — TypeScript or JavaScript runtime
  • docs/doctoring/workspace-first-count-in-click.md — operator or user guidance

Changed behavior

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Repository file: AGENTS.md"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Repository file: AGENTS.md"]
  R1 --> V1["required checks"]
  Evidence --> S2["Repository file: ARCHITECTURE.md"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: ARCHITECTURE.md"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: CHANGELOG.md"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: CHANGELOG.md"]
  R3 --> V3["required checks"]
  Evidence --> S4["Repository file: CLAUDE.md"]
  S4 --> I4["repository behavior"]
  I4 --> R4["Review risk: Repository file: CLAUDE.md"]
  R4 --> V4["required checks"]
  Evidence --> S5["TypeScript/JavaScript: CountInClick.semantic-plan.test.tsx (10 files)"]
  S5 --> I5["TypeScript or JavaScript runtime"]
  I5 --> R5["Review risk: TypeScript/JavaScript: CountInClick.semantic-plan.test.tsx (10 files)"]
  R5 --> V5["package test plus coverage"]
  Evidence --> S6["Repository file: common.json"]
  S6 --> I6["repository behavior"]
  I6 --> R6["Review risk: Repository file: common.json"]
  R6 --> V6["required checks"]
  Evidence --> S7["Repository file: common.json"]
  S7 --> I7["repository behavior"]
  I7 --> R7["Review risk: Repository file: common.json"]
  R7 --> V7["required checks"]
  Evidence --> S8["Docs: workspace-first-count-in-click.md"]
  S8 --> I8["operator or user guidance"]
  I8 --> R8["Review risk: Docs: workspace-first-count-in-click.md"]
  R8 --> V8["docs review"]
Loading

Findings

No source-backed product finding is synthesized from the coverage gate. A coverage miss belongs in the status comment.

  • Head SHA: 92d8ffe3df69f33f43367e610cc2ffa08105e768
  • Workflow run: 33745987705
  • Workflow attempt: 1
  • Coverage gate: failure

Review outcome

Coverage is a gate, not the review. This body reviews the changed product files.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Repository file: AGENTS.md"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Repository file: AGENTS.md"]
  R1 --> V1["required checks"]
  Evidence --> S2["Repository file: ARCHITECTURE.md"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: ARCHITECTURE.md"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: CHANGELOG.md"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: CHANGELOG.md"]
  R3 --> V3["required checks"]
  Evidence --> S4["Repository file: CLAUDE.md"]
  S4 --> I4["repository behavior"]
  I4 --> R4["Review risk: Repository file: CLAUDE.md"]
  R4 --> V4["required checks"]
  Evidence --> S5["TypeScript/JavaScript: CountInClick.semantic-plan.test.tsx (10 files)"]
  S5 --> I5["TypeScript or JavaScript runtime"]
  I5 --> R5["Review risk: TypeScript/JavaScript: CountInClick.semantic-plan.test.tsx (10 files)"]
  R5 --> V5["package test plus coverage"]
  Evidence --> S6["Repository file: common.json"]
  S6 --> I6["repository behavior"]
  I6 --> R6["Review risk: Repository file: common.json"]
  R6 --> V6["required checks"]
  Evidence --> S7["Repository file: common.json"]
  S7 --> I7["repository behavior"]
  I7 --> R7["Review risk: Repository file: common.json"]
  R7 --> V7["required checks"]
  Evidence --> S8["Docs: workspace-first-count-in-click.md"]
  S8 --> I8["operator or user guidance"]
  I8 --> R8["Review risk: Docs: workspace-first-count-in-click.md"]
  R8 --> V8["docs review"]
Loading

@opencode-agent

opencode-agent Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

Coverage evidence did not pass, so approval is blocked. The formal pull-request review is the source-backed diff review, not this status comment.

@seonghobae
seonghobae marked this pull request as draft September 4, 2026 15:09

Copy link
Copy Markdown
Collaborator Author

Current-authority repair finding: protected develop is now 314ddeae7b775a4957594b599358c8255617eb2e, while this PR still reports base SHA 749511c3ad4000090048718f685c6bee6b3d2c25. I converted the PR back to Draft so the older terminal repository checks cannot be mistaken for current protected-base merge evidence. The product delta is retained; do not close it. Next repair is an ordinary non-force descendant restack that adopts intervening protected workflow/security/dependency truth, explicitly reconciles overlapping docs/CHANGELOG if any, and then reacquires exact-head checks/review. Existing Noema/Strix/OpenCode failures and prior approvals/checks remain historical and non-transferable.

Adopt current protected workflow/security and lockfile truth while preserving the canonical first-count-in product/test/doc delta. Reconcile CHANGELOG so protected #1165 entries remain intact.

Signed-off-by: Seongho Bae <me@seonghobae.me>
Commit-Message-Assisted-by: ChatGPT (OpenAI)
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