fix(repo-hygiene): validate clean-batch plan records against requested --tier (#1081)#1088
fix(repo-hygiene): validate clean-batch plan records against requested --tier (#1081)#1088kyle-sexton wants to merge 1 commit into
Conversation
…d --tier (#1081) clean-batch.sh --apply dispatched purely on each plan line's REPO/GITDIR kind; the apply-time --tier flag was informational only, so a stale or swapped plan executed its full gated content while the banner named a narrower tier (a --tier build dry-run plan applied with --tier caches removed both bin/ and .pytest_cache/ while printing Tier: caches). Apply now pre-scans the plan and refuses it atomically (usage error, exit 2, nothing removed, no apply banner) when it carries a record the requested tier does not authorize: a build REPO record under --tier caches, a caches record under build, or a GITDIR record under a non-git tier. The removal set is unchanged; this closes the scope-misrepresentation between --tier and what apply actually removes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Claude encountered an error after 1s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 0s —— View job I'll analyze this and get back to you. |
|
Warning Automated review did not complete — this is an infrastructure failure, not a review verdict. Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."
Re-running the job, or pushing a new commit, will retry the review. |
|
Warning Automated security review did not complete — this is an infrastructure failure, not a review verdict. Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."
Re-running the job, or pushing a new commit, will retry the review. |
|
🔒 babysit-prs lane claiming this PR for on-branch fix work this cycle (amendment-round: 16, safe tier). Will fix clear branch-owned findings and push; will not resolve threads or merge (safe tier). |
Summary
clean-batch.sh --apply --batch-plan <path>dispatched purely on each plan line'skind (
REPO/GITDIR); the apply-time--tierflag was informational only (it setthe banner and whether the summary reports
gitdirs=). A stale or swapped plantherefore executed its full gated content while the banner named a narrower tier —
e.g. a
--tier builddry-run plan applied with--tier cachesremoved bothbin/and
.pytest_cache/while printingTier: caches. Bounded defect: every removedpath was still enumerated and confirmation-gated at plan creation, so nothing
un-gated is ever removed — the flaw is scope misrepresentation at apply time.
Fix
Per the triage decision on #1081 (validate, do not drop the flag),
--applynowpre-scans the whole plan before the banner and before touching any disk and
refuses it atomically (usage error, exit 2, nothing removed, no apply banner) when a
record the requested
--tierdoes not authorize is present:REPOtokencaches--tier cachesREPOtokenbuild--tier build,--tier allGITDIR--tier git,--tier allThis rejects a
build-class REPO record under--tier cachesand gates theGITDIRarm on a git-bearing tier, exactly as the triage resolved. Atomic refusal(vs. per-record rejection) means the apply banner is never printed for a mismatched
plan, so the misrepresentation is structurally impossible rather than merely caught
after some records already ran. A malformed/unrecognized token is still handled as
before by the apply loop's per-record fail-closed guard (exit 1) — a distinct error
class (structural corruption) from a well-formed plan built for the wrong tier.
Authorization uses a dedicated
tier_repo_tokenhelper (empty for the git tier) —deliberately not the existing
manifest_child_token, which returnsbuildforgit and would wrongly authorize a build REPO record under
--tier git.Header /
usage/clean-batch.mdexit-taxonomy and gated-set docs updated to match.Verification
All commands run in the worktree on this branch.
Full test suite (57 assertions, incl. 3 new tier-authorization tests) + shellcheck:
Exact issue repro (a
--tier builddry-run plan applied with--tier caches) —both
bin/and.pytest_cache/survive:Version:
plugins/repo-hygienebumped 0.7.0 → 0.7.1 (patch bugfix) with a matchingCHANGELOG
[0.7.1]Fixedentry.Related
this issue is the deferred Codex P2 finding from that review.
validation ("reject
build-class REPO records under--tier caches; gate theGITDIRarm on a git-bearing tier — veto before merge"); this PR implements thatdirection exactly.
Closes #1081
Work-class: C3 (bug-fix-shaped) — attended triage 2026-07-23, operator-ratified. 🤖