Podsteadr disposable package qualification
Build only from the exact inspected adapter using
bash docker/podsteadr/build-local-candidate.sh SOURCE_GIT NEW_WORK_DIR.
This produces a local unqualified image. It neither activates a catalog
entry nor proves canonical source acceptance. Base image and npm lockfiles are
pinned; the runtime records installed OS package versions, but a reproducible
OS repository snapshot and independent provenance review remain required.
Run PODSTEADR_FIXTURE_IMAGE=FULL_LOCAL_IMAGE_ID bash tests/apps/podsteadr/run-disposable.sh.
The fixture has no external network, host ports, credentials, engine sockets or
installed app data. Every key, account, database and volume is disposable.
Only fixture-owned containers and its named volume are removed.
Covered with the actual built server and dashboard:
- Explicit nonroot UID/GID 1000, actual image healthcheck and served HTML.
- Missing admin binding fails startup rather than assigning first-login admin.
- An unrelated first login cannot claim administration; bound identity can.
- Foreign/missing Origin cookie writes and nonadmin settings writes denied.
- Graceful SIGTERM exits zero; restart with a changed binding preserves the original admin, server-key bytes/private mode, settings and persisted sessions.
- Abrupt SIGKILL/recreation preserves that state too; logout revokes the original session after both recovery modes.
- Test-only synthetic
paid/settledquote, purchase and invalid nonredeemable proof rows survive both recovery modes byte-for-byte. Three parallel retries of the paid quote fail closed with 409, foreign-owner retry gets 404, and repeated settled confirmation returns the original purchase. A loopback sentinel mint receives zero requests; no replacement invoice/mint is attempted.
The synthetic rows are inserted into this fixture's own SQLite database to model interrupted prior state. They are not real payments, valid Cashu proofs, mint reconciliation, certified receipts, or evidence that an ambiguous paid quote can successfully finish delivery. No live database bypass is permitted.
Actual media and packaged browser composition
Run tests/apps/podsteadr/run-media-disposable.sh with immutable local image IDs
in PODSTEADR_FIXTURE_IMAGE, MEDIAMTX_FIXTURE_IMAGE and
BLOSSOM_FIXTURE_IMAGE. Optionally set PODSTEADR_BROWSER_IMAGE to the qualified
Cloud browser runtime to join the actual packaged dashboard journey. No source
or upstream replies are mocked in this composition; only identities/media are
synthetic. Each service shares a disposable network-none namespace, has no host
ports, drops all capabilities and is resource bounded. The app mounts recordings
read-only; MediaMTX alone writes them. Namespace consumers are removed first.
Covered: actual rotated-key RTMP refusal, test-pattern ingest, production status polling, live HLS decoding, recorded MP4 remux, signed upload to the hardened Blossom package, digest/length/exact-byte download and decoding, RSS enclosure, foreign-owner/path refusals and original-recording preservation. The browser uses the real packaged login and API with a restricted synthetic NIP-07 signer, selects and publishes a free recording, checks mobile/desktop reload and cookie persistence. Recreating all three services preserves original recordings, identity, episodes and downloadable bytes. Public signer dependencies are copied from the pinned Podsteadr image into a disposable volume; no fresh npm install.
A real390px header overflow was reproduced by layout-browser.mjs (493px
scroll width), which uses packaged static files and synthetic API replies for
cheap layout-only diagnosis. The additive responsive patch wraps navigation;
390/1440px layout and the full real-media/browser composition then pass.
Layout-only evidence is never substituted for actual integration.
Still open: supported financial recovery/protocol review, production identity/origin rendering, manager-driven install/update/uninstall-preserve/ reinstall, existing-data ownership migration, canonical provenance and operator/device acceptance, including WHIP/camera and network/NAT paths.
A first package needed SIGKILL on stop, and its OCI output omitted Docker healthcheck metadata. The additive lifecycle patch and Docker-format build fix these; the fixture requires clean stop and runs the actual stored healthcheck.