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.
- package/.agents/agents/acceptance-critic.md +2 -2
- package/.agents/docs/agentrc-reference.json +2 -1
- package/.agents/docs/configuration.md +2 -1
- package/.agents/docs/workflows.md +4 -2
- package/.agents/instructions.md +2 -1
- package/.agents/rules/git-conventions-reference.md +5 -5
- package/.agents/rules/git-conventions.md +1 -1
- package/.agents/schemas/agentrc.schema.json +6 -1
- package/.agents/scripts/boot-sweep.js +97 -9
- package/.agents/scripts/{git-cleanup.js → clean-git.js} +2 -2
- package/.agents/scripts/clean-temp.js +54 -0
- package/.agents/scripts/clean-worktrees.js +593 -0
- package/.agents/scripts/drain-pending-cleanup.js +5 -4
- package/.agents/scripts/lib/clean-temp.js +440 -0
- package/.agents/scripts/lib/config-settings-schema-delivery.js +11 -2
- package/.agents/scripts/lib/generated/agentrc-validator.js +1 -1
- package/.agents/scripts/lib/observability/source-classifier.js +3 -1
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +149 -97
- package/.agents/scripts/lib/single-story-sweep.js +2 -2
- package/.agents/scripts/lib/temp-removal.js +110 -0
- package/.agents/scripts/lib/temp-retention.js +122 -73
- package/.agents/scripts/lib/worktree/canonical-path.js +34 -0
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +15 -4
- package/.agents/scripts/single-story-init.js +120 -17
- package/.agents/workflows/{git-cleanup.md → clean-git.md} +10 -10
- package/.agents/workflows/clean-temp.md +67 -0
- package/.agents/workflows/clean-worktrees.md +63 -0
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +3 -2
- package/.agents/workflows/helpers/deliver-story-reference.md +2 -2
- package/docs/CHANGELOG.md +13 -0
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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