mandrel 2.66.0 → 2.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/.agents/agents/acceptance-critic.md +2 -2
  2. package/.agents/docs/agentrc-reference.json +2 -1
  3. package/.agents/docs/configuration.md +2 -1
  4. package/.agents/docs/workflows.md +4 -2
  5. package/.agents/instructions.md +2 -1
  6. package/.agents/rules/git-conventions-reference.md +5 -5
  7. package/.agents/rules/git-conventions.md +1 -1
  8. package/.agents/schemas/agentrc.schema.json +6 -1
  9. package/.agents/scripts/boot-sweep.js +97 -9
  10. package/.agents/scripts/{git-cleanup.js → clean-git.js} +2 -2
  11. package/.agents/scripts/clean-temp.js +54 -0
  12. package/.agents/scripts/clean-worktrees.js +593 -0
  13. package/.agents/scripts/drain-pending-cleanup.js +5 -4
  14. package/.agents/scripts/lib/clean-temp.js +440 -0
  15. package/.agents/scripts/lib/config-settings-schema-delivery.js +11 -2
  16. package/.agents/scripts/lib/generated/agentrc-validator.js +1 -1
  17. package/.agents/scripts/lib/observability/source-classifier.js +3 -1
  18. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  19. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +149 -97
  20. package/.agents/scripts/lib/single-story-sweep.js +2 -2
  21. package/.agents/scripts/lib/temp-removal.js +110 -0
  22. package/.agents/scripts/lib/temp-retention.js +122 -73
  23. package/.agents/scripts/lib/worktree/canonical-path.js +34 -0
  24. package/.agents/scripts/lib/worktree/lifecycle/reap.js +15 -4
  25. package/.agents/scripts/single-story-init.js +120 -17
  26. package/.agents/workflows/{git-cleanup.md → clean-git.md} +10 -10
  27. package/.agents/workflows/clean-temp.md +67 -0
  28. package/.agents/workflows/clean-worktrees.md +63 -0
  29. package/.agents/workflows/git-deliver.md +1 -1
  30. package/.agents/workflows/helpers/acceptance-self-eval.md +3 -2
  31. package/.agents/workflows/helpers/deliver-story-reference.md +2 -2
  32. package/docs/CHANGELOG.md +13 -0
  33. package/package.json +1 -1
