Commit 583dc5a2 by PLN (Algolia)

docs(morning): Sunday brief — 15 tracks, 10 of them changed, and what to hear

J-6, the one-before-last KRK rehearsal. Per-track watch list for the 1h30 run,
because ten of the fifteen tracks have something in them PLN has never heard:
seven new d10 risers, the take_5_drops d5 structure fix, ouais_je_funk's d10
finally mutable, lime_tacos' cymbals relocated to d12, and two tracks that were
not in any tool's idea of the set until yesterday.

Also carries the fresh ghost matrix (9 of 14 transitions, 18 orphans) recomputed
on the real 15-track order — and the pleasant surprise that adding the two
missing tracks produced the longest clean stretch in the set,
piment -> ouais -> lime -> perfect.
parent 97fb85ed
# ☕ Morning, 2026-08-01 — Saturday
# ☕ Sunday 2026-08-02 — J-6, the one-before-last KRK rehearsal
Supersedes yesterday's file. Branch `master`, nothing pushed.
Supersedes Saturday's file. `master` clean, **everything pushed** (0 ahead / 0 behind).
`tools/gig-up.sh` = **GO**, 10/10 cold checks.
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.
**The KRKs go home after tomorrow.** Everything below that says "listen" is a thing only
you can settle, and this run plus one more is the whole remaining budget.
---
## Nothing needs your hands right now
## The set is 15 tracks now, not 13
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.
Your SSOT ruling got applied for the first time yesterday, and the backlog disagreed with
every tool in the repo. **`ouais_je_funk` and `lime_tacos` are in the set** and have never
been played in sequence. `you_my_sunshine` now comes **before** `mafia_sans_serif`.
The one thing worth doing when you sit down:
That drift had already cost you something audible: preload was warming 50 banks where the
set needs 53, so `dr`, `gfunk_bass` and `h2ogmcy` were lazy-loading off disk on first play.
That is the crackle you heard on the `take_5_drops` transition — the same bug, still live,
just smaller. **Now 54/54 warm.** If you hear crackle on a first play today, it is
something new and I want to know.
```
tools/gig-up.sh
```
That's new. It's the whole chain in one green/red, and it was **GO** when I
stopped.
`backlog.md` is now the only place you change the set. `gig-up --converge` regenerates the
list and the preload plan from it; a plain `gig-up` fails loudly if they have drifted.
---
## 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).
## 15 tracks × 90 min = 6:00 each (was 6:55)
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.
Worth feeling on this run specifically — the set got two tracks longer without getting
longer. If it runs over, the encore is the cheapest thing to cut.
**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.
## Per-track: what to listen for
### `docs/GIG-CHEATSHEET.md` — the surface card (#16, the 80/20)
**NEW** = added since your last run, never heard. Ten tracks have something new in them.
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`.
| # | track | bpm | what to listen for |
|---|---|---|---|
| 1 | bombe_dj | 124 | **NEW** riser on d10 |
| 2 | wap | 133 | **NEW** riser on d10 |
| 3 | do_it_right | 89 | the 133→89 drop — deliberate half-time, or does the arc sag? |
| 4 | take_5_drops | 124 | **d5 FIX.** `>\|``\|>`: the slice rhythm should now SURVIVE while ^57/^53 change pitch. Before, `slow 4` was replacing the rhythm with one event per 4 cycles. This is the "d5 steals structure" bug — TODO @PLN verify |
| 5 | piment_bresilien | 124 | d10 is Menace, not a riser (relocation deferred — see below) |
| 6 | **ouais_je_funk** | 120 | **NEW TO THE SET.** d10 SynMenace read `gF3 $ gF3`, so *nothing could mute it* — now `gF3 $ gM3`; check the mute actually drops it. 17 idle slots / 10 borrowed |
| 7 | **lime_tacos** | 110 | **NEW TO THE SET.** Cymbales sol moved **d6 → d12** — Tidal 12 is **+9.8 dB hotter** than Tidal 06, so ride the fader, don't re-gain the pattern. **NEW** riser d10. ^44 still linked to d3 on purpose. 23 idle slots, least integrated track in the set. Also the 110 BPM dip mid-block |
| 8 | perfect | 128 | all 12 orbits declared = your **free reset point**, anything can follow anything into it. No d10 riser possible |
| 9 | gimme_acid | 160 | no d10 riser possible (12 orbits). Leaves 3 ghosts behind |
| 10 | vague_de_crime | 120 | the reference riser. 160→120 is the second big drop |
| 11 | you_my_sunshine | 166 | **NEW** riser d10. Your `??TRANSITION???` seam is right before this |
| 12 | mafia_sans_serif | 160 | **NEW** riser d10. Your `?transition?` seam is right before this |
| 13 | desire | 129 | **NEW** riser d10, plus your own edit — lpf sweep out, room 0.4 / sz 0.5 / dry 1.1 in, crushbus 2.5→3.5 |
| 14 | the_revolution | — | no d10 riser possible (12 orbits) |
| 15 | electric_hammer | — | **NEW** riser d10 |
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.
### The 7 new risers are all the same thing
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:
Your designated safe idiom, copied verbatim from `vague_de_crime`:
```
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
```haskell
d10 $ gF1 $ gM3 $ mask "<t f!7>" $ "risers:8"
```
That's #77's problem list, per track, at a glance.
1-in-8, so it cannot run away; `gM3` mutes it, `gF1` filters it. **d10 = riser** is now
true in 10 of 15 tracks. The one thing to judge: 1-in-8 was tuned on a 120 BPM track — ask
whether it still reads at 160–166 (`you_my_sunshine`, `electric_hammer`).
---
## 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
## Ghosts: 9 of 14 transitions, 18 orphans
```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`:
The two new tracks actually *helped*`piment → ouais → lime → perfect` is four clean
transitions in a row, the longest clean stretch in the set.
```
Syntax error in sequence:
"<0.75 .. 0.8 0.8 .. 0.65>"
^
clean bombe_dj → wap
GHOST wap → do_it_right d7(wap), d9(acidOto3091, vec1_acid)
GHOST do_it_right → take_5_drops d6(daft)
GHOST take_5_drops → piment d11(take5), d12(take5)
clean piment → ouais_je_funk
clean ouais_je_funk → lime_tacos
clean lime_tacos → perfect
GHOST perfect → gimme_acid d6(meth_bass), d7(acidOto3092)
GHOST gimme_acid → vague_de_crime d9(molotov), d11(vocal_bordel), d12(molotov)
GHOST vague_de_crime → you_my_sunshine d7(crimewave) ← your ??TRANSITION???
GHOST you_my_sunshine→ mafia d6, d9, d11 (no_sunshine) ← your ?transition?
clean mafia → desire
GHOST desire → REVOLUTION d6(aeolian, superzow)
GHOST REVOLUTION → electric_hammer d7(FMRhodes1), d8(jungle_breaks), d12(like_sugar)
```
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".
Under pressure the answer is `hush` between the two. Both seams you marked with `??` are
ghosting seams — probably not a coincidence, and worth knowing before you fix the order.
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:
## What I want from your ears, ranked
**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`.
1. **take_5_drops d5** — did the fix restore the rhythm, or change the feel in a way you
dislike? It is the only change that alters an existing sound rather than adding one.
2. **lime_tacos cymbals at +9.8 dB** — fader ride, or does the pattern want re-gaining?
3. **The 7 risers** — right density at 160+?
4. **The two `??` seams** — sunshine before mafia is the truth now; does it play?
5. **Any crackle at all.** It should be gone.
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:
## Deferred by choice, your call to overrule
```
"[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 ..
```
**`piment_bresilien` d10 (Menace) and `ouais_je_funk` d10 (SynMenace) did NOT move.**
You asked me to consider it, and considering it turned up the cost: orbit N is
simultaneously the LCXL column, the Ardour track and the cut/crushbus group. Moving them
means two CC remaps (`^18``^17` / `^20`), a cut-group change, and both synths landing
**+8.2 dB louder** on hotter Ardour channels — on material you have not rehearsed since.
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.
And the decider: `perfect`, `gimme_acid` and `the_revolution` use all 12 orbits, so
**d10 = riser caps at 12/15 no matter what**. Paying that cost to go 10 → 12 seemed wrong
six days out. ~20 min if you want it.
---
## 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:
## Still open on my side
- **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**
- **#122** — does Tidal resume by itself after a watchdog recovery, or does it need a
ctrl+enter? Unverified. Until it is, treat watchdog recovery as *half* a recovery: if
the music does not come back on its own, ctrl+enter in Pulsar.
- **#110** — the full 1h30 safety recording. If this run is being recorded, it may already
be done.
Not ears-bound, so it keeps: #110 the safety recording (the tent, Wednesday),
#16's remaining logistics, #74 pv-at.
## Not gig-blocking, but you named it
**And still: 271 commits exist only on this laptop.** You fly Monday. Pushing is
the only off-machine copy of the gig state.
`python3 tools/set-coherence.py --suggest` already answers "what is this track missing" —
per orbit, with suggestions by role, including the d8 break stacks (`slice/chop`,
`loopAt + rev`). 153 idle slots across the set: `lead=51 perc=33 fx=33 bass=18 kick=12
breaks=6`. Your breaks are the *most* finished part of the set; the leads are where the
empty hands 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