# ☕ Morning, 2026-08-01 — Saturday

Supersedes yesterday's file. Branch `master`, nothing pushed.

You said you'd check coherence this morning. That report is unchanged and
waiting: **`docs/2026-07-31-set-coherence.md`**. Everything below is new.

---

## Nothing needs your hands right now

No rig interaction overnight: no sound, no MIDI, no systemd, and **not one
`.tidal` in the setlist was written to**. Your Pulsar buffers are exactly where
you left them — Ctrl-S whenever you like, nothing of mine can be clobbered by it.

The one thing worth doing when you sit down:

```
tools/gig-up.sh
```

That's new. It's the whole chain in one green/red, and it was **GO** when I
stopped.

---

## What shipped

### `tools/gig-up.sh` — one command, one exit code (#44, done)

The keystone, off the board. It contains **no new checking logic at all** — it's
a running order over the checks you already have (check-boot, check-mix,
silent-eval, fix-mute-roles, pvlint, orphan-orbits) plus a decision about which
failures actually stop a gig.

Hard-fail: boot helpers, Ardour faders, setlist compiles, mute map, pvlint.
Advisory: transition ghosts (#77 is known-open — a gate that goes red for work
you've consciously deferred is a gate you start ignoring) and LCXL-present
(legitimately unplugged at a kitchen table; at the venue it means the set has no
hands).

Cold by default: makes no sound, sends no MIDI, writes no file, safe mid-set.
`--audio` adds the boot-every-track gate, and skips itself if the cold gate is
already red — booting 13 tracks to confirm what a typecheck just told you is ten
wasted minutes at a venue.

**It found two bugs on its first run**, both the same shape, and it's this rig's
signature failure — *a thing verified once, in a context that no longer holds*:

1. `check-boot.sh` and `check-tracks.sh` were **mode 644 — not executable**. The
   pre-gig audio gate has never once been runnable as `tools/check-tracks.sh`
   since it was written. It only ever ran when someone typed `zsh tools/…`.
2. `pvlint --setlist` is a *modifier*, not a mode — it still needs paths. Run
   bare it exits 2 on an argparse error, which from outside looks exactly like a
   lint failure.

### `docs/GIG-CHEATSHEET.md` — the surface card (#16, the 80/20)

Generated from `tools/lcxl_grid.py` + the setlist, not hand-written, so it can't
drift from the rig. Regenerate with `python3 tools/cheat-sheet.py --md`.

Emergency box first, deliberately: the moment you reach for this page is the
moment something is wrong, and a card that opens with a reference table makes you
read past your own panic. Then the gF/gM asymmetry, the CC grid, the set table.

One column on it is worth seeing even if you never print the card — **ghost
risk**, the orbits each track does *not* declare, i.e. the ones that keep playing
whatever the previous track left there:

```
 1  bombe_dj          6,10,11,12 unowned
 6  perfect           declares all 12 — the only track that cannot inherit a ghost
13  electric_hammer   6,7,8,10,12 unowned
```

That's #77's problem list, per track, at a glance.

---

## The one that changes a number you were given

**#112 said "14 corpus tracks do not compile." That number was wrong, and so was
the tool that produced it.** Three bugs in `silent-eval.py`:

**1. It called your own writing style a parse error.** You write much of the
corpus as

```haskell
d1
$ whenmod 128 129 (…)
$ s "<k k*2 <k*2 k> k>"
```

Pulsar wraps blocks in GHCi's `:{ … :}`, which suspends the layout rule, so that
column-0 `$` is a continuation and the track plays fine. The harness emits into a
real *module*, where a column-0 `$` opens a new top-level declaration — a hard
parse error. It then printed, in these words: *"THE TRACK DOES NOT COMPILE — it
will fail live too"*, about code that has never once failed live.

Zero of your 13 setlist tracks use that style. That is exactly why it survived:
the harness was green on everything it was ever pointed at.

**2. A crashed probe was reported as silence.** Any non-zero exit was labelled
SILENT and stderr was discarded — which is where the self-contradicting
`FAIL — 0 orbit(s) SILENT` came from. It now reports CRASH and keeps the error.
That paid for itself immediately, in `live/chill/dub.tidal`:

```
Syntax error in sequence:
  "<0.75 .. 0.8 0.8 .. 0.65>"
               ^
```

A real mini-notation bug, precisely located, that **would** fail live — the
scheduler queries every cycle. It had been hiding behind a message saying zero
orbits were silent.

**3. A latent false green.** Fixing (2) exposed that the exit code was keyed to
the silence count alone, so a corpus where *every* track failed to compile would
have printed "OK — every declared orbit emits events" and exited 0. The exit code
now answers "is anything wrong".

Seven regression tests, mutation-checked — each fix reverted individually to
prove the test actually fails without it. Full suite **229 passed**. The setlist
stayed **13/13 green** throughout; none of this touched the gig path.

### The clean re-run landed. The real number is:

**51 of your 694 `live/` tracks don't compile, and 21 more throw when queried.**
Zero in the setlist. Full triage: `docs/2026-07-31-corpus-compile-failures.md`.

Three figures have now been attached to this question and the first two were
about the tool, not the music: #112's original 14, then a pre-fix 128 (~49 of
them the harness artifact above), now 79+30 across all 799 files. But 799 is the
wrong denominator too — 59 of those files are `study/`, i.e. Tidal documentation
with inline examples that was never meant to compile as a track. Counting it
inflates the figure the same way the bug did, just more quietly.

The **CRASH** class is new and it's the one worth your time. These compile, then
throw — invalid mini-notation *inside a string*, which is exactly why the type
checker let them through:

```
"[d d] <d d d*2 d*4>]"        unbalanced bracket
"~ ulgab?:1"                  ? before :
"[0 .. 7 0]"                  a range with a trailing element
"<0.75 .. 0.8 0.8 .. 0.65>"   a sequence on the left of ..
```

I didn't fix any of them. They're not in the set, and each needs a call about
what you meant — `"[0 .. 7 0]"` has at least two readings and only you know
which. Triage is the deliverable; the edits are yours.

---

## Still yours, and the clock on it

The KRKs stay home. **Sunday afternoon is when "can I judge this at volume"
expires** — not Saturday the 8th. Anything needing your ears on speakers wants to
happen in the next ~30 hours:

- **the coherence report** — 108 idle slots, three systematic patterns, and the
  note that your two named wants (bass `octersub`, lead `slice`) sit *outside*
  your own measured idiom rather than correcting drift in it
- **#33 risers**, **#13 transitions**, **#12 the running order**

Not ears-bound, so it keeps: #110 the safety recording (the tent, Wednesday),
#16's remaining logistics, #74 pv-at.

**And still: 271 commits exist only on this laptop.** You fly Monday. Pushing is
the only off-machine copy of the gig state.