@@ -0,0 +1,67 @@
1
+ ---
2
+ description: >-
3
+ Clear the temp-tree backlog the land-time purge cannot attribute: sort every
4
+ top-level entry under the project's tempRoot into framework, closed-issue,
5
+ aged and kept buckets, preview by default, and delete only confirmed buckets.
6
+ ---
7
+
8
+ # /clean-temp [--execute] [--yes] [--json]
9
+
10
+ The land-time and boot-time purges only reap what they can attribute: the
11
+ framework's own temp layouts and `temp/scratch/`. Everything else an agent
12
+ dropped at the temp root is reported and left alone, so a busy consumer's temp
13
+ tree grows without bound. `/clean-temp` is the operator's catch-up for that
14
+ backlog. It classifies and deletes through the same temp-retention engine the
15
+ purges use — there is no second walker.
16
+
17
+ The script documents its own flags:
18
+ `node .agents/scripts/clean-temp.js --help`. Without `--execute` it is a
19
+ **dry-run preview**; nothing is deleted.
20
+
21
+ ## Buckets
22
+
23
+ Every top-level entry under tempRoot lands in exactly one:
24
+
25
+ | Bucket | What it holds | Unattended (`--yes`) |
26
+ | --- | --- | --- |
27
+ | **framework** | A framework layout holding artifacts the auto-purge would take — Story-keyed on a closed Story, or past `staleDays`. | Deleted |
28
+ | **closed-issue** | An unrecognized entry whose basename names exactly one issue id, and that issue reads `closed`. | Deleted |
29
+ | **aged** | An unrecognized entry naming no id, or several, older than `staleDays`. | **Never** — an age heuristic has no attribution, so it needs a human |
30
+ | **kept** | Everything else, with the reason: issue open, issue read failed, too recent, reserved, or nothing spent. | Kept |
31
+
32
+ An id is a standalone run of up to seven digits in the basename. A basename
33
+ naming two ids is never attributed to either — it is treated as id-less.
34
+
35
+ ## Constraint
36
+
37
+ > [!WARNING] `--execute` deletes files. Interactive runs confirm each bucket;
38
+ > `--yes` deletes the framework and closed-issue buckets only.
39
+
40
+ - Reads fail safe: an open issue, or one whose read fails, keeps its entry.
41
+ - `qa/`, `cache/`, `*.lock` and `signals.ndjson` at any depth are never
42
+ deleted.
43
+ - Project-scoped: the script exits 1 without deleting anything when the
44
+ resolved tempRoot is not inside the project root it was invoked from. It
45
+ never touches `$TMPDIR` or a sibling checkout.
46
+
47
+ ## Steps
48
+
49
+ 1. Preview and read the table (bucket, entry, size, age, reason):
50
+
51
+ ```bash
52
+ node .agents/scripts/clean-temp.js
53
+ ```
54
+
55
+ 2. Delete, confirming each bucket:
56
+
57
+ ```bash
58
+ node .agents/scripts/clean-temp.js --execute
59
+ ```
60
+
61
+ Unattended, `--execute --yes` deletes the framework and closed-issue buckets
62
+ and reports the aged bucket as left for a human. `--json` emits the envelope
63
+ (per-bucket totals and `bytesReclaimed`) instead of the table.
64
+
65
+ Going forward, put ad-hoc scratch under `temp/scratch/story-<id>/` (or
66
+ `temp/scratch/` with no Story): a Story's landing reaps its scratch directory,
67
+ and the boot sweep age-floors the rest.
@@ -0,0 +1,63 @@
1
+ ---
2
+ description: >-
3
+ Reclaim disk from dead worktrees: list every worktree of this project as a
4
+ removal candidate (closed Story, merged branch, orphaned directory, detached
5
+ HEAD) or as kept with a reason, then remove candidates only on `--execute`.
6
+ ---
7
+
8
+ # /clean-worktrees [--execute] [--yes] [--json]
9
+
10
+ Every Story worktree carries its own `node_modules`, so a worktree left behind
11
+ costs gigabytes. Workflow boot already removes `.worktrees/story-<id>` trees
12
+ whose Story is closed or `agent::done` (the boot sweep in
13
+ [`boot-sweep.js`](../scripts/boot-sweep.js)); `/clean-worktrees` is the
14
+ **recovery tool** for everything that sweep does not own — the backlog, trees
15
+ on non-Story branches, directories git no longer registers, and detached
16
+ trees such as the Claude Code app's `.claude/worktrees/*`.
17
+
18
+ The enumeration, classification and removal live in
19
+ [`clean-worktrees.js`](../scripts/clean-worktrees.js), which documents its own
20
+ flags: `node .agents/scripts/clean-worktrees.js --help`.
21
+
22
+ ## Steps
23
+
24
+ 1. **Preview.** Run `node .agents/scripts/clean-worktrees.js` (dry-run, the
25
+ default). It prints one row per worktree — class, path, size, branch/HEAD,
26
+ action — and removes nothing. Show the operator the table.
27
+ 2. **Confirm.** Ask the operator which candidates to remove. Do not proceed
28
+ on your own judgment.
29
+ 3. **Remove.** Re-run with `--execute`. In a terminal it asks per entry;
30
+ `--execute --yes` removes every non-`detached` candidate without asking.
31
+ `--json` emits the envelope, including `bytesReclaimed`.
32
+
33
+ ## Classes
34
+
35
+ | Class | Candidate when |
36
+ | --- | --- |
37
+ | `closed-story` | `.worktrees/story-<id>` on `story-<id>` whose Story is closed or `agent::done`. |
38
+ | `merged-branch` | Any other branch whose PR is MERGED and whose HEAD is the merged head. |
39
+ | `orphan-dir` | A directory under `.worktrees/` that `git worktree list` does not register. |
40
+ | `detached` | A registered worktree with a detached HEAD. |
41
+
42
+ Everything else is **kept** with its reason: the main checkout, an open Story,
43
+ an unmerged branch, a dirty tree, unpushed commits, a tree in use.
44
+
45
+ ## Constraint
46
+
47
+ > [!WARNING] `--execute` deletes worktree directories. Without it the script
48
+ > only previews.
49
+
50
+ - **Project-scoped.** Only worktrees inside the invoking checkout's project
51
+ root are candidates; one registered elsewhere is reported, never removed.
52
+ - **Unique work survives.** A dirty tree, or a HEAD no remote-tracking ref
53
+ contains, is never removed.
54
+ - **Live trees survive.** The tree this process runs from is never removed;
55
+ on macOS and Linux a tree any live process uses is refused outright.
56
+ - **`detached` needs a person.** A detached tree carries no Story label and a
57
+ live session may own it (a blanket prune once destroyed a live delivery's
58
+ worktree), so it is removed only on a per-entry interactive yes — never
59
+ under `--yes`.
60
+ - **Removal goes through the worktree removal seam** (Windows lock retry and
61
+ the pending-cleanup hand-off), never raw deletion.
62
+ - **Branches are untouched.** Deleting local or remote branches is
63
+ [`/clean-git`](clean-git.md)'s job.
@@ -77,7 +77,7 @@ node .agents/scripts/boot-sweep.js \
77
77
  --current "$(git rev-parse --abbrev-ref HEAD)"
