feat(exclusion): resume-under-exclusion + post-hoc re-verifier (finish Phase 1) #17
+471
−24
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 two remaining exclusion items — finishes Phase 1 end-to-end. Builds on #13–#16.
1. Resume-under-exclusion (replaces the #15 force-fresh interim)
#15 always built a fresh zip when an
exclude_specwas set (so the staleness guard never compared an exclusion-filtered zip against a non-exclusion source walk). This restores resume for exclusion archives:archive.enumerate_source_excluded(...)— exclusion-aware sibling ofenumerate_sourcereturning(survivor_count, newest_survivor_mtime, exclusion_report). Reads the spec where it runs (so--globusworks), never raises.__main__resume — the staleness guard now compares survivors against the exclusion-filtered zip (no more spurious[STALE]), and the resumed run records the re-derived exclusion block so reclaim's INV-E stays correct on resumed archives. A changed/added/removedexclude_specshifts the survivor count →[STALE]abort → re-zip with--fresh(message says so). Computed even under--force-resumeso the log is right.2. Post-hoc re-verifier —
verify_exclusions.pyThe audit tool that makes "prove nothing real was dropped" answerable months later, by a different operator, without trusting the original run. Given run-log JSON(s), it re-confirms every recorded exclusion is still git-
COVERED:Uses the coverage config recorded in the log (INV-E's
repo_root), so it needs no access to the originalexclude_spec. Exits non-zero on anyLOST.Tests —
tests/test_exclusion_polish.py(+8)enumerate_source_excluded(no spec / survivors-only / unreadable-spec-counts-all) andverify_log(OK / CHANGED / LOST-when-edited-not-pushed / SKIP / gate-off-is-LOST). CLAUDE.md updated (drops the "pending" notes; adds the new script to the layout). Suite 128 → 136 green.Phase 1 (exclusion) is now complete
--globusrobustnessNext: Phase 2 — size-routing (solo + content-addressed shards) and the RFC rewrite (staged hybrid).
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
🤖 Generated with Claude Code