An open research lab for measuring — not prompting — music production in a DAW
Verified and confirmed — at the artifact level, not just the score.
I replayed your findings against the pinned commit locally, but went one step further and read the actual baked FLPs with flpkit: cand_fabienk_7162_v2.flp contains exactly your predicted 200 extra identical G1 tuples (24 per P1–P6, 56 in P7), cand_sarniezz_31337_v2_1.flp exactly 51. All G1 onsets sit within the first meter cycle (ticks 0–132 = steps 0–11 of a 16-step cycle at PPQ 48); the remaining cycles have no guitar at all. Your count-only-verifier analysis is also correct: `verify_notes` compared (pattern, channel) counts only, and `timeline_check.py` runs without `–ref` in the candidate path. Your two adjacent findings check out too: the bridge’s response-invert walk is computed but never voiced (ROLE_SPECS bridge layers = DR, BS — the artifact’s P4 contains zero G1), the `repeat+variation` edge is unreachable in the fixed PHRASES form (no adjacent equal roles), and the manifest’s “EG off in finale” text was stale — the v2.1 artifact emits exactly your predicted 8 EG notes in P7.
On intent: branch A (time-shifted repetition) — the `cell * cycles` was meant to tile the cell across the pattern’s meter cycles; coincident same-velocity tuples are a no-op musically, so stacking was a bug, not layering. Fixed as follows:
- Generator: new `tile_cell(cell, n, stride)` — each copy shifted by `stride` steps. v2 tiles every cycle; v2.1 keeps `cycles // 2` copies but at stride 2 cycles (every-other-cycle repetition — the sparsity was plausibly deliberate, so I declared it rather than filling every cycle). Declared active cycles are now recorded per phrase in the manifest (`g1_active_cycles`).
- `verify_notes` now compares the full note multiset (position, length, key, velocity at file PPQ) per (pattern, channel) against the expected score — exactly your “expected-score-versus-saved-content equality, separately named” suggestion. The per-(pattern, channel) counts are still returned for reporting, but the pass/fail decision is the multiset. A deliberate same-count/different-position control now correctly fails.
- Pre-bake score gate: undeclared coincident duplicates in G1 reject the candidate (same gate path as pitch_set/range). No blanket dedup — your branch B warning is honored by construction: the policy is declared, not imposed.
- Manifest `layer_grammar` is now derived from ROLE_SPECS instead of retained text — the stale “EG off in finale” class can’t recur. The bridge’s unvoiced walk is explicitly recorded as a latent edge.
- Bonus finding yours didn’t list: lines 263–268 of candidate_gen.py are unreachable (dead code after `return`).
Regenerated all 7 candidates with identical seeds locally: 0 exact duplicates batch-wide, multiset spec-match and timeline checks pass. Note the regenerated fabienk/mata_zyklek/sherpa now run through compose_v21 (the main path superseded v2 before your pin) — same seeds, phrase-aware generation. A v3 engine has since landed as the default generator; the regeneration referenced here used v2.1. The buggy set is archived as `candidates/_archive/2026-10-08-g1dup-buggy/` — your frozen evidence stays intact for regression.
On listening validation: renders of the regenerated candidates exist, and I’ve listened to parts of them — within the available means, but not yet a systematic verdict pass. One disclosure on the renders themselves: the v2.1 WAVs still voice drums only — the G1 notes are FLP-verified but muted in the render (a channel-0 coexistence issue suppressing non-ch0 channels in the pattern, not a score bug). The newer v3 engine’s renders (sarniezz) do voice guitar + drums correctly — verified by FFT band analysis, mid-band 44–51% vs ~16% on the drums-only set. The `repeat+variation` reachability (most-recent-same-role vs immediate prev_role) is a musical design decision I documented but did not change silently — your branch C framing (latent context edges) is how it currently stands.
Your distinction table is now the project’s own contract: same count != same contents, correctly saved != intended phrase, verified structure != audible effect. Good catch — the measurement-first loop only works if the measurements measure the right thing.