feat(tuner): gate playback until you've tuned — hold autoplay + no-trap Skip/Back/Esc (working-tuning PR 4)#666
Merged
Conversation
byrongamatos
force-pushed
the
feat/v3-tuner-uses-working-tuning
branch
from
July 1, 2026 07:23
6cf14be to
36fd8d1
Compare
…ap Skip/Back/Esc (working-tuning PR 4) When the opt-in auto-open fires because a song needs a different tuning, playback now WAITS behind the tuner instead of starting underneath it — the "tune before you play" model. Built on a new generic core hook window.feedBack.holdAutoplay() (mirrors holdAutoExit): the tuner claims the hold synchronously on song:loading (beating the song:ready autostart) and releases it — or a 12s fail-open backstop does — so a wedged plugin can never strand a song. Generation-guarded; manual Play always wins. No one-way trap: - Skip = "I've tuned" -> plays and records the song's tuning as the instrument's current working tuning (the explicit write-point PR 3 left as 'assumed'). - Back to library / Esc -> leave the song, record nothing (reuses requestExitSong; Esc is the existing player shortcut). - The in-panel x is dropped for an auto-open — Skip/Back/Esc are the dismiss surface. This also keeps the write honest: Skip is the only on-player dismiss that records, so leaving never falsely records a tuning. Stacked on #660 (working-tuning PR 3). Core app.js gains only the generic hook (a test asserts it never references the tuner's internals); shell-agnostic. Needs a desktop smoke-test that the tuner mic doesn't contend with note_detect's scoring input under ASIO/exclusive mode (per the design charrette). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF
… (PR #666 review) Review fixes for the autoplay gate: - The 12s fail-open backstop could start playback UNDER a legitimately-open tuner (a slow / mic-verify retune > 12s). holdAutoplay()'s release now carries a .settle() that cancels the backstop; the tuner calls it once the tuner is confirmed open (_gateClaimed), so the hold becomes deliberate and only a dismiss / song switch releases it. (Fail-open still covers "claimed but wedged before deciding".) - The async song:ready handler could release a NEWER song's gate after its await (global _gateClaimed, no guard). It now snapshots _autoOpenGeneration and bails if a newer song took over. - holdAutoplay guarded by song generation, not per-hold — a stale release from an earlier hold could clear a later one. Each hold now mints a unique token that release()/settle() must match. Tests: source-level assertions for the token, settle(), the settle-on-open call, and the song:ready gen-guard. 45 tuner+speed tests green. Codex-reviewed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
byrongamatos
force-pushed
the
feat/v3-tuner-playback-gate
branch
from
July 1, 2026 09:18
7592e0d to
ba957a2
Compare
byrongamatos
changed the base branch from
feat/v3-tuner-uses-working-tuning
to
main
July 1, 2026 09:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Working-tuning PR 4 (the gate). Stacked on #660 → base is
feat/v3-tuner-uses-working-tuning; review/merge after the #655→#660 stack.What
When the opt-in tuner auto-open fires because a song needs a different tuning, playback now waits behind the tuner instead of starting underneath it — the "tune before you play" model — and it's never a one-way trap.
How
window.feedBack.holdAutoplay()(static/app.js) — mirrors the existingholdAutoExit(). The tuner claims the hold synchronously onsong:loading(beating thesong:readyautostart that caused the original flash), andrelease()— or a 12s fail-open backstop — runs the deferred start. Generation-guarded (a new song invalidates a stale hold); manual Play always wins. The hook is generic — a test assertsapp.jsnever references the tuner's internals.plugins/tuner/screen.js+plugins/tuner/utils/ui.js):assumed).requestExitSong; Esc is the existing player "Back to library" shortcut).Test
node --test— 36 green: the ported gate tests (claim onsong:loading, release on dismiss, feature-off no-claim, the core hook + fail-open backstop), #660's working-tuning tests, and a new static test for the Skip / Back-to-library / Esc escape-hatch wiring.⚠ Pre-ship smoke-test (per the design charrette)
This is a core playback change. On desktop with a real mic, verify: (1) Esc/Back exits cleanly mid-gate (not swallowed by the tuner), and (2) the tuner's mic doesn't contend with note_detect's scoring input under ASIO / exclusive mode.
🤖 Generated with Claude Code
https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF