Fail closed on unreadable manifests instead of losing blobs #180

Merged
clawbot merged 1 commits from issue-157-prune-manifest-integrity into next 2026-09-22 11:45:30 +02:00
Collaborator

Closes #157 (HIGH: silent backup-data loss, no attacker).

Prune finds in-use blobs by reading every snapshot's manifest. A manifest it could not download or decode was logged and skipped, so blobs referenced only by that snapshot looked unreferenced and were deleted — and the command still exited 0, while snapshot create --prune runs it unattended with force. collectReferencedBlobs now returns an error naming the remote key; PruneBlobs propagates it, so prune deletes nothing and exits non-zero.

Three related integrity gaps from the same issue are closed too:

  • Manifest generation logged and skipped a blob whose lookup failed or returned no row, producing a manifest shorter than the snapshot needs (that blob would be pruned next cycle). It now fails instead.
  • Deep verify treated the database as authoritative and only warned when the manifest omitted a database blob. It now fails on any divergence.
  • docs/REPOSTRUCTURE.md described a latest-local vs latest-remote comparison that does not exist; corrected to the real behavior (keeps manifests' blobs, deletes nothing if any manifest is unreadable, needs exclusive access during backups).

Tests: prune deletes nothing and errors on an undecodable manifest; manifest generation errors on a missing blob; deep verify fails when the manifest omits a database blob.

Judgement call: implemented the issue's full four-item Definition of Done, not only the two prune/manifest fixes the brief emphasized.

Model: opus-4-8

Closes https://git.eeqj.de/sneak/vaultik/issues/157 (HIGH: silent backup-data loss, no attacker). Prune finds in-use blobs by reading every snapshot's manifest. A manifest it could not download or decode was logged and skipped, so blobs referenced only by that snapshot looked unreferenced and were deleted — and the command still exited 0, while `snapshot create --prune` runs it unattended with force. `collectReferencedBlobs` now returns an error naming the remote key; `PruneBlobs` propagates it, so prune deletes nothing and exits non-zero. Three related integrity gaps from the same issue are closed too: - Manifest generation logged and skipped a blob whose lookup failed or returned no row, producing a manifest shorter than the snapshot needs (that blob would be pruned next cycle). It now fails instead. - Deep verify treated the database as authoritative and only warned when the manifest omitted a database blob. It now fails on any divergence. - `docs/REPOSTRUCTURE.md` described a latest-local vs latest-remote comparison that does not exist; corrected to the real behavior (keeps manifests' blobs, deletes nothing if any manifest is unreadable, needs exclusive access during backups). Tests: prune deletes nothing and errors on an undecodable manifest; manifest generation errors on a missing blob; deep verify fails when the manifest omits a database blob. Judgement call: implemented the issue's full four-item Definition of Done, not only the two prune/manifest fixes the brief emphasized. Model: opus-4-8
clawbot added 1 commit 2026-09-22 11:18:41 +02:00
Prune learned which blobs are in use by reading every snapshot's
manifest, but merely logged and skipped one it could not download or
decode. Blobs referenced only by that snapshot then looked unreferenced
and were deleted, with a zero exit — and `snapshot create --prune` runs
this unattended. collectReferencedBlobs now errors, naming the remote
key, so prune deletes nothing and exits non-zero.

Manifest generation likewise skipped a blob whose lookup failed or was
missing, yielding a manifest short of what the snapshot needs; it now
fails. Deep verify only warned when the manifest omitted a database
blob; it now fails on any divergence. Docs corrected.

Model: opus-4-8
clawbot added the needs-review label 2026-09-22 11:18:49 +02:00
clawbot self-assigned this 2026-09-22 11:18:49 +02:00
Author
Collaborator

PASS

Model: opus-4-8

PASS Model: opus-4-8
clawbot merged commit 86361c8b50 into next 2026-09-22 11:45:30 +02:00
clawbot deleted branch issue-157-prune-manifest-integrity 2026-09-22 11:45:30 +02:00
Sign in to join this conversation.