-
feat(orphan-orbits): name the ghosts before the stage does (#68) · 3ab9ae03
PLN, by ear, 2026-07-28: loaded vague_de_crime, played bombe_dj, and "heard diam's voice, now still hearing the synth from crimewave... i hear it regardless of gains, but filters work on them". THE MECHANISM, and why his two symptoms are the proof `dN $ ...` replaces orbit N and says NOTHING about the others, so every orbit the outgoing track declares and the incoming one does not just keeps running forever underneath the new track. "Regardless of gains" follows because the new track's gain lines address only ITS OWN orbits — nothing in it can reach the ghost. "But filters work on them" follows because gF3 is the GLOBAL CC51 DJ filter, applied INSIDE the ghost's own still-running pattern. An orbit that ignores the faders but answers the DJ filter is diagnostic of exactly this, and nothing else. Not a rig fault. It bites at every transition where the outgoing track declares an orbit the incoming one does not — which is 8 of the 12 OPAL transitions. WHAT SHIPPED armada/setlist_opal2026.txt — the set as DATA, in play order, resolved from backlog.md's codenames by locating each file rather than guessing ("Mafia" is mafia_sans_serif, "Le shifteur marteau" is electric_hammer, "Take five Drops" is take_5_drops). Reordering this file re-answers the ghost question, which is exactly what #12 needs. tools/orphan-orbits.py — reuses pvlint's existing orbit parser (DRY) and: * walks the set pairwise and names each transition's ghosts WITH THE SOUND they play, because "d6 (crimewave)" is actionable on stage and "d6" is not * --matrix, the full A->B grid, so #12 can order the set with the ghosts in view * --silence TRACK, a paste-ready `dN $ silence` preamble * --pair A B, exiting non-zero when ghosts exist so #44 can gate on it THE RESULT FOR THIS SET 12 transitions, 8 leave ghosts, 16 orphaned orbits. Worst: after REVOLUTION (4), after Gimme Acid (3). The original ear-report reproduces exactly — vague_de_crime -> bombe_dj leaves {6, 10}, and d6 IS the crimewave synth. And one ordering lever worth more than the report: Perfect <3 declares ALL TWELVE orbits, so its column in the matrix is entirely clean. It is a free RESET POINT — put it after the messiest stretch and ghosts stop propagating. The tool now detects and names reset points generally rather than leaving that to be noticed. WHY IT STOPS SHORT OF FIXING IT AUTOMATICALLY The obvious automation is to have tidal-remote eval a generated silence block. Read the plugin first: `eval-file` calls atom.workspace.open(..., activatePane: true) — it OPENS AND ACTIVATES the file, so it would yank the editor away from the track being played, mid-transition. That is worse than the ghost. Until the plugin gets a focus-free `code` command, the fix is `hush` (safe under pressure, costs the tail) or pasting the block at the top of a track — and that is a .tidal edit, which is PLN's call, not mine. `dN` IS `xfade N`, so `d6 $ silence` should FADE the ghost rather than cut it; that wants an ear before it is assumed. TESTS: 39 new, suite 306 -> 345, all green. The one that matters is the cross-validation: the parser's orbit set is asserted against the TEN sets hand-measured on 2026-07-28, before this parser existed. All ten agree, so the tool and the ear agree. Also pinned: a commented-out `-- d6` counts as neither declared nor overwriting (correct in both directions); the silence block never silences the track's own orbits (that shape is a mute-bomb and would be blamed on the rig); it uses `silence` and never `# gain 0` (which leaves the pattern scheduled and revivable by a later global gain); and d1-d5 never orphan anywhere in this set — so if a future track drops one, the ghost lands on the loudest possible orbit and the suite says so before the stage does.PLN (Algolia) authored3ab9ae03
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| test_gig_log.py | Loading commit data... | |
| test_orphan_orbits.py | Loading commit data... |