Commit 9d5d4257 by PLN (Algolia)

docs(tasks): archive the silent-orbit hunt — two evenings, one header-only buffer

Two entries, both written as documentary source rather than bookkeeping.

#63 is the epidemic itself: `~dirt.doNotReadYet = true` makes SuperDirt read WAV
HEADERS ONLY, so every bank registers with a correct file count and its buffers
hold no audio. The methodological lesson is worth more than the bug — every
measurement used a 4-8 second window, and at that timescale a TIME-VARYING
failure looks STATIC. "These two sample banks are dead" was overwhelming and
wrong, and six hypotheses got built on top of it. The decisive test was one
command: same pattern, t+3s healthy, t+26s gone.

Also recorded honestly: our own probe tool FABRICATED signal from contaminated
taps and contradicted PLN's ears for an hour. Five orbits at an identical +0.0
dBFS peak was the fingerprint nobody read. Kept in the archive on purpose — a
tool that invents evidence outranks the human in an argument it should always
lose, and that is worth remembering out loud.

#59 is the smaller, funnier one: "sound broke after a Window Reload, fixed by a
Tidal reboot" was never a breakage. Lazy activationHooks left the package
dormant, and `tidalcycles:reboot` was simply the first activationCommand that
woke it. The workaround worked for a reason unrelated to the story told about it,
which is exactly why nobody looked further for months.
parent 872676a2
...@@ -380,3 +380,15 @@ memory `project_fourier_api`. Named after Joseph Fourier — the transform behin ...@@ -380,3 +380,15 @@ memory `project_fourier_api`. Named after Joseph Fourier — the transform behin
- **Done:** deployed live 2026-06-29. (a) Generated `@nech/api` TS client from the OpenAPI snapshot (openapi-generator typescript-fetch → tsup ESM bundle; clean operationIds → `audio.analyzeEmotion()`; subpath exports). (b) Stood up **Verdaccio 6** on erable (loopback `:4873`, `~/srv/verdaccio/{storage,conf}`, `unless-stopped`) behind an LE-TLS nginx vhost **`npm.nech.pl`**; seeded publisher `pln` via the user API, locked signups (`max_users:-1`), creds 0600 at `~/.config/nechapi/verdaccio.pln.{pw,token}`. (c) Published `@nech/api@0.1.0` and install-verified as a consumer (AudioApi/Configuration import clean). (d) Retired `nech.ts` (`git rm`), updated README + onboarding.html to the `@nech/api` install path. Commits: client `ed77ee9`/regens, retire `851767f`; VERDACCIO.md marked DEPLOYED. - **Done:** deployed live 2026-06-29. (a) Generated `@nech/api` TS client from the OpenAPI snapshot (openapi-generator typescript-fetch → tsup ESM bundle; clean operationIds → `audio.analyzeEmotion()`; subpath exports). (b) Stood up **Verdaccio 6** on erable (loopback `:4873`, `~/srv/verdaccio/{storage,conf}`, `unless-stopped`) behind an LE-TLS nginx vhost **`npm.nech.pl`**; seeded publisher `pln` via the user API, locked signups (`max_users:-1`), creds 0600 at `~/.config/nechapi/verdaccio.pln.{pw,token}`. (c) Published `@nech/api@0.1.0` and install-verified as a consumer (AudioApi/Configuration import clean). (d) Retired `nech.ts` (`git rm`), updated README + onboarding.html to the `@nech/api` install path. Commits: client `ed77ee9`/regens, retire `851767f`; VERDACCIO.md marked DEPLOYED.
- **Learnings:** three Verdaccio gotchas the bare runbook missed — `listen: 0.0.0.0:4873` (else binds localhost INSIDE the container, dead `-p` map), `chown -R 10001:65533` the bind-mount (verdaccio uid), and `ssl_protocols TLSv1.2;` ONLY (erable's old OpenSSL rejects TLSv1.3 and fails `nginx -t`). Non-interactive publish: create the user via `PUT /-/user/org.couchdb.user:<name>` to get a token, then `npm publish --userconfig <temp .npmrc with _authToken>` — no interactive `npm adduser`/`login` needed. KEY DECISION: `@nech/*` reads are `$authenticated` (not public) — consistent with the bearer-gated `/openapi.json` (#48); so consumers need an npm READ token, a deliberate consistency call over install-convenience. - **Learnings:** three Verdaccio gotchas the bare runbook missed — `listen: 0.0.0.0:4873` (else binds localhost INSIDE the container, dead `-p` map), `chown -R 10001:65533` the bind-mount (verdaccio uid), and `ssl_protocols TLSv1.2;` ONLY (erable's old OpenSSL rejects TLSv1.3 and fails `nginx -t`). Non-interactive publish: create the user via `PUT /-/user/org.couchdb.user:<name>` to get a token, then `npm publish --userconfig <temp .npmrc with _authToken>` — no interactive `npm adduser`/`login` needed. KEY DECISION: `@nech/*` reads are `$authenticated` (not public) — consistent with the bearer-gated `/openapi.json` (#48); so consumers need an npm READ token, a deliberate consistency call over install-convenience.
- **Deps:** unblocked by the OpenAPI snapshot (#32); part of EPIC #21. Follow-ups (in `armada/api/TODO.md`): a `nech_api` Python client; mint hexa a read token. - **Deps:** unblocked by the OpenAPI snapshot (#32); part of EPIC #21. Follow-ups (in `armada/api/TODO.md`): a `nech_api` Python client; mint hexa a read token.
## #63 — The silent-orbit epidemic: `doNotReadYet` loads WAV headers only
- **Description:** for two evenings, orbits in `the_revolution_will_be_sampled` (d4/d5/d9-d12, varying per boot) made no sound. Events were visible in the Pulsar highlighter, no error appeared anywhere, and every static check — patterns, g* helpers, sample banks, libsndfile readability, orbit count, PipeWire links, Ardour routing, saved faders — pronounced the rig healthy while it was demonstrably not.
- **Done:** root cause identified 2026-07-28. SuperDirt `DirtSoundLibrary.sc:221` reads `Buffer.readWithInfo(server, path, onlyHeader: doNotReadYet)`. With `~dirt.doNotReadYet = true` (start_and_midi.scd:202) it reads **only the WAV header**: the buffer is allocated with a correct frame count and duration but contains NO AUDIO DATA. That is verbatim the `Buffer UGen: no buffer data` message. The deferred real read is what decides whether an orbit sounds, so which orbits die changes per boot, and a re-eval sometimes revives one by retriggering the read. Fix (eager-load the set's banks) spun out to #26 and deliberately NOT shipped at J-7 without index-integrity validation. Tooling shipped alongside: `872676a` (probe-chain contamination guard), `a43f428`+`d3de9bd` (remote control channel + CLI), `66af326` (eager package activation, which also closed #59).
- **Learnings:** THE METHODOLOGICAL ONE, worth more than the bug: every measurement used a 4-8 second window, and at that timescale a TIME-VARYING failure looks STATIC. "These two sample banks are dead" was overwhelmingly convincing and completely wrong; six hypotheses were built and demolished on top of it (banks, symlinks, 24-bit depth, filename characters, buffer exhaustion, xfade). The decisive observation took one command: play `arpy`, measure at t+3s (-37.0 dBFS rms, healthy) and again at t+26s (-inf, gone), no re-eval between. Patterns play, then die. Sampling ONE subject at TWO times would have found this in five minutes. Second lesson, more uncomfortable: probe-chain FABRICATED signal — contaminated capture taps reported five orbits at an identical +0.0 dBFS peak (twelve independent orbits don't do that; it was the mix measured five times), and that false table said d4/d5 had recovered while PLN's ears and Ardour's meters said otherwise. A measurement tool that invents signal outranks the human in an argument it should always lose; it now refuses to report unverified rows. Also: `find` does NOT follow symlinked directories without `-L`, which produced a confident "these files don't exist" about 69 files that do; and a bank name doesn't reveal its loader (`Dirt-Samples/kick` doesn't exist as a folder, yet `s "kick"` plays, because banks also come from `Samples/extra/*` and tidal-drum-machines).
- **Deps:** absorbed the `no buffer data` half of #45 (whose remaining 69 `zz._` AppleDouble warnings are harmless junk); handed the fix to #26, now the gig blocker; unblocked #59 as a side effect.
## #59 — "Sound broke after a Window Reload, fixed by a Tidal reboot"
- **Description:** a Pulsar `Window: Reload` reliably killed audio, and rebooting Tidal reliably restored it. Filed as a mysterious interaction between the reload and the audio stack.
- **Done:** fixed 2026-07-28 (`66af326`, pulsar-tidalcycles). Nothing was breaking. `activationHooks: ["source.tidalcycles:root-scope"]` plus `activationCommands` made Pulsar DEFER loading the package, so a reload landed in a window where the Tidal package was simply DORMANT — no ghci, none of its three UDP ports bound, and nothing saying so. `tidalcycles:reboot` happened to be the first *activationCommand* in the list, so "rebooting Tidal" worked by WAKING the package, not by fixing anything. Removed both keys; the package is now eager.
- **Learnings:** the remedy worked for a reason unrelated to the story we told about it, which is exactly why the cause stayed hidden for so long — a reliable workaround stops anyone asking why. Proof was structural rather than inferred: the renderer's `~/.pulsar/blob-store` contained no compiled tidalcycles code at all, so `lib/tidalcycles` had never been required (a good general check for "did this package actually load?"). Design consequence worth keeping: lazy activation and remote control are mutually exclusive on principle — a channel whose purpose is removing the manual keypress cannot itself require a keypress to come into existence. And shipping package JS always costs exactly one reload, because new code cannot be injected into a running Electron renderer.
- **Deps:** found while debugging why the new remote channel (#44/a43f428) wasn't listening; unblocks unattended launch work (#44).
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