Summary
The content-addressed handler advances the durability vector (gating offload) with VerifyResult.Verified() == false — its evidence is presence + ciphertext size, not content verification — and the gate cannot tell a presence+size-backed component apart from a BLAKE3-backed one. The design's scan-back fingerprint (the thing that upgrades presence+size to a recordable ciphertext checksum) needs to be the precondition for these components gating deletion.
Where
sync/content_addressed.go — advances internally despite Verified() == false; Verification.Method = "presence+size".
offload/gate.go — reads destination_run_ids with no per-component verification method.
store/remote_objects.go — checksum_algo/checksum columns exist (nullable since v17) but, prior to the fingerprint PR, nothing populates them.
Why it matters
Offload deletes local bytes once the gate passes. For a content-addressed offsite, "passed the gate" currently means "rclone reported the upload succeeded and a listing showed the expected (decrypted, i.e. arithmetically derived) length" — no content check. The README is honest that the runs row is shallow; the vector is not, and the gate treats both methods identically.
Fix shape
Record the verification method per component (or per remote_objects row), and have the offload gate require a genuinely content-verified component for content-addressed targets — i.e. hold these targets out of the gate until the scan-back fingerprint pass has recorded a checksum and a verified_at_ns. Coordinate with the fingerprint PR (which populates remote_objects.checksum).
This is the "verified by construction / no trust column" premise from the design — it holds only once every gating advance is actually verified.
Adversarial audit of offload-v1 (auditor D F5).
Summary
The content-addressed handler advances the durability vector (gating offload) with
VerifyResult.Verified() == false— its evidence is presence + ciphertext size, not content verification — and the gate cannot tell a presence+size-backed component apart from a BLAKE3-backed one. The design's scan-back fingerprint (the thing that upgrades presence+size to a recordable ciphertext checksum) needs to be the precondition for these components gating deletion.Where
sync/content_addressed.go— advances internally despiteVerified() == false;Verification.Method = "presence+size".offload/gate.go— readsdestination_run_idswith no per-component verification method.store/remote_objects.go—checksum_algo/checksumcolumns exist (nullable since v17) but, prior to the fingerprint PR, nothing populates them.Why it matters
Offload deletes local bytes once the gate passes. For a content-addressed offsite, "passed the gate" currently means "rclone reported the upload succeeded and a listing showed the expected (decrypted, i.e. arithmetically derived) length" — no content check. The README is honest that the runs row is shallow; the vector is not, and the gate treats both methods identically.
Fix shape
Record the verification method per component (or per
remote_objectsrow), and have the offload gate require a genuinely content-verified component for content-addressed targets — i.e. hold these targets out of the gate until the scan-back fingerprint pass has recorded a checksum and averified_at_ns. Coordinate with the fingerprint PR (which populatesremote_objects.checksum).This is the "verified by construction / no trust column" premise from the design — it holds only once every gating advance is actually verified.
Adversarial audit of offload-v1 (auditor D F5).