Context
The ultra-review verifier on PR #279 traced a since-fixed executor offset desync into live-file corruption, specifically because of two pre-existing defense gaps in crates/driven-localfs/src/store.rs:
- The resumable session only rejects
consumed < session.size, with no overshoot check for consumed > session.size. An over-long append sequence falls straight through to commit instead of being rejected.
commit_object renames the temp file over the live destination before hashing/verifying it. A garbled temp file transiently replaces the user's backed-up file until the next reconcile cycle self-heals it.
The executor-side trigger for this was already removed in PR #279 (window-aligned resume with restart-on-out-of-window offsets), so this issue is purely defense-in-depth hardening in the backend, not a currently-reachable bug.
Ask
- Add a bail-out for
consumed > session.size (overshoot), symmetric with the existing consumed < session.size check.
- Verify the temp file's hash before
commit_rename, not after, so a garbled temp file never transiently becomes the live file.
Related notes
driven-sftp's equivalent bounds check surfaces as a bail! that aborts the whole per-source reconcile, via the unconditional map_err at the executor call site - this skips other pending ops that cycle. Consider mapping it to a per-op abandon instead of a whole-reconcile abort.
- The resume's forward-resync-beyond-window
Restart branch currently has no completion-path test (the test fake rejects out-of-band offsets outright). A smarter fake, or a localfs-backed executor resume test, would close that gap.
Reference
PR #279 (fix(core): stream the resumable-upload resume instead of buffering the whole file) - deferred hardening item from its multi-agent review.
Context
The ultra-review verifier on PR #279 traced a since-fixed executor offset desync into live-file corruption, specifically because of two pre-existing defense gaps in
crates/driven-localfs/src/store.rs:consumed < session.size, with no overshoot check forconsumed > session.size. An over-long append sequence falls straight through to commit instead of being rejected.commit_objectrenames the temp file over the live destination before hashing/verifying it. A garbled temp file transiently replaces the user's backed-up file until the next reconcile cycle self-heals it.The executor-side trigger for this was already removed in PR #279 (window-aligned resume with restart-on-out-of-window offsets), so this issue is purely defense-in-depth hardening in the backend, not a currently-reachable bug.
Ask
consumed > session.size(overshoot), symmetric with the existingconsumed < session.sizecheck.commit_rename, not after, so a garbled temp file never transiently becomes the live file.Related notes
driven-sftp's equivalent bounds check surfaces as abail!that aborts the whole per-source reconcile, via the unconditionalmap_errat the executor call site - this skips other pending ops that cycle. Consider mapping it to a per-op abandon instead of a whole-reconcile abort.Restartbranch currently has no completion-path test (the test fake rejects out-of-band offsets outright). A smarter fake, or a localfs-backed executor resume test, would close that gap.Reference
PR #279 (fix(core): stream the resumable-upload resume instead of buffering the whole file) - deferred hardening item from its multi-agent review.