Commit e4e421be by PLN (Algolia)

docs(gig): the tooling pass, and the five bugs the split was hiding

parent 4d8e3e2a
......@@ -263,6 +263,48 @@ than git-modified files. Five of them (rose_rouge, sunny_side_up, quand_on_decol
something_about_drums, bombe_dj) were outside the overnight sweep and are being validated.
Catalog for reference: 703 `.tidal` files under `live/`.
## Tooling pass — one launcher, one gate (Tue 22 night, DONE)
`cd9d0d8` `7c0d40e` `4d8e3e2`. Two verbs: **`gig-up.sh` DOES, `tools/check-gig.py`
PROVES.** The gate is 23 probes as a TABLE (command, fix, severity, layer, preconditions)
plus the machine layer absorbed through `gig-preflight --json` — 39 checks, one report, one
exit code. The launcher now ENDS by calling it, so the path PLN presses and the path the
Bridge presses run the same gate. `tools/gig-up.sh` keeps a superseded banner and stays
unrun until after the gig (nothing is deleted before its replacement has run for real).
Measured: **16.5s full, 3.4s `--fast`** (what the launcher uses), 0.3s machine layer.
39 tests in `tools/tests/test_check_gig.py`; suites 510 passed, 2 failed (both pre-existing).
**Five bugs it surfaced, each verified against the failing leg, not the passing one:**
1. 🔴 **preload was being rewritten from the OPAL set on every launch.** Default was
`setlist_opal2026.txt` (Sept 6). Measured **132 banks → 45**, leaving **41 of Thursday's
banks to be read off disk mid-set**. The set is now named once at the top of the launcher
and read by both the plan generator and the gate; generation converges instead of
clobbering, so the deliberate 132-bank union is left alone.
2. 🔴 **the launcher span raw `sclang`, not `parvagues-sc.service`** — so it had no
journal, no rlimits, no supervision and no OOM protection (the 2026-08-15 death). Only
the OTHER gig-up started the unit, so unifying the two is what exposed it.
3. **`LCXL present` said the desk was plugged in while it was not** — it grepped
`aseqdump -l`'s PORT column, where `lcxl3-driver` publishes a virtual output named
"ParVagues LCXL3". The gate was matching our own driver. Now anchored on the client name.
4. **`setlist compiles` proved backlog.md's 15 tracks, not the 17 being played.**
`--setlist armada/setlist_thu24.txt` scopes the compile + preload probes to this gig.
5. **`SC -> Ardour` would have printed NO-GO on every `--headphones` launch** (gated on
scsynth, but its real precondition is Ardour). Preconditions are per-probe; an unmet one
is **SKIP**, never FAIL. Also: `gig-preflight`'s "mk3 LEDs unimplemented" warning has
been untrue since `lcxl3-driver` took over painting, and `gig-log preflight` — the
armed-global check, the one that found gMask at 127 for 74 minutes — could not block
anything because it lived only in the launcher's report. It is a blocking probe now.
- [ ] **YOURS, once, tonight: press the launcher from the desktop icon.** Everything above
is proven by running the gate directly; the launcher's new blocks have never executed.
**Window closes silently = GO. Window stays open = read the NO-GO block, it carries the
fix for each line.** Two probes could false-NO-GO on a genuinely cold boot and did not
today: `gig-log recording` (asserts a session file written in the last 20s, right after
the unit starts) and `audio graph` (blocking, and it runs on the `--headphones` path for
the first time). If either fires on the first launch, suspect the probe's assumption
before the rig.
## Learnings (Sun 21 night)
- LCXL3 protocol has no LED/OLED readback — ghost file (`/tmp/lcxl3-oled-ghost.txt`) is the
......
......@@ -2,7 +2,7 @@
{
"date": "2026-09-17",
"task": "GUI launcher did not spawn the MIDI lens or the tray",
"learning": "The launcher (gig-up.sh) and the unit converger (rig_units.py --ensure) disagreed on SuperDirt topology \u2014 raw sclang vs parvagues-sc.service \u2014 so the launcher never called ensure; the fix is ensure()'s proof-process skip, not another hand-copied unit list."
"learning": "The launcher (gig-up.sh) and the unit converger (rig_units.py --ensure) disagreed on SuperDirt topology — raw sclang vs parvagues-sc.service — so the launcher never called ensure; the fix is ensure()'s proof-process skip, not another hand-copied unit list."
},
{
"date": "2026-09-17",
......@@ -12,12 +12,15 @@
{
"date": "2026-09-18",
"task": "tray GIG UP did nothing + midimon silent",
"learning": "The Bridge ran 'gig-up.sh --converge --quiet' but gig-up.sh's arg guard only knew --headphones/--help, so every tray GIG UP died on flag 1 (exit 2, output captured). Flags now parsed: --converge boots SuperDirt + converges units with NO app windows, --quiet mutes ok/info. midimon watches 132:0 (the lcxl3-driver's translated virtual port), not the raw surface \u2014 silence there just means the driver had no input yet."
"learning": "The Bridge ran 'gig-up.sh --converge --quiet' but gig-up.sh's arg guard only knew --headphones/--help, so every tray GIG UP died on flag 1 (exit 2, output captured). Flags now parsed: --converge boots SuperDirt + converges units with NO app windows, --quiet mutes ok/info. midimon watches 132:0 (the lcxl3-driver's translated virtual port), not the raw surface — silence there just means the driver had no input yet."
},
{
"learning": "Two gig-up.sh exist: root (1-click, owns leds()) and tools/ (the GO/NO-GO gate the Bridge calls, where lcxl3-driver is boot=manual so nobody starts it). The v3 LCXL3 enumerates as 'LCXL3 1', breaking every v2 'Launch Control XL' grep \u2014 present/LEDs/path checks all silently misread. lcxl-path must match the driver's virtual PORT name 'ParVagues LCXL3' (under RtMidiOut client), never chase the PipeWire relay mesh (everything reaches everything via 143)."
"learning": "Two gig-up.sh exist: root (1-click, owns leds()) and tools/ (the GO/NO-GO gate the Bridge calls, where lcxl3-driver is boot=manual so nobody starts it). The v3 LCXL3 enumerates as 'LCXL3 1', breaking every v2 'Launch Control XL' grep — present/LEDs/path checks all silently misread. lcxl-path must match the driver's virtual PORT name 'ParVagues LCXL3' (under RtMidiOut client), never chase the PipeWire relay mesh (everything reaches everything via 143)."
},
{
"learning": "WirePlumber 0.4.17 ignores wireplumber.conf.d SPA-JSON rules (0.5 syntax) \u2014 this box reads Lua from main.lua.d only, and a partial alsa_monitor.rules reassignment clobbers the built-in table by index (dropped the card to profile off). Every wireplumber restart tears down Ardour's JACK client; recovery needed a full Ardour relaunch. pactl/wireplumber restart restored the missing HiFi profile after a UCM probe failure (card showed only off/pro-audio)."
"learning": "WirePlumber 0.4.17 ignores wireplumber.conf.d SPA-JSON rules (0.5 syntax) — this box reads Lua from main.lua.d only, and a partial alsa_monitor.rules reassignment clobbers the built-in table by index (dropped the card to profile off). Every wireplumber restart tears down Ardour's JACK client; recovery needed a full Ardour relaunch. pactl/wireplumber restart restored the missing HiFi profile after a UCM probe failure (card showed only off/pro-audio)."
},
{
"learning": "A generated boot file is only as good as the list it is generated FROM. gig-up.sh rewrote preload.scd on every launch from a default naming the PREVIOUS gig (setlist_opal2026.txt): measured 132 banks -> 45, leaving 41 of Thursday's banks to be read off disk mid-set — the exact 'crackle at the venue' failure the check was built for, re-armed by a stale default. Two structural lessons. (1) Name the set ONCE and have every consumer read that; the plan generator and the gate disagreeing about 'the set' is the whole bug. (2) An unconditional write is destructive in the quiet direction: the plan in place was a deliberate 132-bank UNION and regeneration could only narrow it, so gen_preload now asks check-preload first and leaves a covering plan alone. Corollary from the same pass: merging two tools that share a name means diffing what they DO, not just what they check — the root launcher span raw sclang while the other started parvagues-sc.service, so repointing the Bridge at 'one launcher' would have silently taken it off systemd (losing rlimits, the journal, supervision and OOM protection)."
}
]
\ No newline at end of file
]
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