Commit 1d3bb807 by PLN (Algolia)

docs(archive): the portable-rig trio — sample-pack, rig-doctor, clone-the-gig

Three tasks that turned 'can PLN play from another laptop' from a question into
a procedure, archived long-form because the learnings are the blog material.

The through-line worth reading later: every one of the three had a structural
flaw that only appeared when you asked where the tool would RUN. sample-pack was
designed as two bundles until PLN reframed it as one parameterized query over the
mapped list. rig-doctor was green at home and structurally incapable of naming
absence on a fresh box, because it resolved against the machine it ran on.
rig-install would have created an empty quark directory that the next run reads
as 'already installed'. None of the three was caught by a test; all three were
caught by asking what happens on a machine that has nothing.
parent 2d51973f
...@@ -2183,3 +2183,154 @@ it may be another session's notes, and an untracked file that is *tracked on mas ...@@ -2183,3 +2183,154 @@ it may be another session's notes, and an untracked file that is *tracked on mas
exactly what blocked a branch switch earlier the same session. exactly what blocked a branch switch earlier the same session.
**Deps.** Remaining items → #14 (needs PLN's eyes on the editor). **Deps.** Remaining items → #14 (needs PLN's eyes on the editor).
---
## #20 — sample-pack: CLI to share the banks for chosen tracks or sets
**Description.** PLN needed to hand a set's samples to another machine — his own
travel laptop, and two friends. Git cannot carry the corpus, so the transport is a
temporary file-transfer link, and the question "which banks does this set actually
need" had never been answered for anything but one gig's preload.
**Done.** `tools/sample-pack.py` (`fa7aef0`). Selectors `--tracks` / `--set NAME`
(`--set list` enumerates; sets come from `armada/setlist_*.txt` plus gig
`tracks.json`, with `{slug}-{year}` aliases because slugs collide across years) /
`--all` as the default. Dry-run by default, `--pack DEST`, `--manifest-only`,
`--json`. Built the bundle and verified it file-by-file against its own manifest:
**281 banks, 9385 files, 15,108,195,468 bytes, 0 mismatches**, then staged it to
`/mnt/freebox/PLN/parvagues-carryon` byte-identically (9387 files both sides,
21m53s over SMB at ~11 MB/s; the local NVMe pack took 20 seconds).
**Learnings.**
*The spec collapsed once PLN corrected the framing.* I had designed two bundles —
a small carry-on and a big friends' share. He reframed it as **one parameterized
thing**: pack the *mapped* Dirt-Samples list, filtered by a track selection,
default all. "its ok like the done samples, not the work-in-progress ones."
The mapped view IS the curated set, and that single rule also solved the problem
I thought needed a separate decision: the 36 GB `Fred/` pack dropped out for
free, because it was never mapped.
*The rights picture was the real obstacle to the friends' share, not the size.*
Measured: ~101 GB total, of which ~87% is commercial third-party material — the
repo's own `register_fred_rights.py` labels `Fred/` a "Fred again.. producer stem
pack (fan dropbox)"; `rhadamanthe/` is 14 GB of Vengeance/Splice; `90sArchive/`
33 GB of retail sample-CD titles. Stated once as fact; PLN decided: "Fred doesnt
fly, it was public download but its too heavy and unfiltered."
*Half the "sample corpus" is not sample audio*: 85 unextracted `.zip` = 35.94 GB,
470 JPEGs = 6.71 GB, 18 `.mov` = 5.71 GB. Playable audio is ~57 GB of ~101 GB.
True junk (`.asd`, AppleDouble, `.DS_Store`) is 12,504 files but only 80.6 MB —
free file-count hygiene, not a space win.
*Duplicate estimates need spot-checking before they're quoted.* Grouping by
(name, size) suggested 4.96 GB duplicated; hashing the 40 worst groups confirmed
only ~32% of those bytes. Realistic figure ~1.5–2 GB. The cheap signal was a
ceiling, not an answer.
*The subtle constraint is bank indexing.* `s "bank:N"` indexes files in the order
SuperDirt's `pathMatch("*")` glob returns, and that glob skips dotfiles — so an
AppleDouble sidecar may be omitted safely, but dropping one real file renumbers
every index after it and silently changes what a track plays. A bank travels
whole or not at all. Consequence: `rhadamanthe_divers` costs 4.58 GB — 30% of the
bundle — for **5 indices across 3 of 714 tracks**, and cannot be trimmed.
**Deps.** Unblocked #19 (the doctor consumes `--json`) and #21. Fed #29.
---
## #19 — rig-doctor: does THIS machine have what the rig needs
**Description.** The measurement everything else was built on: run on a fresh
Linux box, install nothing, and report what's missing with a pointer to the fix.
A friend can run it on a machine we never touch and paste the output back, which
turns "does this work elsewhere" from a guess into a list.
**Done.** `tools/rig-doctor.py` (`5837135`), 44 checks in six groups — toolchain,
samples, synths, devices, install surface, secrets. stdlib-only so it runs on a
box with nothing installed; read-only by construction; every path derived from
`Path(__file__)` / `Path.home()`. Then `06039c8` committed
`sample-manifest.json` (463 KB) and taught it to fall back to that.
**Learnings.**
*The headline finding, and it was structural.* The samples check resolved bank
names by walking the Dirt-Samples tree **of the box it ran on**. Green at home,
worthless away: on an empty machine it reports "0 banks resolve" and can never
say "281 missing". A self-referential measurement confirms presence but cannot
name absence. Fixed by committing a manifest generated on a machine that DID have
everything — so the useful ordering works: clone, run the doctor, get the exact
missing list, all *before* 15 GB of audio moves. See
`feedback_absence_needs_an_external_reference` in memory.
*Mutation-verify the absence path, not just the presence path.* Planting two
nonexistent banks proved the check FAILs, names them, sizes them, and flips the
verdict — and exposed a fix pointer that could not be followed ("see
`<manifest.json>/README.md`", a path that cannot exist). A fix you cannot follow
is not a fix.
*Report `unknown` rather than a confident wrong FAIL.* `/etc/sudoers.d` is
`750 root:root`, so a non-root run cannot `stat` inside it at all — Python's
`Path.exists()` silently swallows the PermissionError to `False`, which would
have produced a clean, confident, wrong answer.
*Diagnostics, not a lock.* Quark commits are reported for orientation because
PLN rejected pinning them (#27). "Known-good observed on PLN's laptop" is a
useful sentence; "restore this 2022 commit" would have been a fear encoded as a
finding.
*Green at home proves no false alarms, not coverage.* Its first real test is a
bare machine (#29), and that limit was stated rather than papered over.
**Deps.** Blocked by #20. Unblocked #21. Fed #29.
---
## #21 — Clone-the-gig: one procedure from bare laptop to performing
**Description.** The install half: a documented, idempotent path from a bare Linux
box to a rig that can play, runnable by PLN on a new laptop and by the friend who
bought his LCXL2 on a machine we never touch.
**Done.** `tools/rig-install.sh` + root-level `SETUP.md` (`2d51973`), plus a fix
to `tools/parvagues-rig.target`, which had drifted from its own generator — still
`Wants=` the now-manual `lcxl3-driver`, missing `midiviz`. Idempotency proved by
running it twice on a fully-provisioned box: both exit 0, output identical, every
line "already ok", and the final line is the doctor's own verdict rather than the
installer's claim of success.
**Learnings.**
*Not docker, by explicit decision.* Realtime scheduling, the PipeWire/JACK graph,
ALSA MIDI passthrough, a GPU and a Qt GUI all cost more to containerise than they
save on a machine you own. An idempotent converge script — the shape
`tools/rig_units.py` already had — was the right size.
*Never escalate silently.* Root steps are PRINTED with what each one buys
(`--print-root-steps` shows only those), because a script that quietly sudos is
one nobody can audit before a gig. `tools/install-protect.sh`'s own comment
explains why it copies rather than symlinks: a root unit whose `ExecStart` lives
under a user's home is a privilege-escalation hole.
*The gap nothing owned.* Two systemd units reference
`%h/.local/bin/tidal-ardour-autoroute.sh` and `%h/.local/bin/midi-autoconnect.sh`,
and NOTHING in the repo created those symlinks — they were hand-made once on one
laptop. Absent, both units restart forever. This was a top-5 fresh-box breakage
and is now an install step.
*An empty directory can be worse than a missing one.* An unconditional
`mkdir -p "$DIRT_SAMPLES"` would have created an empty quark root that the NEXT
run's presence check reads as "already installed" — silently skipping the stock
Dirt-Samples forever, on top of a carry-on bundle that deliberately excludes
them. Caught in review before shipping.
*Same name, different scripts.* `gig-up.sh` at the repo root launches the gig;
`tools/gig-up.sh` is an older GO/NO-GO gate. An easy and expensive mix-up.
*What is honestly NOT portable is written down in SETUP.md rather than hidden:*
the literal `/home/pln` paths in `start_and_midi.scd` and `sample_watch.scd`
(#28), which give any non-`pln` account a rig that boots cleanly with banks
silently missing. A stranger hitting that with no warning is the worst outcome.
**Deps.** Blocked by #19 + #20. Blocks #22 (blog post from the outcome) and #29.
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