prepare records an immutable manifest of every regular backend/dist file (path/size/sha256/dev/ino) in the owned root and binds its record identity in ownership; serve revalidates record and every file before spawn, passes the manifest to the child on fd 4, and the immutable preload hash-verifies all files at startup and serves only cached verified bytes for any import below backend/dist, so imported dependency replacement is refused before RUNNING or never executes. The render command validates the commit snapshot.json manifest, binds snapshot bytes to the manifest digest and the installed Git blob, and passes the expected digest to the renderer, which revalidates head/files digest with bounded no-follow reads and renders only verified bytes with lease release on refusal.
4.2 KiB
Task 9 quality audit — final 5
Scope: the two blocking findings from task9-quality-audit-final4.md — unbound production
module graph at manual serve, and commit-addressed snapshots accepted without content identity at
render. Manual acceptance remains PENDING; no VERDICT.md was created.
Verdict: APPROVED for the two final integrity blockers
1. Manual serve binds the complete backend/dist module graph, not only server.js
prepare now builds a post-build manifest of every regular backend/dist file
(relative path, size, SHA-256, device, inode) and writes it as an exclusive 0600 record
(installation/runtime/backend-dist.manifest.json) inside the owned root; ownership.json
records that record's path/device/inode/size/SHA-256. serve revalidates the manifest record
identity and bytes, revalidates every distribution file against it (no-follow, single inode,
size and digest), and refuses before spawning. The manifest descriptor is passed to the child on
fd 4 together with the entrypoint on fd 3. The immutable preload parses the manifest, verifies
the entrypoint cross-digest, reads and hash-verifies every file at startup, caches the
verified bytes, and its load hook serves only those cached bytes for any import below
backend/dist (entry URL still served from the bound fd-3 bytes). A same-path regular
replacement of any imported dependency is therefore refused before RUNNING (serve-time
validation), refused at child startup (startup verification), or rendered harmless (cached
bytes), and the parent revalidates the full manifest at RUNNING publication and at stop.
2. Renderer binds snapshot content to its commit identity
The generated render command validates the bounded saved read/publish revisions, the
commit-addressed owned snapshot path, the installed Git HEAD, and the bounded
snapshot.json manifest of that commit: head equals the commit, files[<id>.yaml] is the
SHA-256 of the snapshot bytes, the manifest revision binds commit/blob/snapshot path, the saved
revision blob equals the manifest blob, and git rev-parse <commit>:workspaces/<id>.yaml plus
git hash-object of the snapshot bytes both equal that blob. It passes the expected digest as
--snapshot-sha256. The renderer re-reads the bounded snapshot.json (head,
files[<id>.yaml] must equal the carried digest), opens the snapshot once with no-follow
semantics and bounded reads, renders only the digest-verified bytes, re-verifies around lease
publication, releases the lease in finally, and publishes no output on any refusal.
Deterministic regressions added
- static regular replacement of an imported production dependency after
prepareis refused, no marker, no accepted PID record, no orphan; - deterministic dependency check/load swap (
beforeSpawnrename) is refused by the child's startup verification, no marker, no PID record, no orphan; - after
RUNNING, a same-path regular dependency replacement is never executed: the loader serves the verified cached bytes (health-visible source stays the original) and the marker is absent; - renderer refuses a same-path regular snapshot byte replacement against the carried digest and manifest, with lease release and no output;
- renderer refuses manifest
head,filesdigest, expected-digest, missing, and malformed cases, with lease release and no output; - wrapper refuses missing manifest, manifest head/digest/revision tampering, saved-revision blob
mismatch, Git blob mismatch, and snapshot-vs-Git-bytes mismatch, and passes the exact
--snapshot-sha256on the valid path (stub renderer records arguments).
Verification
bash scripts/test-p1-manual-acceptance.sh(backend build + both suites): 59 tests, 59 pass, 0 fail; no8791/8792listener and no--p1-manual-nonceprocess remain.npx tsc --noEmit -p .(backend): PASS.- Real-repository
prepare+cleanupcycle: 39 distribution files bound, entrypoint cross-digest verified, owned root fully removed afterwards. - Diff check: only the seven Task 9 paths are touched; no Task 8 file was modified.
- This report and the implementation contain no fixture secret or canary values.
Manual acceptance remains PENDING by design; the walkthrough and human verdict are unchanged.