Commit 8c3bea37 by PLN (Algolia)

docs(tasks): archive #93/#106/#107/#31 to the structured completed log

Four tasks closed 2026-07-29 evening: the silent-eval harness fix (and the real bug
it uncovered), the take-pack sidecar+archive tool, and the desire rhythm study.
Written for a cold reader per the archive's own convention — commit hashes are in
git log, this is the narrative and the numbers that don't show up in a diff.
parent 9ec69a35
...@@ -1037,3 +1037,119 @@ it). **59 knob substitutions across 13 tracks, 5 gSel FIXMEs, 0 collisions.** Co ...@@ -1037,3 +1037,119 @@ it). **59 knob substitutions across 13 tracks, 5 gSel FIXMEs, 0 collisions.** Co
ignore. Hence `--knobs`. ignore. Hence `--knobs`.
**Deps.** #46; blocks #94 (buttons, 166 refs, now unblocked by gMask's retirement). **Deps.** #46; blocks #94 (buttons, 166 refs, now unblocked by gMask's retirement).
---
## #93 — silent-eval harness cannot BUILD 3 of 13 setlist tracks
**Description.** Found while verifying the #92 column migration, 2026-07-29. Two of
the harness's own build failures (ambiguous `cutoff`, ambiguous chord-literal
`IsString`) had been sitting there, mislabeled as "harness limit, ignore this" — a
message that turned out to be actively dangerous.
**Done.** Two real harness bugs fixed by matching ghci's actual defaults instead of
diverging from them: hide every top-level name the generated module defines from the
`Context` import (in ghci a `let` shadows an import silently; at module top level
there is no shadowing, so the fix is to make hiding explicit and derive the hide-list
from the generated text so it can't drift); turn on `ExtendedDefaultRules` +
`NoMonomorphismRestriction`, both on by default in ghci. 12/13 tracks now build.
The verdict computation changed too: build errors whose GHC line number falls inside
the track's own generated lines now get a distinct `BROKEN` verdict — "THE TRACK DOES
NOT COMPILE — it will fail live too" — and count as a gig blocker; errors in the
harness scaffolding stay `BUILD FAILED — harness limit`. Line numbers are mapped back
to the real `.tidal` file by matching the offending line's text.
**Learnings.**
- **The distinction between "our fault" and "your fault" must be computed, never
asserted as a constant string.** The harness's own reassuring message was right
twice and catastrophically wrong the third time — it told the reader to ignore a
real, gig-blocking bug in `desire.tidal` (#108) using the exact same words it used
for its own limitations.
- **Two apparently-separate build failures had the same root cause**: the harness
environment diverging from how ghci actually evaluates the same code. Fixing the
divergence generically (match ghci's defaults) resolved both, rather than patching
each symptom (annotate this one literal, rename that one binding).
- **The 13th failure wasn't a harness bug at all.** Once the two real harness bugs
were fixed, the last one turned out to be a genuine typo committed in
`desire.tidal` — see #108.
**Deps.** Found via #92. Unblocks accurate pre-gig verification of the whole setlist
for the first time. Directly produced #108 (gig blocker found).
---
## #106 — Per-take sidecar: the MIDI performance must travel with the audio
## #107 — Take archive: wavpack compression
**Description.** PLN, 2026-07-29, recording OPAL practice: *"ensure recordings have
the midi too, keep this from blowing up tracking either ardour rec or compressing to
avoid storing hours of no-move?"*. Two asks, one command.
**Done.** `tools/take-lens.py pack <take> [--compress]`. Sidecars a take's MIDI
(every cc/note/track/mark record in the window, copied out of the gig log before its
prune timer deletes them), meta (window, per-orbit peaks, xrun delta, gear/boot
state), and EDL, next to the audio rather than in a directory nothing else protects.
`--compress` then `wavpack -h`s every source and verifies EACH with `wvunpack -vm`
before reporting bytes saved. Measured on take 94 (21 min, 12 orbits): **5.84 GB →
1.25 GB, all verified lossless.** Never deletes the `.wav` — that's a separate,
explicit, human step after the take has been heard.
**Learnings.**
- **`xrun` in gig-log's `s` records is a running total, not a per-tick delta** — the
same `CUMULATIVE` trap the log format documents in its own code, walked into again
by a new consumer. Summing it reported 58,668,469 xruns for a 21-minute take.
Rebased (last minus first): 230, a real and useful number.
- **Records != events.** A `cc` record is a one-second coalesced bucket carrying a
count `n`; reporting the record count instead of `sum(n)` understated the
performance ~25x.
- **FLAC was rejected outright, not benchmarked against.** It can't store 32-bit
float, and routing through s32 would hard-clip the 8 orbits sitting over 0 dBFS
while looking like a clean win on the one silent orbit. A format that can silently
destroy the loudest material is not a candidate, regardless of ratio.
- **Found in passing: the LED daemon was silently mute in its own journal.** Two
independent causes — Python block-buffers stdout to a pipe (always true under
systemd, fixed with `PYTHONUNBUFFERED=1`), and its own `-q` flag was suppressing
the one line that mattered (track changes) rather than the per-CC chatter it was
meant to quiet. `quiet` needs to mean "no spam," not "no signal."
**Deps.** Pairs together by design (one `pack` run does both). #106/#107 depend on
nothing; the trim-threshold fix ([[feedback_trim_threshold_ear_correction]] in
memory) landed the same evening on the same tool.
---
## #31 — desire.tidal bass rhythmics study
**Description.** PLN, 2026-07-29: *"i gotta solve desire bassline is not great
rythmics coulld be cooler more nto more ete_a_mauerpark or insouciance or
haunted_house i guess. letting it cool."* — pointing at his own prior tracks as the
target feel, then deliberately stepping back from the decision.
**Done.** `study/desire_bass_rhythm.tidal` — read all three referenced `.tidal`
files, named the current line's mechanism precisely (four equal `.`-groups, one
repeated note, density-only variation via `*<n>`, no rests, strictly on-grid — "a
metronome with a stutter"), extracted the six mechanisms the references share and
desire has none of (uneven durations via `@`, pitch=rhythm, eighth-note calage
displacement, accent following the rhythm's own weighting, rests, a phrase longer
than one bar). Wrote four alternatives, each isolating a different subset of
mechanisms so the reaction is attributable, verified via `silent-eval --seeded` to
compile and measurably differ (3.0/4.0/4.5/5.75 onsets per bar vs ~5.5 today). Pitch
design (D minor, measured corr=0.903) held constant throughout.
**Learnings.**
- **The densest option (D, 5.75/bar) is the control that matters most.** It's
*busier* than the current line and still reads as a riff — proving the original
complaint was never about note count, it was about where notes fall and how long
they last. Without that control, "add some space" would have felt like a guess
dressed as a diagnosis.
- **Different shape from the copycat/algoraoke workflow.** That one matches an
EXTERNAL track via web research and demucs. Here the references are the artist's
own prior work already in the repo — the method is read the actual source, name
the current mechanism precisely, extract the shared grammar, hand back isolated
options. See `feedback_self_reference_rhythm_study` in memory.
- **"Letting it cool" is an instruction, not a delay.** It means prepare options
without pushing a decision — the study never touches his dirty working copy.
**Deps.** Depends on nothing. Surfaced #108 as an unrelated finding (desire.tidal
doesn't currently compile at all — a one-character typo, not a rhythm issue).
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