feat(disk-hygiene): accept_unpublished lane for throwaway repos (#4227) - #4936
Conversation
|
PR body contract — issue linkage This PR body conforms to the issue-linkage contract. Nothing to do. |
Gates 1-2 stay categorical. A local Git checkout that cannot pass the evidence bundle remains contested; the model never deletes it outside the engine. No accept_unpublished relaxation. Bump to 0.27.4. Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
eee7c0d to
a57942b
Compare
# Conflicts: # plugins/disk-hygiene/CHANGELOG.md
…#4227) A vcs-evidence.json repository entry may carry "accept_unpublished": true with a non-empty "reason". It is accepted only on an entry whose path is itself an exact approved path. It waives the empty-porcelain and heads-on-remote gates for that repository; a status or head probe that fails to run, the stash gate, the repository-set and git-boundary checks, and every link, mount, handle, identity, and descendant check still apply. The gates report "accepted-unpublished" and the evidence result lists each acknowledgement with its reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PT4esxbdC7eQiwQxy35Mie
Replace the "contested throwaways stay contested" text with the decided lane: an operator-overridden contested checkout goes through accept_unpublished and handoff-verify, never an out-of-engine deletion, and the operator is told unpushed and untracked content will be lost. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PT4esxbdC7eQiwQxy35Mie
Add tests that an acknowledgement covers only its own approved path, never a nested repository, and never an identity change after the scan. Point the four-gate sentence at the waiver, and tie the skill's deletion step to the manual handoff lane. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PT4esxbdC7eQiwQxy35Mie
|
Claude finished @kyle-sexton's task in 3m 16s —— View job Security review complete
Scope: No security issues found. Notes from the review (informational, not findings):
This is a narrow, well-tested relaxation of an internal safety gate, gated by exact-path matching and a mandatory human-authored reason, with no injection, auth-bypass, or secret-handling issues in the diff. |
|
Claude finished @kyle-sexton's task in 4m 20s —— View job
|
Resolve CHANGELOG.md conflict in disk-hygiene: identical-bump collision at 0.28.8, renumbered to 0.28.9. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PT4esxbdC7eQiwQxy35Mie
|
Claude finished @kyle-sexton's task in 1m 47s —— View job Security review — skipped (unchanged diff)
Skip gate: this head already has a successful security review that still applies. The three-dot diff No new security-relevant surface to review. The prior finding — no security issues found — |
…o 0.28.14 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hx63mvV8t39y644DQ3uLnn
|
Claude finished @kyle-sexton's task in 2m 48s —— View job
|
|
Claude finished @kyle-sexton's task in 1m 53s —— View job Security review — skipped (unchanged diff)
Skip gate: this head already has a successful security review that still applies (skip-gate condition 3).
The No new security-relevant surface to review at |
…checkout (#5541) Closes #5178 ## Summary On Linux an operator-acknowledged throwaway checkout had no deletion route inside the engine: `handoff-verify` ran only on Windows and macOS, and `apply` keeps VCS protection categorical. This adds `handoff-apply`, a Linux-only engine route for one exact approved path. The acknowledgement (`accept_unpublished` in `vcs-evidence.json`) is evaluated only in the handoff verification path; preview and token `apply` stay categorical, as the owner decided on the issue. ## Fix - `hygiene.py`: new `handoff-apply` subcommand (`--execute --snapshot --path --vcs-evidence --report --data-root`). It refuses off Linux, runs `handoff_verify` in-process for the one path, deletes only on a `clear` verdict, repeats the non-VCS checks per entry, and waives only `vcs-tracked-content`. The verdict reports `accept_unpublished`. - The snapshot records `.git` without its descendants, so `handoff-apply` is the one lane that removes entries outside the snapshot: it empties the repository metadata fd-relative, refusing on a mount point, a consumer protection glob match (re-checked per child as the purge reaches it), an unreadable directory or a device change, and unlinking links rather than following them. - `destructive_guard.py`: the exact `handoff-apply` shape asks when the plugin is enabled (`exact-engine-handoff-apply`); the kill switch denies it (`kill-switch-disabled-handoff-apply`). - SKILL.md, `safety-model.md`, `unsupported-platform-handoff.md`, the fan-out worker brief and the README name the Linux route and keep the loss warning (unpushed commits and untracked or ignored files are lost). - disk-hygiene 0.35.0 with a CHANGELOG entry. ## Verification - `bash plugins/disk-hygiene/skills/clean/scripts/hygiene.test.sh` (from `skills/clean/scripts`): 624 tests OK on the merged tree, covering the Linux route, an unacknowledged repository staying contested, the per-child protection recheck and the guard shapes. - `check-changelog-parity.sh` with `--check`, `--check-order`, `--check-bump origin/main` and `--check-preserved origin/main`, and `validate-plugins.sh`: pass. - Ruff check through the pinned wrapper and markdownlint: clean. ## Related - #4227, #4936 - Owner decision (2026-09-29) on #5178: add a Linux `handoff-verify` to engine `apply` route that re-checks gates 3+, acknowledgement only in handoff-verify, preview and apply categorical. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Closes #4227
Summary
Adds the
accept_unpublishedlane the #4227 decision chose. A throwaway local Git checkout (no remote, untracked files, zero commits) can now verifyclearinhandoff-verifyonce the operator records an acknowledgement for that exact approved path. Before this, such a checkout could only be deleted outside the engine, with every check skipped. This PR replaces the earlier "contested throwaways stay contested" text, which documented the opposite of the decision.Fix
handoff-verifyVCS evidence mode): avcs-evidence.jsonrepository entry may carry"accept_unpublished": truewith a non-empty"reason". The entry is accepted only when itspathequals an approved path exactly, so a nested repository or a pattern cannot carry it. The value must be the literaltrue, and the two keys must appear together.github.comremote) reportaccepted-unpublishedinstead of failing. A status or head probe that fails to run still fails closed. Gate 3 (stashes), the repository-set and Git-boundary checks, and every link, mount, handle, identity, and descendant check still apply.vcs_evidence.accept_unpublishedlists each acknowledgement with its reason. Without an acknowledgement, verdicts are unchanged.SKILL.md,reference/safety-model.md, andreference/unsupported-platform-handoff.mdnow require the acknowledgement plushandoff-verifybefore any deletion the operator overrides, forbid deleting outside the engine, and require warning the operator that unpushed commits and untracked or ignored files will be lost.disk-hygiene0.28.14 (one patch above main), with a CHANGELOGAddedentry.Verification
HandoffVerifyTestscases, written first (red, then green):clear, and the verdict shows the acknowledgement and its reason;contested;SKILL.mdrequireshandoff-verifybefore an operator-overridden VCS deletion, forbids out-of-engine deletion, and requires the loss warning (text assertion);truevalue, a blank reason, or a reason without the flag (or the flag without a reason).hygiene.test.sh: 492 tests. The only failures are the 11test_guard_allows_literal_readonly_supporting_bash_commandssubtests, which also fail onmainon this machine.scripts/check-changed-skills.sh origin/mainshows those same 11 failures and nothing else.check-changelog-parity.shpasses--check,--check-order,--check-bump origin/main, and--check-preserved origin/main.check-stale-base-overlap.sh --check origin/main,check-purged-em-dashes.sh,markdownlint-cli2,typos, andscripts/run-ruff.sh check plugins/disk-hygieneall pass.Related
🤖 Generated with Claude Code
https://claude.ai/code/session_01PT4esxbdC7eQiwQxy35Mie