ledger: iteration 3 reconciled — L-33/L-31 done (gate notes logged); P-31 gating; C-31 ready

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
vadimwit
2026-07-10 09:47:20 +01:00
parent ce24d5490f
commit 0b982f9514
+8 -3
View File
@@ -22,13 +22,13 @@ The shared queue all agents read and write. Lifecycle and rules: [`PROTOCOL.md`]
| M-04 | Seed `sprint-glance-and-loop` from user directive 2026-07-10; schedule the 24×30m loop | maestro | done | — | `docs/agents/LEDGER.md` | sprint seeded, cron created |
| C-30 | Loop-detection truth fixtures: new `scripts/loop-fixtures.mjs` (+ smoke wiring) — realistic chord-history cases with expected loops: (a) clean 3-chord loop ×23 reps; (b) 3-chord loop with one spurious misdetection inside a rep; (c) consecutive duplicate commits of the same chord; (d) 5-chord loop followed by 2 foreign chords — loop must survive; (e) 7- and 8-chord loops; (f) section change loop-A→loop-B — detection must switch; (g) chromatic non-loop → null. Run each against the CURRENT `detectRepeatingProgression` and mark which fail today (`expectedFail: true`) so the suite is green now and L-30 flips the markers off | quality | done | — | `scripts/loop-fixtures.mjs`, `scripts/smoke.mjs` | fixtures runnable via smoke; failure map of the current algorithm documented in the fixture file header; smoke green (expected-fails annotated, not silently skipped) |
| L-30 | Redesign `detectRepeatingProgression` in `theory.js`: collapse consecutive duplicate chords before matching; tolerate ≤1 substitution/insertion per cycle (noise from misdetection); support loop lengths 28; recency-weighted scoring so an old section can't outvote the current loop; keep the pure signature, the rotation-`canonicalize` output, and every other export byte-untouched. Flip all C-30 `expectedFail` markers to passing. **C-30 findings folded in (2026-07-10):** (a) the `reps × len²` scoring artifact is the primary everyday bug — a clean 2-chord vamp ×4 reports a bogus 3-chord `[Am,Am,G]` via self-overlapping occurrences; candidate generation must reject candidates that are rotations/overlaps of a shorter period (not just exact periodic patterns at len ≥ 4); (b) 7/8-loops contain realistic non-adjacent internal chord repeats (`Am … Am`) — period detection must not collapse those into shorter false loops | engineering | done | C-30 | `src/lib/theory.js` (detectRepeatingProgression + private helpers only) | all C-30 fixtures green with zero expectedFail markers (incl. `vamp-2x4`/`vamp-2-sustained`); no other theory.js export changed; build + smoke green |
| L-31 | Commit-layer tuning in App.jsx's progression effect (lines ~154-173): a committed loop must survive transient misses (the miss-4-then-clear rule drops the loop during fills/turnarounds); a new loop replaces the old only with consistent evidence; first commit shouldn't need extra rounds when detection is already stable. **Primary trace case (C-30 finding, 2026-07-10):** pre-L-30 detection flaps between the true loop and ghost 4-patterns, so `progressionVoteRef` never sees 2 consecutive identical keys and nothing ever commits — verify post-L-30 stability makes the 2-vote commit reachable in the noisy fixtures, then tune (post-L-30 status: claimed). **L-30 gate findings folded in (2026-07-10):** (a) a 2-rep loop with one corrupted rep FLAPS through data-faithful sub-cycles commit-to-commit until the next clean rep — faster first-commit must NOT let a single transient sub-cycle detection replace an already-committed loop (replacement needs consistent evidence); note non-null detection resets the miss counter, so today's committed loop already survives the flap; (b) ride-along one-line fix: theory.js ~line 601-603 docstring overclaims "ghost occurs exactly once by construction" — false for same-chord-same-phase corruption (behavior fine, comment too strong); (c) deletions untolerated by design — fine at ≥3 reps, degrades to (a)'s flapping at exactly 2. 🚨 **Audio contract: touch ONLY the progression useEffect + its refs — no callback, ref-sync, or AudioCapture change** | engineering | claimed | L-30 | `src/App.jsx` (progression effect only) | loop survives fixture-style fills end-to-end (hand-trace documented in commit); App.jsx diff confined to the progression effect block; build + smoke green |
| L-31 | Commit-layer tuning in App.jsx's progression effect (lines ~154-173): a committed loop must survive transient misses (the miss-4-then-clear rule drops the loop during fills/turnarounds); a new loop replaces the old only with consistent evidence; first commit shouldn't need extra rounds when detection is already stable. **Primary trace case (C-30 finding, 2026-07-10):** pre-L-30 detection flaps between the true loop and ghost 4-patterns, so `progressionVoteRef` never sees 2 consecutive identical keys and nothing ever commits — verify post-L-30 stability makes the 2-vote commit reachable in the noisy fixtures, then tune (post-L-30 status: done). **L-30 gate findings folded in (2026-07-10):** (a) a 2-rep loop with one corrupted rep FLAPS through data-faithful sub-cycles commit-to-commit until the next clean rep — faster first-commit must NOT let a single transient sub-cycle detection replace an already-committed loop (replacement needs consistent evidence); note non-null detection resets the miss counter, so today's committed loop already survives the flap; (b) ride-along one-line fix: theory.js ~line 601-603 docstring overclaims "ghost occurs exactly once by construction" — false for same-chord-same-phase corruption (behavior fine, comment too strong); (c) deletions untolerated by design — fine at ≥3 reps, degrades to (a)'s flapping at exactly 2. 🚨 **Audio contract: touch ONLY the progression useEffect + its refs — no callback, ref-sync, or AudioCapture change** | engineering | done | L-30 | `src/App.jsx` (progression effect only) | loop survives fixture-style fills end-to-end (hand-trace documented in commit); App.jsx diff confined to the progression effect block; build + smoke green |
| D-30 | VoicingBrowser gallery: render ALL matching guitar shapes side by side (each = label + ChordDiagram + its own ▶) and all four piano styles side by side (label + MiniPiano thumb + ▶) — no chips, no selection state; grid wraps on narrow viewports; one-at-a-time playback preserved (new play stops the previous). All existing mounts (Voicings section, ChordDetailModal tabs, JamGuide station-enlarge) get the gallery automatically; `show` prop semantics unchanged | design | done | — | `src/components/VoicingBrowser.jsx` | every placeable shape/style visible simultaneously with zero clicks; AA contrast + tokens; keyboard-reachable play buttons; build + smoke green |
| D-31 | Glance-mode concept doc: the Knowledge Center panel open WHILE the jam plays — what auto-follows live detection with zero clicks (current station's voicing gallery inline? licks strip for the style? what stays on screen vs behind interaction), density/space budget vs the Roadmap track, narrow-viewport plan, and the migration order for L-33. No user gate: pick the strongest layout, record rationale + rejected alternatives. **Returned once (2026-07-10):** piano gallery width understated ~45% (2-octave crops for rootless 7th-chord voicings → ~940px not 640; scroll is the piano rail's normal state on most loops) + licks strip ~190px not 150 + 4 clarifying notes; layout itself held — fixed + re-gate PASS | design | done | — | `docs/design/glance-mode.md` | doc names every component to touch, the auto-follow rules, and honest space math (what fits at 1280×900 and at narrow) |
| L-33 | Implement glance mode per D-31 (`docs/design/glance-mode.md` — the "playhead accordion"): the station column at canonicalPos expands to the full D-30 gallery and advances with the playhead; licks strip below (level-filtered, token-boundary context match, strip-owned "fits — now" chrome, guitar licks under piano tab with honest heading); pin gesture inherits onFocusChord semantics; auto-follow never emits focus-chord and never auto-plays audio; piano rail EXPECTED to scroll (never assert one-row fits); follow the doc's 5-commit migration order | engineering | claimed | D-30, D-31 | `src/components/GlanceRail.jsx` (new), `src/components/JamGuide.jsx`, `src/components/VoicingBrowser.jsx` (optional additive `dense` prop only) | glance behaviours live per the doc; audio contract intact (App.jsx untouched or additive-only); build + smoke green |
| L-33 | Implement glance mode per D-31 (`docs/design/glance-mode.md` — the "playhead accordion"): the station column at canonicalPos expands to the full D-30 gallery and advances with the playhead; licks strip below (level-filtered, token-boundary context match, strip-owned "fits — now" chrome, guitar licks under piano tab with honest heading); pin gesture inherits onFocusChord semantics; auto-follow never emits focus-chord and never auto-plays audio; piano rail EXPECTED to scroll (never assert one-row fits); follow the doc's 5-commit migration order | engineering | done | D-30, D-31 | `src/components/GlanceRail.jsx` (new), `src/components/JamGuide.jsx`, `src/components/VoicingBrowser.jsx` (optional additive `dense` prop only) | glance behaviours live per the doc; audio contract intact (App.jsx untouched or additive-only); build + smoke green |
| P-30 | KB expansion: **neo-soul/rnb piano** cell (next per `docs/kb-backlog.md` after jazz/gospel) | content | done | — | `src/data/kb/rnb/piano.js`, `src/data/kb/index.js` | validator green + registered; renders in the piano tab; prose claims arithmetic-verified |
| P-31 | KB expansion: **blues piano** cell | content | claimed | P-30 | `src/data/kb/blues/piano.js`, `src/data/kb/index.js` | validator green + registered |
| C-31 | Sprint-end sweep: full build + validator + smoke + fixtures, then update PR #3 (push + PR body/comment summarising this sprint) per PROTOCOL §6 | quality | backlog | L-31, L-33, D-30 | (none — verification) | all green; PR #3 updated |
| C-31 | Sprint-end sweep: full build + validator + smoke + fixtures, then update PR #3 (push + PR body/comment summarising this sprint) per PROTOCOL §6 | quality | ready | L-31, L-33, D-30 | (none — verification) | all green; PR #3 updated |
> Sequencing: C-30 ‖ D-30 ‖ D-31 ‖ P-30 are file-disjoint and ready now. Then C-30 → L-30 → L-31 (serial chain on theory.js/App.jsx), and D-30+D-31 → L-33. P-31 fills spare iterations. Critic gates every task.
@@ -42,6 +42,10 @@ The shared queue all agents read and write. Lifecycle and rules: [`PROTOCOL.md`]
> GATE 2026-07-10 (Critic) · **L-30 PASS** (`4cc0009`) — smoke 817/817 (all 17 fixtures plain guards, 9 original greens no regression), validator + build green. Diff confined: theory.js 2 hunks in the repeating-progression section only, `canonicalize` unchanged context; loop-fixtures.mjs = marker removals + historical rewordings, every history/expect array untouched (frozen contract intact). 15 novel generalization probes: 11 correct, 3 data-faithful (only phase-locked exactly-alternating corruption yields a doubled pattern — genuinely 6-periodic data no algorithm could distinguish), 1 better-than-expected (all-reps-edited loop found via clean rotation). Every reportable "ghost" now corresponds to a pattern that exactly recurred — the old structurally-fake ghosts are gone. Perf 0.210.73 ms/call ×1000. Consumer contract at App.jsx:154-173 type-matches. 3 non-blocking findings folded into L-31's row.
> GATE 2026-07-10 (Critic) · **L-33 PASS** (`see commit`) — build green, smoke 817/817, validator green; diff exactly the 3-file lock (App.jsx/theory.js diffs attributed to L-31). SSR of the real JamGuide 37/37: expanded-column cell counts == independently derived shape counts (dom7@G=4, min7@D=4), aria-current one-per-list, mic microcopy exactly once (dense suppresses per-mount copies), pin semantics diffed line-by-line identical to old selectedStation (deps + emit/clear), GlanceRail imports no chordAudio + auto-follow has zero focus/audio side effects (scrollIntoView reduced-motion-guarded), heard-live + nothing-heard paths correct. Token matcher proven through the real render on a hostile country I-vs-I7 case (3 fits not 4) + full 23-lick chordContext audit — no false positive possible; exotic glyphs (♯/°/ø) outside the char class fail conservative (miss, never false-fit). `dense`-less VoicingBrowser SSR **byte-identical** to committed 0945a08. Zero-click audit: all variations + all licks in initial markup. Deviations accepted (staging cosmetic; heard-live licks strip musically right). Non-blocking: first-mount scroll on unknown playhead benign; LicksStrip perf fine unmemoized. Committed `c78baf4`.
> GATE 2026-07-10 (Critic) · **L-31 PASS** (`ce24d54`) — 🚨 audio contract CLEAN: 1 hunk in the progression useEffect, contract-grep zero hits, no ref-sync/mount props; theory.js ride-along comment-only (verified zero executable lines). Independent re-trace with own mirror + real detector: spurious-substitution commits #7 zero drops; section change replaces with zero intermediate nulls; breakdown first-null at foreign-commit 28 (comment's "~28" numerically exact) and clears at exactly 6 nulls; 2-rep flap survives with rival counter provably reset. HOSTILE-1 proved REPLACE_VOTES=3 load-bearing (rival hit 2 before agreement reset — 2 would displace-and-flap); alternating rivals never accumulate; newSong null-shape defensively handled. Build/smoke 817/817/validator green. 2/3/6 judged musically sensible; v-a commit-then-upgrade UX accepted over blank display. Non-blocking: "consecutive" comment nuance (nulls are neutral, not resetting — amend to "consecutive non-null" if ever touched); threshold consts re-created per render (trivially cheap, hoisting would exceed the lock); Luthier's +53/12 was arithmetic sloppiness for +47/6.
---
## Shipped sprint: `sprint-knowledge-center` (branch: `sprint-jamguide-piano` — complete 2026-07-09, PR #3)
@@ -188,6 +192,7 @@ _(Maestro appends one line per completed iteration: `<date> · <task ids done>
- 2026-07-09 · **iteration 8/24 — SPRINT `sprint-knowledge-center` COMPLETE** · done: C-21 (sprint-end sweep — build/validator/smoke all green on 72c6d45; full-App SSR renders; authored vs computed piano paths both proven; zero dead imports; audio contract +1 line since seed) · **PR #3 opened: https://github.com/whattheflat/JamBuddy/pull/3** (supersedes PR #2 — main hadn't absorbed it) · all 21 sprint tasks done, 4 returned-then-fixed by the gate, 0 unresolved · loop cron deleted after 8 of 24 budgeted iterations (board empty) · remaining backlog: EducationPanel retirement, FAMOUS_PROGRESSIONS level tags, smoke drift guards, pianoVoicing rootPc, negative-fret unify, L-12, bass renderer
- 2026-07-09 · **iterations 67/24** · done: L-25 (`e24aa4b` instrument-scoped modal tabs), C-22 (`b4e8f12` validator hand-span rule, smoke 799), P-23 (`564a9e0` gospel piano cell, 140 plays — returned once: one improv-row scale claim false for vi7/iii7, split into exact rows, PASS re-gate; 39/40 first-pass claims held), L-24 (`2165bb5` authored piano packs render at stations — implementer agent hung at verification after ~1 h, killed, completion-pass agent audited + finished; Critic PASS with 0 resolver drift) · incidents: P-23 stalled once mid-authoring (resumed from transcript, no loss); L-24 hung silently (diff intact, completed by fresh agent) · backlog: resolveDegree drift guard filed · **board empty except C-21 → sprint-end sweep + PR**
- 2026-07-08/09 · **iteration 5/24** · done: D-23 (`db397f6` VoicingBrowser show prop + LickCard stack-guard), D-24 (`e2110ae` MiniPiano thumbs crop to voicing span, 266→142 px), P-24 (11 licks rock/country/reggae — KB now **23 licks across 6 styles**, every note pitch-verified) — Critic PASS all three, zero returns · D-24 gate raised a false alarm on the D-21 rootPc fix (its harness bypassed VoicingBrowser; Maestro verified line 297 intact — no regression); hardening idea backlogged (`pianoVoicing` return rootPc) · promoted L-25 · next ready (all file-disjoint): L-24 ‖ L-25 ‖ C-22 ‖ P-23, then C-21 closes the sprint
- 2026-07-10 · **iteration 3/24** · done: L-33 (`c78baf4` **glance mode LIVE** — playhead accordion, licks strip, heard-live fallback; gate SSR 37/37, dense-less VoicingBrowser byte-identical to 0945a08, token matcher proven hostile-proof, App.jsx untouched by construction), L-31 (`ce24d54` commit layer 2/3/6 — gate re-traced all five scenarios independently + 3 hostile traces; REPLACE_VOTES=3 proven load-bearing; audio contract grep-clean) · **all three user asks now end-to-end on the branch** · P-31 (blues piano, 164 plays) authored — gate in flight; its verifier self-caught 3 prose overclaims pre-review · C-31 promoted (holds until P-31 lands so the sweep sees a settled tree) · next: gate P-31 → C-31 closes the sprint
- 2026-07-10 · **iteration 2/24** · done: P-30 (`b51daa1` rnb piano cell, KB 154 plays — PASS first try, a piano-pack first; found+fixed its own 36-key-window stacking defect pre-review), L-30 (`4cc0009` detector rewrite: dup-collapse, weak-period ghost rejection, len 28, ≤1 edit/cycle with ≥2-exact evidence gate, recency-weighted coverage — smoke 817/817, gate ran 15 novel probes, 0.20.7ms/call) · L-33 built (playhead accordion + LicksStrip + heard-live fallback, SSR 24/24 self-checked) — gate in flight · L-31 dispatched with both gates' findings folded (flap-survival constraint, docstring ride-along) · both watchdog-stalled agents recovered cleanly via resume · promoted: P-31 · next: gate L-33, land L-31, then C-31 closes
- 2026-07-10 · **iteration 1/24** · done: M-04, D-30 (`0945a08` VoicingBrowser gallery — all shapes/styles side by side, no chips; PASS first try), C-30 (`fdd93c7` 17 loop fixtures + smoke wiring; PASS — found the len² self-overlap artifact as the root cause of the user's missed 3-chord loops, folded into L-30/L-31 DoDs), D-31 (`6c7a1a7` glance-mode "playhead accordion" doc — returned once on piano-gallery width math, fixed, PASS re-gate) · in flight: L-30 (detector redesign, dispatched early — C-30 contract ready), P-30 (rnb piano) — both stalled once on the 600s API watchdog near completion, both resumed via SendMessage · promoted: L-33 (ready, locks per D-31 doc) · finding worth noting: "5 chords then 2 others" passes at pure-function level — the live failure is the ghost-pattern flapping starving the 2-vote commit layer (L-31's trace case)
- 2026-07-10 · **new sprint `sprint-glance-and-loop`** seeded on the SAME branch (commits extend PR #3) · user asks: all voicing variations side-by-side with no button pushing; fix loop detection (misses a returning 3-chord loop and a 5-chords-then-2-others shape); glanceable zero-click learn session that follows the live jam · loop scheduled: /jam-loop every 30 min × 24 iterations (12 h, cron 13,43) · ready now (file-disjoint): C-30 ‖ D-30 ‖ D-31 ‖ P-30, then C-30→L-30→L-31 and D-30+D-31→L-33