feat(verify): per-pair cursor + last-touched pair ordering #1

Merged
tcgoellnitz merged 13 commits from worktree-verify-pair-cursor into main 2026-05-20 11:34:44 +00:00
Owner

Summary

  • Verify persists per-pair cursor (cursor_side, cursor_rel) plus
    last_touched_at in ~/Library/Application Support/backup/verify-state/<key>.json
    and resumes interrupted scans where they stopped instead of restarting
    alphabetically.
  • Pairs are ordered by last_touched_at ascending at the start of every
    verify-all run (None = oldest), so no pair starves another in
    budget-limited environments.
  • deactivate --purge removes verify-state alongside fsevents-state.

Implements the spec in
docs/superpowers/plans/2026-05-20-verify-pair-cursor.md.
Closes the starvation gap where large pairs at the end of the config
or files at the alphabetical tail could go indefinitely unverified.

Test Plan

  • Full unittest suite passes (485 tests, 1 skipped pre-existing)
  • Manual smoke test: tight time budget (1 min) against a multi-pair config;
    confirm pair order: <oldest>(touched=...), ... log line and that
    verify-state JSON files appear under ~/Library/Application Support/backup/verify-state/
  • Manual verify run-after-resume: kill mid-scan, run again,
    confirm scan continues at saved cursor (look for scan src: seen=N hashed=K
    with low N relative to the tree size)
  • Manual deactivate --purge: confirm both fsevents-state and
    verify-state files are removed for the drive's pairs
## Summary - Verify persists per-pair cursor (`cursor_side`, `cursor_rel`) plus `last_touched_at` in `~/Library/Application Support/backup/verify-state/<key>.json` and resumes interrupted scans where they stopped instead of restarting alphabetically. - Pairs are ordered by `last_touched_at` ascending at the start of every `verify-all` run (None = oldest), so no pair starves another in budget-limited environments. - `deactivate --purge` removes verify-state alongside fsevents-state. Implements the spec in [docs/superpowers/plans/2026-05-20-verify-pair-cursor.md](docs/superpowers/plans/2026-05-20-verify-pair-cursor.md). Closes the starvation gap where large pairs at the end of the config or files at the alphabetical tail could go indefinitely unverified. ## Test Plan - [x] Full unittest suite passes (485 tests, 1 skipped pre-existing) - [ ] Manual smoke test: tight time budget (1 min) against a multi-pair config; confirm `pair order: <oldest>(touched=...), ...` log line and that verify-state JSON files appear under `~/Library/Application Support/backup/verify-state/` - [ ] Manual verify run-after-resume: kill mid-scan, run again, confirm scan continues at saved cursor (look for `scan src: seen=N hashed=K` with low N relative to the tree size) - [ ] Manual `deactivate --purge`: confirm both fsevents-state and verify-state files are removed for the drive's pairs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A partial state file is worse than no state file, but the prior
implementation only caught KeyError so a JSON object with e.g.
cursor_side: 42 or cursor_side: "garbage" was silently accepted,
violating the dataclass's type annotations.

Add per-field validation matching the template in
backup_mac.backup.state.load_pair_state: pair_name/src/dst must be
str (no str(...) coercion that would mask corruption); cursor_side
must be None or "src"/"dst"; cursor_rel and last_touched_at must
be None or str. Each failure mode logs a WARNING and returns None.

Also fix a stale docstring reference to the deprecated
datetime.utcnow() — point at datetime.now(timezone.utc).strftime(...)
instead. Timestamp-producing code lands in Task 5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
tcgoellnitz/backup_mac!1
No description provided.