78
78
  ```
79
79
 
80
- The safe subset of the `/git-cleanup` phases: fast-forwards the base branch,
80
+ The safe subset of the `/clean-git` phases: fast-forwards the base branch,
81
81
  prunes stale remote-tracking refs, and reaps merged branches. It never
82
82
  touches the stash, never reaps a candidate with unpushed work / dirty
83
83
  worktree / open parent ticket, and always exits `0` — a failed sweep is
@@ -95,7 +95,7 @@ per-criterion, mid-delivery, and evaluates the actual work product.
95
95
  without being respawned; a stale or absent stamp reports `spawn: true` and
96
96
  the command runs for real. The credited run itself is stated once, in
97
97
  [`deliver-digest.md`](deliver-digest.md) § 5.
98
- + Emits **one** verdict file under `temp/` conforming to
98
+ + Emits **one** verdict file under `temp/scratch/story-<id>/` conforming to
99
99
  [`acceptance-eval-verdict.schema.json`](../../schemas/acceptance-eval-verdict.schema.json):
100
100
  one `{ index, criterion, verdict: met|partial|unmet, evidence,
101
101
  verifyEvidence[] }` record per `acceptance[]` item, in acceptance-array
@@ -137,4 +137,5 @@ per-criterion, mid-delivery, and evaluates the actual work product.
137
137
  (transition to `agent::blocked`) and post a `friction` comment naming the
138
138
  unmet criteria and their evidence. Never silently proceed to close.
139
139
 
140
- Write the verdict under `temp/` only — it is a scratch artifact.
140
+ Write the verdict under `temp/scratch/story-<id>/` only — a scratch artifact
141
+ the Story's landing reaps.
@@ -48,7 +48,7 @@ presence, so re-running init on a partially-initialized Story is idempotent.
48
48
  ### Merged-`story-*` sweep
49
49
 
50
50
  Between the fetch and the branch seed, init runs the same primitive as
51
- `<agentRoot>/scripts/git-cleanup.js` scoped to `story-*` in
51
+ `<agentRoot>/scripts/clean-git.js` scoped to `story-*` in
52
52
  `--execute --remote` mode, excluding this run's `story-<id>`, reaping merged
53
53
  siblings' local refs, `origin/` refs and stale tracking refs in one pass.
54
54
 
@@ -539,7 +539,7 @@ once per project to delete the conflicting bot workflows entirely.
539
539
  > cause), or after a manual merge on a `--no-wait-merge` run:
540
540
 
541
541
  ```bash
542
- node .agents/scripts/git-cleanup.js \
542
+ node .agents/scripts/clean-git.js \
543
543
  --execute \
544
544
  --remote \
545
545
  --yes \
package/docs/CHANGELOG.md CHANGED
@@ -15,6 +15,19 @@ All notable changes to this project will be documented in this file.
15
15
  -->
16
16
  <!-- markdownlint-disable-file MD004 MD012 MD037 -->
17
17
 
18
+ ## [2.67.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.66.0...mandrel-v2.67.0) (2026-09-26)
19
+
20
+
21
+ ### ⚠ BREAKING CHANGES
22
+
23
+ * the /git-cleanup slash command is now /clean-git, and .agents/scripts/git-cleanup.js is now .agents/scripts/clean-git.js. Update any operator scripts or runbooks that invoke the old names.
24
+
25
+ ### Added
26
+
27
+ * add /clean-temp and a reapable scratch layout for agent-authored temp files ([#5459](https://github.com/dsj1984/mandrel/issues/5459)) ([#5464](https://github.com/dsj1984/mandrel/issues/5464)) ([0e9ae9b](https://github.com/dsj1984/mandrel/commit/0e9ae9b7e53ceffc7561bea99f76c60e06bc1169))
28
+ * add /clean-worktrees and re-wire the closed-Story worktree sweep into boot ([#5460](https://github.com/dsj1984/mandrel/issues/5460)) ([#5463](https://github.com/dsj1984/mandrel/issues/5463)) ([bbd946e](https://github.com/dsj1984/mandrel/commit/bbd946e94f636956690f07a8f29ecc64170dce02))
29
+ * rename /git-cleanup to /clean-git ([#5461](https://github.com/dsj1984/mandrel/issues/5461)) ([#5466](https://github.com/dsj1984/mandrel/issues/5466)) ([104c60d](https://github.com/dsj1984/mandrel/commit/104c60d9c0baffece7d30c17ff7520d2f9db112e))
30
+
18
31
  ## [2.66.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.65.0...mandrel-v2.66.0) (2026-09-26)
19
32
 
20
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandrel",
3
- "version": "2.66.0",
3
+ "version": "2.67.0",
4
4
  "description": "Claude Code-first opinionated workflow framework: instructions, skills, rules, and SDLC workflows that govern AI coding assistants.",
5
5
  "files": [
6
6
  ".agents/",