Repository navigation
feat(s19): snapshot producer, restore-check, live doctor probes, bundle folding - #64
Merged
Merged
Conversation
…le folding Productizes the practiced procedure in scripts/ship-backup.sh where that is safe, keeping its invariants load-bearing in the CLI too: - teploy-ship snapshot: same archive shape as the script (tar of the nucleus data dir + sha256 sidecar + manifest); refuses while ship-* containers run unless the operator attests the coordinated stop (--i-stopped-writers); never overwrites; never deletes anything except its own partial output after a failed production so a failed tar cannot wedge the label+date slot. - teploy-ship restore-check: verifies an archive WITHOUT unpacking (sidecar in sha256sum -c form, full-stream gzip integrity, content listing failing on absolute/.. paths); verdict is integrity-only and names the rehearsal as the restore proof. The unpack and rehearse stay in the script. - doctor: store liveness (SELECT 1) and clock skew against the store's own clock (SELECT now()) probed read-only when NUCLEUS_URL is set; unknown otherwise or when the engine answers no time query; store consistency deliberately not probed (read-only while writers may run). - support bundle (scriptVersion 2): doctor.json + the latest backup manifest (the receipt, never the archive), both degrading to note files. Tests: 11 snapshot/restore-check tests incl. negative controls (running-writer refusal with the exact stop line, overwrite refusal, tampered sidecar, truncated archive with re-computed checksum caught by gzip, path-escape listing, failed-production cleanup), 4 live-probe doctor tests against a fake store client, 2 bundle folding tests. Fake fixtures only; no live systems. No upstream defects found; nothing to report upstream.
# Conflicts: # AUDIT_OPEN.md # CHANGELOG.md # NEXT_SESSION.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The S19 tail from the programme (row #49): the snapshot producer, the restore-check command, doctor's store/clock probes, and folding doctor + the latest backup receipt into the support bundle.
teploy-ship snapshot— produces the same archive shape asscripts/ship-backup.sh backup(<label>-<date>/nucleus-data-full.tgz+.sha256sidecar +manifest.txtunderSHIP_BACKUP_DIR, default/_backups). Refuses while anyship-*container it can see is running, printing the exact coordinateddocker stopit expects, unless the operator attests with--i-stopped-writers. Never overwrites; never deletes anything except its own partial output after a failed production (so a failed tar cannot occupy the label+date slot forever — retention stays the operator's). Docker absent/unreachable is advisory, not a refusal: a box without docker can still take a snapshot.teploy-ship restore-check <archive>— verifies WITHOUT unpacking: sha256 sidecar insha256sum -cform (the sidecar must travel with its archive), full-stream gzip integrity (node zlib, the honestgzip -t), and the tar content listing, failing on absolute or..paths that would escape an unpack target. Exit 0 only forverified. The verdict is integrity-only and names the rehearsal (scripts/ship-backup.sh rehearse) as the restore proof — the unpack and rehearse steps stay in the script by design.doctor— store-connectivity and clock stop reporting blind unknowns whenNUCLEUS_URLis set: read-only liveness (SELECT 1) and skew against the store's own clock (SELECT now()), each degrading to unknown rather than guessing. Store CONSISTENCY is deliberately not probed (cannot be established read-only while writers run); with no configured store both stay unknown and say why.scriptVersion2) — now carriesdoctor.jsonandbackup-receipt.txt(the latest backup manifest — the receipt, never the archive), both through the redaction gate and both degrading to note files.Verification
pnpm run lintclean;pnpm run buildclean.pnpm test: 2180/2180 root, 222/223 scripts (1 skip =ship-backup.test.mjsrehearse-without-docker on a docker-present machine; the grader-sensitivity port-8901 test passed on the recorded run — it is the documented CI-run item on contention).src/snapshot.test.ts(11): archive shape parity with the script, running-writer refusal with the exact stop line,--i-stopped-writersattestation recorded in the manifest, docker-unavailable advisory, overwrite refusal with bytes unchanged, dry-run writes nothing, failed-production cleanup + retryable slot, tampered sidecar / wrong-name sidecar / missing sidecar, truncated archive with a re-computed sidecar caught by gzip (the checksum alone cannot), path-escape listing, receipt selection (newest, skips rehearsals, bounded).src/install-doctor.test.ts(+4):SELECT 1liveness true/false, store clock parsed from Date/number/ISO, garbage/throwing time query degrades the clock to unknown (runDoctor reports incomplete, not ready), probes wired through runDoctor (answering store = ready; silent store = not-ready with clock unknown).src/support.test.ts(+2): bundle carries redacted doctor.json + receipt; both degrade to notes.verifyaccepting the CLI-produced archive, and a file-store support bundle containing both new files.Deliberately deferred
restore --into) and rehearsal remain script-only — they touch a live recovery.restore-readiness.tsstill has no command of its own.Programme row #49 and AUDIT_OPEN.md updated to match. No upstream defects found. DO NOT MERGE (slice discipline).