6.3 KiB
Podsteadr exact-source adapter
This adapter is based only on the frozen, read-only Podsteadr Git object:
- commit:
eb20e88f582e1ddb0f32e8acf90cd9e77ec63b8f - tree:
be6cf1d033f17ab53f23e5b8e5c7f4492f18e2f8 - authored/committed:
2026-07-31T11:08:20Z - subject:
fix: switch HLS output from low-latency to standard mode
The source-stage receipt intentionally does not establish that this was the source tested by the earlier unpinned packaging proposal. That proposal is not an input to this adapter.
podsteadr-archipelago.patch removes first-valid-login administrator claiming.
The app instead requires PODSTEADR_ADMIN_PUBKEYS, rendered by the manifest
from Archipelago's public-only {{NODE_IDENTITY_PUBKEYS}} contract. Missing or
malformed bindings stop startup. An empty admin slot can be claimed only by one
of those keys. Existing administrators and user rows are preserved and never
silently reassigned by this patch.
Cookie-authenticated state-changing requests additionally require an exact
Origin match against PUBLIC_URL or optional, explicit
PODSTEADR_TRUSTED_ORIGINS. Safe cookie reads and public reads remain
available without an Origin check. NIP-98 authentication remains
request-bound and builds acceptable URLs only from those configured origins;
Host and X-Forwarded-* headers cannot expand the trust boundary.
Paid invoice confirmation atomically claims a quote by moving it from
pending to paid before minting. Concurrent confirmation and restart retry
therefore fail closed rather than invoking the mint twice. A paid quote that
did not reach settled remains an explicit manual/protocol-reconciliation
state; this adapter does not infer a refund, request another invoice, or retry
an external financial operation with an unknown outcome.
The original security adapter tree is
4aaa497444f4d1018991b3d5a691d91f342cbab6; that patch SHA-256 remains
68025cccb6d69ff114115f99fab18416797b02aa947d1ba46fb52578086551e4.
The additive podsteadr-lifecycle.patch handles SIGTERM/SIGINT by closing
Fastify, the status poller, relay pool and SQLite, with a bounded failure exit.
The prior packaged PID-1 process required SIGKILL after a five-second stop;
the lifecycle fixture now requires exit 0, not merely preserved bytes afterward.
Lifecycle patch SHA-256:
4b5b0fe46dcd8aa7eb9583d36bee3bd3cc135b3917ccd45703ffd7969bf8b9dd.
The lifecycle-only tree was b7205e36559ec2110be648686586e6aa1221dd25.
podsteadr-responsive.patch corrects the packaged navigation's493px width at a
390px viewport by allowing genuine wrapping, not hiding overflow. Actual
packaged media/browser and390/1440px layout checks cover the change. It does not
alter backend/auth/payment behavior. The responsive-only tree was
9fd59884e20c4c976c3b8b54ffb4270ece7c62da.
podsteadr-native-bridge.patch adds the missing canonical provider script with
explicit data-app-id="podsteadr" and data-no-nip98: Podsteadr owns its login
request and must not invoke the provider's unrelated automatic-login endpoint.
The bridge-only upstream tree before receipt files was
05084117f72a61c8dd3dbd96ccc81b60f73e1e79.
podsteadr-server-key.patch adds a Linux-container key-only bootstrap and
hardens the server's existing identity loader. Both use the same function and
preserve existing key bytes/inode. New files are fsynced before no-clobber
publication; config/root directory descriptors are pinned, symlinks and unsafe
permissions are refused, and reads are bounded. Existing malformed, hardlinked,
or nonprivate keys fail closed without reset, chmod, rotation or secret output.
Missing keys beside existing database/other application data also refuse;
normal startup establishes identity before opening/migrating SQLite so identity
loss cannot silently generate a new signer.
A reader racing the temporary second hardlink may refuse and require an explicit
retry; it never replaces the winner. Crash remnants are preserved for inspection,
not silently treated as permission to regenerate an identity.
Run node dist/provision-server-key.js /data only in a reviewed provisioning
context with an existing owned data directory. It emits {version:1,publicKey}
and loads no HTTP, database, relay or financial services. It does not configure
Blossom, authorize arbitrary uploaders, rotate keys, or install anything. The
fixture's opt-in PODSTEADR_KEY_BOOTSTRAP=1 checks that bootstrap identity matches
normal startup and recreation, and allows sidecars to start before the app.
The same actual package also passes a synthetic nonempty-data key-loss negative:
startup refuses without changing SQLite or regenerating the key; restoring the
retained exact inode/bytes restores the original authenticated app. This is a
fixture repair, not an automatic product recovery policy. Final logout assertions
remain after restoration (not before reuse of the saved session).
Production manager hooks, durable public-key allowlist binding, nonempty migration
and independent security review remain gates, not permissions granted by this CLI.
Current expected upstream tree: 29e47624ba86572d278411d229e24f4822046021.
Server-key patch SHA-256:
090b7564cec6a05ab3828f6f4c5fb1451d986cd766133ea1e35b9c60e2ee02cd.
The source test gate builds first because bootstrap CLI regressions execute the
compiled command. Fifteen new key cases and all106 server tests pass in isolation;
these are not independent review or managed installation acceptance.
The local build copies neode-ui/public/nostr-provider.js from the exact platform
candidate into the image and records .archipelago-provider-sha256 separately
from the upstream tree. The package test checks served JavaScript against that
receipt and checks the script attributes. This corrects a missing package input,
not native-broker, operator identity or installed trust acceptance. Dashboard
media tests use an explicitly synthetic signer; they do not certify the broker.
Use prepare-source.sh with an explicit source Git directory and a new output
directory. It exports the recorded commit without modifying the source checkout,
verifies its tree, checks and applies the patch, and records the resulting tree.
Source acquisition remains outside this adapter until a sanitized canonical
public source location is approved; a local version label is not provenance.
This is source-stage material, not a reviewed image, signed catalog entry, or installed-node qualification.