# OPAL 2026 — completed-task archive

Long-term learning + blog/video source material for the gig-prep thread. Each entry is a
finished board task captured in full (description · done · learnings · deps), appended by the
`/pre-compact` ritual before the task is cleared off the active board.

Deliberately **separate from `armada/tasks/completed-archive.md`**, which is scoped to
L'Armada (the media/marketing toolbox). Same discipline, different thread. Newest first.

---

## #15 — Mid-set recovery runbook ("when it breaks")
- **Description:** PLN needed a playbook for the gig going wrong on stage, where the failure
  mode is panic as much as it is technical.
- **Done:** `RUNBOOK.md` at repo root (commit `9bdf395`). Symptom-first structure, ordered
  cheapest-first, with an explicit rule zero that a SuperCollider reboot is the *last* resort.
- **Learnings:**
  - Structure it **symptom-first, not cause-first** — mid-set you don't know the cause, you
    know the sound stopped. §0 is a 10-second triage that routes to a section.
  - **A frozen Pulsar does not stop the audio.** Patterns live in the ghci process, not the
    renderer, so `Window: Reload` is a cheap fix that keeps the music playing. This inverts
    the instinct to panic-kill the editor.
  - Documented §2b, the **zombie port 6010** failure (see #21 learnings) — the nastiest kind,
    because it is completely silent.
  - **Fader 77 is global gain.** Down = everything silent, nothing looks broken. Now in the
    pre-set checklist because it's a one-move fix that's easy to overlook.
  - Every procedure is **labelled by evidence strength** — verified-by-running vs.
    read-from-source vs. inherited-from-prior-incident. A runbook you've never executed is a
    hypothesis and should admit it.
- **Deps:** feeds #14 (rehearsal must actually *execute* the runbook, especially §5).

## #21 — The gF/djfbus mute-bomb
- **Description:** `gF1/2/3` sent values into `djfbus`, a **non-registered** SuperDirt effect.
  LCXL faders rest at 0, so any gF-wrapped stream muted with no recovery — and essentially
  every mature ParVagues track wraps its streams in gF. Armed across the whole set.
- **Done:** Safe-at-rest rewrite using core `hpf`/`lpf` mapped so fader-rest == bypass
  (`gHPF = range 20 8000`, `gLPF = range 20000 180`, `gF3 = id`). Shipped first as a
  shadow-eval in `live/lib/prelude.tidal` (`29ce103`), live-confirmed by PLN ("f123 djfs seem
  to work great overall"), then **baked permanently into `BootTidal.hs`** (`98d073f`).
- **Learnings:**
  - **A fix that lives only in a running process is not a fix.** It was correct and validated
    for a full day while still being one SuperCollider reboot away from silently rearming.
    "Live-confirmed" and "durable" are different states; the gap between them is where this
    kind of bug hides.
  - Design controls so **rest position == no effect**. The bug wasn't really the missing bus,
    it was that the *default* state of the hardware was an *extreme* value. `gF3 = id` is the
    strongest form of this — a spare fader that cannot touch sound at all.
  - Discovered while type-checking: a stale `ghc` holding port **6010** makes a fresh Tidal
    print "Can't handshake with SuperCollider" and then behave **completely normally in
    Pulsar** while nothing plays and no error surfaces. Detect with `ss -lunp | grep 6010`.
  - `prelude.tidal` was demoted from accidental-source-of-truth to explicit **rescue sheet**,
    with the stale-boot tell written down (push fader 49 → mutes; pulling to 0 makes it
    *worse*, because 0 is the mute position on the old defs and bypass on the new).
- **Deps:** unblocked the same bake-in for #13; feeds #15's §1a and #18.

## #32 — Always-on lean gig recorder
- **Description:** Capture every performance without depending on Ardour, and slice test
  samples for the Slop visuals work.
- **Done:** `tools/gig_record.sh` (`29ce103`) — PipeWire → rotating hourly opus segments in
  `recordings/`, with `start`/`stop`/`status`/`slice` subcommands. Verified running
  continuously across this session (pid 3686091).
- **Learnings:** deliberately a **separate process from Ardour** — if Ardour dies you still
  have the set. A freshly-rotated segment reading 0 bytes is normal and should not read as
  failure; `status` had to be taught to say so.
- **Deps:** spawned #37 (GUI toggle, HUD REC indicator, silence-trim, per-track metadata).

## #19 — Free 100GB+ before the gig
- **Description:** Disk was at ~28GB free with a deadline of ~Aug 1; Ardour stem recordings
  were the bulk.
- **Done:** Freebox mount repaired, 436GB of **verified-identical** stem media archived and
  deleted → **188GB free**.
- **Learnings:** `du`-summed bytes deleted (436GB) vs `df`-reported bytes freed (160GB)
  disagreed sharply. Cause is btrfs `compress=zstd` plus reflink/CoW sharing — benign
  filesystem semantics, not partial deletion. **`df` is the authoritative number**; don't
  chase the gap. Verify identity *before* deleting, always.
- **Deps:** unblocked all recording-heavy work (#32, rehearsals).

## #9 — 1-click ordered gig launcher
- **Description:** At every gig start, whichever of SuperDirt or Ardour opened the
  LaunchControl XL first won it. When Ardour won, sclang couldn't get the controller and PLN
  was stuck doing a disconnect/reconnect MIDI dance during setup.
- **Done:** `gig-up.sh` (`ba8e84a`, hardened by `e304355`, `0c65fda`, `2bc6a8e`, `c35c902`) —
  brings SuperDirt up **first**, waits on a real readiness gate (scsynth alive + `:57120`
  listening + a SuperCollider MIDI client present), and only then launches Ardour and Pulsar.
- **Learnings:**
  - **Order beats retry.** The MIDI dance was a symptom of a race; gating on readiness
    removed the race instead of automating the workaround.
  - Gate on **observable readiness**, not `sleep`. Three independent checks, because any one
    of them alone can be true while the rig is still unusable.
  - Made **idempotent** — it converges the rig rather than spawning duplicates, so it's safe
    to run when you're unsure of the current state. That's exactly the property you want from
    something you'd run while panicking (see #15 §5).
  - `set -u` bit hard: `open_term` read an unused `$1` and crashed the launcher on start
    (`e304355`).
- **Deps:** feeds #15 §5, #18; prerequisite for #14.

## #27 — Editor highlight horizontal jitter
- **Description:** Eval highlights visibly shifted text horizontally when toggling.
- **Done:** `border` → `outline` across `.event-highlight` and all 17 per-stream `-dN` rules.
- **Learnings:** **`border` participates in layout and reflows text; `outline` does not.** For
  any decoration that toggles at performance rates, outline is the correct primitive. (The
  *residual* wiggle after this fix turned out to have a separate cause — see #35, a competing
  runtime style injection toggling 30×/sec.)
- **Deps:** partially overlaps #35; both feed #6.

## #5 — Version-control the pulsar-parvagues-hud package
- **Description:** The HUD package was live-edited with no git history.
- **Done:** Package brought under version control with its own repo/branch.
- **Learnings:** the HUD, `pulsar-tidalcycles`, and `~/.pulsar/styles.less` are **three
  separate version-control domains** (the last untracked entirely, as user config). A single
  visual bug can require coordinated edits across all three — which is exactly what #35 hit.
  Knowing the domain boundaries is a prerequisite for debugging anything editor-side.
- **Deps:** prerequisite for #6, #7, #22, #35, #36.
