Commit b9d83bcd by PLN (Algolia)

docs: the receipt for everything gig prep deliberately parked

Eleven items, each with the acceptance test it is waiting on and the reason it
was left rather than done. Ordered by what it costs to carry, not by effort.

The two with a real deadline are at the top: retiring tools/gig-up.sh, which is
only still present because nothing is deleted before its replacement has run for
real AND because it is the transcription check's reference; and folding
gig_gate's scaffolding into gig-preflight, which was refused this week for
buying tidiness rather than behaviour.

Written now rather than after the gig because the reasons are what rot. The list
of files is recoverable from git; 'we left this because a corpus rewrite with
Pulsar open destroyed a rehearsal edit once' is not.
parent 8171325c
# After Thursday: what the gig prep parked
**Status:** outline, written 2026-09-22. Nothing here is for before the gig.
Every item below was found and deliberately left. The rule that produced the
list: *nothing is deleted until the thing that replaces it has run for real*, and
*a gig week is not when you refactor the boot path*. So this is the receipt for
those decisions, with the acceptance test each one is waiting on.
Ordered by what it costs to leave, not by effort.
## 1. Retire the bash gate
`tools/gig-up.sh` (620 lines) is superseded by `tools/check-gig.py` and carries a
banner saying so. It is kept for two reasons, and **both expire on Thursday
night**: nothing is deleted before its replacement has run on a real launch, and
it is the reference for the transcription check
(`test_every_bash_gate_check_survived_the_port` reads ITS check names and
requires each to appear in the new probe table).
*Do:* `git rm tools/gig-up.sh`. The test skips itself when the file is gone —
deliberately, with a note that the probe table becomes the only source of truth
at that moment. Re-read that note before deleting; it is the last chance to
notice a check nobody ported.
*Acceptance:* suite green with the skip, `grep -rn 'tools/gig-up' ` clean apart
from dated snapshots (`MORNING.md`, `LAST_THIRD.md`, `TASKS_DUMP.md` are history
and stay wrong on purpose).
## 2. Fold the gate's scaffolding into gig-preflight
`gig_gate.py` holds the verdict vocabulary; `gig-preflight.py` still has its own
copy of `add()`, the OK/WARN/FAIL constants and the report renderer. The two
agree today — which is *why* the machine layer absorbed with no rewrite — and
that agreement is currently held by a test rather than by a shared import.
*Do:* have `gig-preflight.py` import `gig_gate`, delete its duplicate ~60 lines,
keep its standalone CLI contract (`rig-doctor.py`, `RUNBOOK.md` and its own
docstring all reference it directly).
*Acceptance:* `test_preflight_json_still_speaks_the_shared_record_shape` passes
unchanged, and `gig-preflight.py --json` output is byte-identical modulo live
values.
*Why not now:* it edits a file the boot path calls, to buy tidiness rather than
behaviour. That is exactly the trade a gig week should refuse.
## 3. The duplicate FIXME lines
90 files carry 114 duplicated `FIXME(#54/#94)` comment lines — the migrator
stacked a fresh note on every pass before it learned to dedupe. Cosmetic: the
tool is idempotent now, so the count is frozen.
*Do:* one pass removing exact-duplicate consecutive FIXME lines. **With Pulsar
closed** — a corpus rewrite with his editor open destroyed a rehearsal edit once
already, and separately had a save from a stale buffer silently undo a
migration.
*Acceptance:* `silent-eval --seeded` verdicts diffed per file against
`docs/2026-09-22-catalog-playability.tsv`: zero changes, the same way the four
migrations were proven.
## 4. The 36 PV011 bus-slot collisions
Outside the 17-track set, so they cannot affect Thursday. Inside it, zero.
*Do:* `pvlint --setlist` over the whole corpus, resolve per track. Expect real
musical decisions, not mechanical ones — two tracks wanting the same crush bus is
a choice about what they sound like together, which is why this was not
auto-fixed.
## 5. One BPM parser
`lcxl3-driver.parse_bpm` and `setlist_samples.declared_bpm` are the same regex
against the same `setcps (BPM/60/4)` form. The driver's copy is load-bearing
during a set (the tempo readout), which is why it was left alone with a comment
saying it collapses post-gig.
*Acceptance:* `test_one_tidal_parser.py`'s `KNOWN_DEBT` shrinks by one entry —
that list only shrinks, and paying an entry off is required to be recorded.
## 6. Enable Ardour OSC, and close the live-fader blind spot
`use-osc="0"` in `~/.config/ardour8/config`; port 3819 is already set. So **no
tool can read the LIVE faders** — `check-mix` reads the last SAVED session, which
is why the gate states that limit in those words every single run.
This is the root cause of a recurring class: the D-row faders are MIDI-learned to
CC 77-84, the saved file and the physical desk drift independently, and an orbit
at −inf was caught three sessions running with a different set of tracks each
time. With OSC on, `ardour faders` becomes a live question instead of an archival
one.
*Do:* enable OSC, teach `check-mix.py` to prefer the live read and fall back to
the session file, and keep the caveat text for the fallback path.
*Acceptance:* move a fader on the desk without saving; `check-mix` reports the
new value. That is the leg that breaks, so it is the leg to test.
*Risk:* OSC is a new listener on a box that performs. Enable it on a calm
evening and leave it on through a full rehearsal before trusting it at a venue.
## 7. `ete_a_mauerpark` d9
Its `mask` shares `^58` with d6's gate. Structural, not a rename: d9 has no
button slot in the authored grid, so the fix is gSel work, not a migration. Left
because the track plays correctly — the two controls simply move together.
*Acceptance:* `tools/button-column-audit.py` clean for that file, with d9's mask
on a slot no other orbit claims.
## 8. midiviz: the rest of the state wire
Steps 3–5 of `docs/2026-09-22-midiviz-state-wire.md`. Step 2 shipped: the driver
publishes `surface-state.json`, and midiviz draws the three family filters as
zones with the detent at 64.
- **Step 3 — the full 48-cell layer.** The publisher already sends all 32
analogue values; `_paint_state` filters to `family_filter` with a one-line
guard. Widening it needs dirty-cell repaint so the layer stays free at rest:
`seq` says whether anything moved, the value diff says which cells.
- **Step 4 — orbit activity from `eval-events.jsonl`.** Already being written,
one object per ctrl+enter, and the driver already reads it. Tailing it tells a
viewer which orbits are live in the loaded track, which answers the real stage
question: *I turned the knob and nothing happened — is the pattern silent, or
is the knob not wired?* Surface state answers the second half; this answers the
first.
- **Step 5 — only if still wanted:** beat-level activity needs an OSC feed from
SuperDirt. The only genuinely new component in any of this, and the only one
that touches the audio process. Weigh it against everything else on this page.
Also inherited from the theme work: **`--theme` is one-shot**, so a converge
brings `dark` back. Persist the choice rather than passing it.
## 9. The two failing tests
Both pre-existing, both real, neither mine:
- `test_one_tidal_parser::test_no_new_file_parses_tidal_itself` flags
`tools/fold-orbits.py:96,100`. Those regexes match **PipeWire node names**
(`node.name = "..."`), not Tidal syntax, so this is a false positive in the
ratchet. The escape hatch the ratchet itself documents is a `tidal-parse-ok`
comment on the line — *not* a `KNOWN_DEBT` entry, since that list only shrinks.
Read the ratchet's own note before deciding: a false positive it cannot see is
exactly how a real one would hide.
- `test_gearbox::test_label_falls_back_to_the_raw_key` — the dash fallback
changed in `6fb0f98` and the test was not updated. Decide which is right; the
test is the older statement of intent.
## 10. Two setlists called opal2026
`setlist_opal2026.txt` exists at the repo root (Sep 6) **and** in `armada/`
(Sep 17). The root copy is the one the launcher used to generate `preload.scd`
from on every launch, which is how Thursday's set came within one button-press of
being warmed against the wrong gig. It is now only a last-resort fallback.
*Do:* keep one. `armada/` is where setlists live (`setlist_thu24.txt` is there),
so the root copy goes — but check nothing else reads it first, and note that
deleting it makes the launcher's fallback branch unreachable, which is arguably
the point.
## 11. `preload.scd` is generated, gitignored, and mode 0600
Its own history is the argument for looking at it again: a generated,
gitignored, never-compared boot file *debuted as a crackle at the venue*. It is
now compared — `check-preload` runs in the gate and in the launcher's converge —
but nothing in the repo records what it contained on any given night.
*Consider:* logging the bank count and a hash into the gig-log session file at
boot. Cheap, and it turns "was it warm?" into a question with an answer after
the fact. Weigh it against the ethos: an artifact nobody compares against
reality is worse than none, and this one would be compared by exactly one
future question.
---
## Not on this list
**The 2h rehearsal, the crush-bus A/B, `sept1`'s controller and
`ete_a_mauerpark`'s d9 effects.** Those are gig work, they need his ears, and
they belong in `TODO_GIG.md` where they already are.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment