ADR-0058: WavAmpster is a first-party program; its bin and capability id are knamp
this ADR extends), ADR-0015 (CIPHER owns the OLED, so
WavAmpster does not draw there), ADR-0017 (the deck’s
audio chain), knamp-stations.md (the station
package format), 2026-06-24-knamp-design.md (deleted 2026-07-29; recover from git history) (the approved
brief)
Context
Section titled “Context”WavAmpster is the deck’s music player: a build-time tool packages a folder of MP3s or WAVs into a
station (rendered PCM plus a station.knst manifest), and on the deck the operator browses
stations, tunes one, and it keeps playing in the background while they use the rest of the machine.
It shipped across four PRs in June 2026 (GWP-599, GWP-678, GWP-679) and has been running in the
emulator since.
ADR-0042 closed the first-party program roster at thirteen and set the rule that adding a program
takes a successor ADR: “Stub programs are acceptable at launch; unchartered programs are not.”
WavAmpster has been a routable program in screen_router.c with no ADR behind it. The brief that
approved the build predicted this gap and listed a charter as the follow-on. This ADR closes it.
The naming also needed a decision. The program was renamed to knAmp in June to fit the deck’s kn-prefixed family, and the implementation branches (cut before that rename, merged after it) put the old name back everywhere. Two names have been live in the tree since.
Decision
Section titled “Decision”WavAmpster joins the ADR-0042 roster as the fourteenth first-party program, under the same rules as the other thirteen. Its operator-facing name is WavAmpster; every identifier is knamp.
-
WavAmpster is program #14 on the ADR-0042 roster. It is a first-party program: it ships in the system image, is always present regardless of what cart is in the slot, has no Capability Registry presence, no
cartridge_historyentry, and is never superseded by a cart. A cart may ship stations; it never gates access to the player. -
The name splits by audience. “WavAmpster” is what the operator sees: the headline, the status-bar title, prose in docs.
knampis what anything typed or referenced uses: the packaging binary, the Rust crate, thelaunch-appprogram id, the screen-router entry, the Lisp namespace (knamp/…,knamp-mode),runtime/programs/knamp/, and the doc filenames. -
The player engine stays in C; the screen stays in Lisp.
station.cowns discovery, transport, and the PCM mix because the Fe tick fires only for the active screen and background audio has to outlive the mode.runtime/programs/knamp/knamp.lspis a control and view surface over thestation-*FFI. This split is the reason background playback works, and it is the only part of the program that is not Lisp. -
All decode happens at build time. The
knamptool decodes MP3 and WAV on a workstation and emits S16LE / 44.1 kHz / mono PCM. The deck has no decoder and streams the rendered PCM only. -
Stations install into the
/opt/noshcontract at/opt/nosh/share/assets/stations, which the host probes first. Operator music gets there with thestationsAnsible role (converge/stations.yml), which packages on the control node and pushes the PCM. -
The scope stays where the brief locked it. Real PCM only: no chiptune conversion, no MIDI to PSG, no generative audio. No OLED now-playing readout, because ADR-0015 gives the auxiliary display to CIPHER.
Options Considered
Section titled “Options Considered”Option A: Charter it as roster program #14, split the name by audience. (ACCEPTED)
Section titled “Option A: Charter it as roster program #14, split the name by audience. (ACCEPTED)”Keeps ADR-0042’s rule intact by doing what the rule asks, and settles the naming with one line an author can apply without thinking: display name WavAmpster, identifier knamp.
Option B: Leave it unchartered.
Section titled “Option B: Leave it unchartered.”Rejected because ADR-0042 makes unchartered programs a defect, and the roster is the router’s authoritative list. An unlisted routable program is exactly the drift the roster exists to prevent.
Option C: Rename it wholesale to knAmp, retiring “WavAmpster”.
Section titled “Option C: Rename it wholesale to knAmp, retiring “WavAmpster”.”Rejected because the Napster-homage register is the point of the operator-facing name, and the brevity argument only ever applied to what gets typed. Splitting by audience keeps both.
Consequences
Section titled “Consequences”Positive
Section titled “Positive”- The router’s program set matches the chartered roster again.
- One naming rule covers every future reference, so the June rename cannot silently revert twice.
- Stations resolve through the
/opt/noshcontract instead of the build-time source checkout.
Negative / Accepted costs
Section titled “Negative / Accepted costs”- Two names for one thing, which needs the rule in this ADR to stay coherent.
- The audio engine is C, so the player is the least Lisp-authored of the first-party programs.
- Operator music is not in version control, so a deck reflash needs
stations.ymlre-run.
Follow-on work this ADR creates
Section titled “Follow-on work this ADR creates”- The screen predates the ASCII design system and hand-draws its progress bar. Recomposing it on
ui/pattern.lspslots (meter, list, kv) is a separate story.
Documentation Updates
Section titled “Documentation Updates”-
docs/adr/README.md: index entry for this ADR -
docs/software/cartridges/authoring/knamp-stations.md: renamed fromwavampster-stations.md -
docs/software/cartridges/authoring/README.md: updated link -
runtime/src/screen_router.c:knampprogram id + lib path -
runtime/programs/knamp/knamp.lsp: renamed, namespaceknamp/ -
sdk/knamp/: crate, binary, and lib renamed fromwavampster -
runtime/src/cli.{h,c}+hosts/emulator/src/main.c:--stationsand the contract probe -
hosts/device/tools/sd-provision/converge/: thestationsrole +stations.yml
Narrative
Section titled “Narrative”WavAmpster is the deck’s music player, and it has worked for a month without ever being written
down. That was fine while it lived only in the emulator, and it stopped being fine once the roster
of first-party programs became the router’s authoritative list: a program the router can reach but
no decision describes is drift waiting to happen. This ADR writes it down, and it settles a name
that had been reverting on its own. The program the operator sees is WavAmpster, loud and a little
ridiculous, which is the point. Everything an author types is knamp. The one piece of the design
future readers should hold onto is why the audio engine is C while the screen is Lisp: the Lisp tick
only fires for the screen you are looking at, and music that stops when you look away is not
background music.