feat(exclusion): wire the second filter into the archive path (Phase 1b-1) #15
+410
−16
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
Turns exclusion on in the live archive path — the first behavior change of the feature.
make_zip_filesnow applies the subtractive identity+coverage filter and drops git-COVEREDregenerable metadata from the zip it builds; the archive path logs and reports exactly what happened.Builds on the primitives (#13) + orchestrator (#14). Part of the settled staged-hybrid direction, Phase 1.
Design guarantees
--globus-capable. Theexclude_specPATH is read on the machine that builds the zip (a compute node, which has/depot), so it works whether launched locally or from a Mac via--globus.evaluate_exclusionsnever raises; a bad/unreadable spec, an unreachable git remote, or missinggiton a node all degrade to "back up everything" with a recorded reason.COVERED.Changes
load_config: newexclude_spec(path|null) +exclude_optional(list) keys, type-checked only (file read at run time).make_zip_files: reads the spec, runsevaluate_exclusions, subtracts the COVERED set frommatched_files, returns the report as a 6th value; refuses to build an empty archive.reconstruct_from_zipreturns a matching 6-tuple.send_to_fortress: records the fullexclusionblock in the run log (reclaim will readexcluded_arcnames+ re-gate — INV-E, next PR);[EXCLUDE]/[EXCLUDE-DEMOTE]/[EXCLUDE-CONTEST]audit lines; exclusion summary in the completion email; on a companion-guard (INV-C) trip sends a loud[EXCLUSION-ABORT]alert while continuing (everything backed up) — per your "continue + loud alert" call.__main__: banner line + plumbing.config.example.json+ CLAUDE.md (config table + an Exclusion section).Interim note (next slice)
When an
exclude_specis configured the run always builds a fresh zip (skips resume), so the staleness guard never compares an exclusion-filtered zip against a non-exclusion source walk. Proper resume-under-exclusion (exclusion-awareenumerate_source+ a spec-sha guard) is the next PR, followed by reclaim INV-E + the post-hoc re-verifier.Tests —
tests/test_exclusion_wiring.py(+9)load_configvalidation;make_zip_filesend-to-end against a real repo + bare remote — drops COVEREDstatus/catalogJSON, keeps DATA (.tiff/.csv); subtractive keying (members == checksums == zip, excluded in none); unreadable spec and dirty subtree both DISABLE and back up everything.test_size_driftupdated for the 6-tuple. Suite 110 → 119 green.Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
🤖 Generated with Claude Code