diff --git a/plugins/repo-hygiene/.claude-plugin/plugin.json b/plugins/repo-hygiene/.claude-plugin/plugin.json index 2ead9dbf1..f1c4aa7de 100644 --- a/plugins/repo-hygiene/.claude-plugin/plugin.json +++ b/plugins/repo-hygiene/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "repo-hygiene", - "version": "0.4.1", + "version": "0.4.2", "description": "Repo hygiene action-router: /repo-hygiene:clean sweeps reclaimable caches, build artifacts, and stale git metadata, and can realign the working tree to a fresh-pull state — dry-run-first, with destructive tiers gated behind explicit confirmation and a session-scoped destructive-command guard. Ecosystem targets are detected at runtime; secrets, runtime dependencies, and skill data are preserved by default.", "author": { "name": "Melodic Software", diff --git a/plugins/repo-hygiene/CHANGELOG.md b/plugins/repo-hygiene/CHANGELOG.md index 5638985d1..824d235f5 100644 --- a/plugins/repo-hygiene/CHANGELOG.md +++ b/plugins/repo-hygiene/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to the `repo-hygiene` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.4.2] + +### Fixed + +- **`git-tree-reset` context doc — surfaces the `reset --hard` non-atomicity + caveat on the exit-5 gate.** The exit-5 bullet in + `skills/clean/context/git-tree-reset.md` accurately described the gating + contract (a failed `reset --hard` skips `clean` and the restore guard, so the + tree is never left cleaned-but-not-reset) but omitted that `reset --hard` is + not atomic and may have partially modified tracked files before it failed — + a caveat the runtime exit-5 stderr message already surfaces. The bullet now + carries that parenthetical, so the doc is consistent with the script's stderr + output. (#485) + ## [0.4.1] ### Fixed diff --git a/plugins/repo-hygiene/skills/clean/context/git-tree-reset.md b/plugins/repo-hygiene/skills/clean/context/git-tree-reset.md index 5c553afbf..e2dd8d8ae 100644 --- a/plugins/repo-hygiene/skills/clean/context/git-tree-reset.md +++ b/plugins/repo-hygiene/skills/clean/context/git-tree-reset.md @@ -36,7 +36,7 @@ Skill data (`.claude/skills/*/data/`) is preserved unconditionally — no flag r - Upstream tracking branch required (`@{u}`); a configured-but-unresolvable upstream — remote-tracking ref absent (e.g. a squash-merged branch whose remote was deleted and pruned), where `@{u}` degrades to the literal token — is a first-class gate: skip the repo with `Blocked: upstream-unresolved (/)` before any destructive op, so a literal `@{u}` can never reach `reset --hard` (exit 6). - Blocks on default branch (`main`/`master`/resolved default) unless `--force-default-branch` (exit 3). - Aborts when HEAD is ahead of upstream unless `--allow-unpushed` (exit 4) — prevents silent loss of unpushed commits. -- Aborts the apply if `reset --hard` fails (exit 5) — `clean` and the restore guard never run, so a failed reset can never leave the tree cleaned but not reset. +- Aborts the apply if `reset --hard` fails (exit 5) — `clean` and the restore guard never run, so a failed reset can never leave the tree cleaned but not reset (the reset itself may have partially modified tracked files, since `reset --hard` is not atomic). - Aborts the apply if `git clean -fdx` genuinely fails (exit 7) — a non-zero clean exit whose cause is NOT locked/in-use files. The reset succeeded (its `AppliedReset:` line is still emitted); `clean` prints `AppliedClean: failed` instead of a success line, so the report can never claim a clean that errored. Locked/in-use files are the expected non-fatal case (see `Unremovable:` below) and are not a failure. - Post-clean restore guard: any tracked file deleted via reparse-point traversal is restored from the index (`RestoredTracked:` count; safe because `reset --hard` ran first). - Locked / in-use files git could not delete are reported (`Unremovable:`), not silently left.