mandrel 1.85.0 โ†’ 1.87.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 (41) hide show
  1. package/.agents/instructions.md +7 -0
  2. package/.agents/rules/git-conventions.md +45 -0
  3. package/.agents/scripts/boot-sweep.js +215 -0
  4. package/.agents/scripts/epic-deliver-prepare.js +55 -0
  5. package/.agents/scripts/git-cleanup.js +8 -0
  6. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +107 -30
  7. package/.agents/scripts/lib/epic-plan-ideation.js +24 -3
  8. package/.agents/scripts/lib/framework-version.js +210 -0
  9. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +7 -22
  10. package/.agents/scripts/lib/orchestration/epic-cleanup.js +330 -6
  11. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +34 -3
  12. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +102 -7
  13. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +83 -30
  14. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +85 -1
  15. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +34 -3
  16. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +71 -4
  17. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +8 -3
  18. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +54 -6
  19. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +35 -4
  20. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +75 -0
  21. package/.agents/scripts/lib/single-story-sweep.js +239 -57
  22. package/.agents/scripts/lib/story-body/story-body.js +81 -4
  23. package/.agents/scripts/providers/github/tickets.js +18 -1
  24. package/.agents/scripts/single-story-init.js +7 -51
  25. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +7 -2
  26. package/.agents/skills/core/epic-plan-premortem/SKILL.md +8 -2
  27. package/.agents/skills/skills.index.json +3 -3
  28. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +36 -8
  29. package/.agents/workflows/git-cleanup.md +72 -18
  30. package/.agents/workflows/git-deliver.md +36 -0
  31. package/.agents/workflows/helpers/acceptance-self-eval.md +23 -1
  32. package/.agents/workflows/helpers/deliver-epic-reference.md +19 -13
  33. package/.agents/workflows/helpers/deliver-epic.md +47 -3
  34. package/.agents/workflows/helpers/deliver-stories.md +16 -3
  35. package/.agents/workflows/helpers/epic-audit.md +60 -2
  36. package/.agents/workflows/helpers/parallel-tooling.md +9 -2
  37. package/.agents/workflows/helpers/plan-epic.md +32 -14
  38. package/.agents/workflows/loops/nightly-audit.md +9 -1
  39. package/.agents/workflows/plan.md +32 -4
  40. package/docs/CHANGELOG.md +27 -0
  41. package/package.json +1 -1
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  description: >-
3
3
  Run smart change-set audits at Epic finalize. Consumes the epic-audit-prepare
4
- envelope, dispatches each selected lens inline via runAuditSuite, and posts
5
- an audit-results structured comment back onto the Epic ticket.
4
+ envelope, dispatches each selected lens (inline, or via a single
5
+ audit-orchestrator sub-agent that fans the lenses out as parallel level-2
6
+ agents) through runAuditSuite, and posts an audit-results structured comment
7
+ back onto the Epic ticket.
6
8
  ---
7
9
 
8
10
  # Epic Audit (helper)
@@ -197,6 +199,62 @@ After the runner returns:
197
199
  ๐ŸŸก Medium / ๐ŸŸข Suggestion). Hold the aggregate for Step 3
198
200
  (auto-fix) and Step 4 (the `audit-results` structured comment).
199
201
 
202
+ ### Optional: delegate the roster walk to an audit-orchestrator sub-agent
203
+
204
+ The Step 2 loop above walks the `selectedAudits` roster **serially in the
205
+ host's own context**. When the roster carries more than one lens, `/deliver`
206
+ Phase 4 MAY instead delegate the whole walk to a **single audit-orchestrator
207
+ sub-agent** โ€” one level-1 `Agent` call (`subagent_type: general-purpose`) โ€” that:
208
+
209
+ 1. Receives the **already-selected** `selectedAudits` roster, the run's
210
+ `depth`, and the prepare envelope's substitution payload. It does **not**
211
+ re-run `selectAudits` and does **not** widen the roster โ€” the roster is
212
+ fixed upstream by Step 1 (see the Constraints below).
213
+ 2. Fans the roster out as **parallel level-2 agents, one per lens** (nested
214
+ `Agent` dispatch โ€” verified depth 2, announced max depth 5, per
215
+ [#2870](https://github.com/dsj1984/mandrel/issues/2870) and the
216
+ "Flat Story dispatch by design" note in
217
+ [`deliver-epic.md`](deliver-epic.md)). Each level-2 agent executes exactly
218
+ one lens's workflow procedure at the run's `depth`, isolated from the main
219
+ context.
220
+ 3. Collects the per-lens findings, **aggregates them by severity** (๐Ÿ”ด / ๐ŸŸ  /
221
+ ๐ŸŸก / ๐ŸŸข), and returns **only the aggregated audit-results** to the host โ€”
222
+ the per-lens reasoning transcripts stay in the level-2 leaves and never
223
+ enter the main context. The host resumes at Step 3 (remediation routing)
224
+ with the aggregate exactly as if it had walked the roster itself, and Step 4
225
+ posts the identical `audit-results` comment.
226
+
227
+ This delegation is a **cross-lens parallelization of the roster walk only**. It
228
+ is orthogonal to โ€” and MUST NOT be conflated with โ€” the *per-lens execution
229
+ strategy*:
230
+
231
+ - **The per-lens cost/precision gate is preserved.** Each level-2 lens agent
232
+ still runs its own lens at whatever strategy that lens's cost/precision gate
233
+ dictates (`docs/roadmap.md` ยง "The per-lens cost / precision gate"): an
234
+ orchestrated lens fans its own analysis dimensions out under
235
+ `runAuditOrchestration`, a sequential-only lens runs turn-by-turn. Fanning
236
+ the *roster* out in parallel changes **which context** runs a lens, never
237
+ **how** that lens runs internally, so no per-lens cost gate is bypassed or
238
+ altered.
239
+ - **The "do not batch-convert the sequential-only lenses" rule is preserved.**
240
+ The seven sequential-only lenses (`audit-dependencies`, `audit-devops`,
241
+ `audit-sre`, `audit-privacy`, `audit-seo`, `audit-ux-ui`,
242
+ `audit-lighthouse`) stay sequential **inside** their level-2 agent.
243
+ Dispatching them as parallel level-2 agents is **not** a batch-conversion of
244
+ their internal execution โ€” a sequential-only lens remains sequential-only
245
+ (`docs/roadmap.md` ยง "Remaining orchestration surface"). Generalizing any of
246
+ those lenses to orchestrated is still a separate, gated, lens-by-lens
247
+ decision that this roster fan-out neither performs nor pre-empts.
248
+
249
+ Weigh the whole subtree's token cost before delegating
250
+ ([`.agents/instructions.md` ยง 4](../../instructions.md) โ€” cost compounds with
251
+ nesting depth): the level-1 orchestrator plus one level-2 agent per lens
252
+ re-pays the always-loaded context at each level. For a single-lens roster the
253
+ serial host walk is cheaper; the delegation pays off when several lenses fan
254
+ out at once. Either path produces the identical Step 4 `audit-results` comment,
255
+ so the delegation is a performance/context-isolation choice, never a change to
256
+ what gets audited or reported.
257
+
200
258
  If a future Story lifts per-lens execution out of the host-LLM walk
201
259
  into the CLI itself, the runner will populate `findings[]` and this
202
260
  section will collapse to a "read the structured findings off the
@@ -76,8 +76,15 @@ If a unit of work is both long (Rule 2) and independent (Rule 1 or 3),
76
76
  prefer the higher-numbered rule โ€” the parallelism gain compounds the
77
77
  background-shell gain. Concretely: dispatch the `Agent` calls in one turn
78
78
  (Rule 3), and **inside** each sub-agent let it apply Rule 2 to its own
79
- long-running shells. The host does not need to micromanage the child's
80
- shell strategy.
79
+ long-running shells โ€” and, within the supported nesting depth budget
80
+ (verified depth 2, announced max depth 5; see
81
+ [#2870](https://github.com/dsj1984/mandrel/issues/2870)), let it apply
82
+ **Rule 3** to its own independent sub-units as well, not only Rule 2
83
+ background shells. A sub-agent is a full orchestrator at its own level:
84
+ recursive `Agent` fan-out is available to it, so the host does not need to
85
+ micromanage the child's shell **or** dispatch strategy. Mind the depth
86
+ budget and the compounding cost โ€” every nesting level re-pays the
87
+ always-loaded context (see [`instructions.md` ยง 4](../../instructions.md)).
81
88
 
82
89
  ## Constraints
83
90
 
@@ -683,26 +683,36 @@ node .agents/scripts/epic-plan-spec-validate.js \
683
683
 
684
684
  3. **Phase 8.3 โ€” Holistic Consolidation (HITL diff gate)**: After the
685
685
  draft `temp/epic-[Epic_ID]/tickets.json` exists and **before** the persist
686
- call below, activate the
686
+ call below, **dispatch a genuine fresh-context sub-agent** (`Agent` tool,
687
+ `subagent_type: general-purpose`) whose task is to read the
687
688
  [`epic-plan-consolidate`](../../skills/core/epic-plan-consolidate/SKILL.md)
688
- skill with `[Epic_ID]` as input. This is a **separate critic pass with
689
- fresh context** (not a self-review appended to the author skill): it reads
690
- the draft array plus the Epic body (which carries the Tech Spec
691
- sections), reconciles the draft against
689
+ skill and execute its procedure with `[Epic_ID]` as input. Dispatching the critic
690
+ as a sub-agent โ€” **not** activating the skill inline in your authoring
691
+ turn โ€” is what makes it a **separate critic pass with fresh context**: the
692
+ sub-agent does not inherit the conversation that authored the draft, so it
693
+ cannot grade its own homework (the same nested-dispatch mechanic the
694
+ acceptance self-eval loop uses, now that the sub-agent depth limit is
695
+ lifted โ€” see [`.agents/instructions.md` ยง 4](../../instructions.md)). The
696
+ sub-agent reads the draft array plus the Epic body (which carries the Tech
697
+ Spec sections), reconciles the draft against
692
698
  the Tech Spec `## Delivery Slicing` target, and emits a **consolidated**
693
699
  `tickets.json` plus a human-readable
694
700
  `temp/epic-[Epic_ID]/consolidation-report.md`. Its operations are
695
701
  scope-preserving only โ€” **merge sibling Stories and rewire
696
702
  `depends_on`** โ€” and it MUST NOT add scope or invent tickets; it
697
703
  consolidates fragmented slices by merging them into a cohesive Story,
698
- never by splitting one. It runs **before** the deterministic
704
+ never by splitting one. The sub-agent **never writes to GitHub**: it emits
705
+ only the two temp artifacts and returns control to this operator session.
706
+ It runs **before** the deterministic
699
707
  validator (step 7), so the validator re-checks its output and the critic
700
708
  cannot emit an invalid plan.
701
709
 
702
710
  **Show the operator the consolidation report (the before/after diff +
703
- rationale) before persisting.** Consolidation is never auto-applied without
704
- review: on operator approval, persist the consolidated `tickets.json`; on
705
- rejection, persist the draft instead. This is a sub-step of Phase 8 โ€” it
711
+ rationale) before persisting.** The HITL diff-confirm and the persist call
712
+ both run here in the **operator session**, never inside the sub-agent โ€”
713
+ consolidation is never auto-applied without review: on operator approval,
714
+ persist the consolidated `tickets.json`; on rejection, persist the draft
715
+ instead. This is a sub-step of Phase 8 โ€” it
706
716
  does **not** renumber the top-level lifecycle phases (9โ€“12).
707
717
 
708
718
  4. **Phase 8.4 โ€” Reachability Completeness Critic (HITL diff gate, F6)**:
@@ -742,11 +752,17 @@ node .agents/scripts/epic-plan-spec-validate.js \
742
752
  invalid addition cannot reach GitHub.
743
753
 
744
754
  5. **Phase 8.5 โ€” Planning Pre-Mortem Critic (code-reading, F9)**: After the
745
- reachability critic (8.4) and **before** the persist call below, activate the
755
+ reachability critic (8.4) and **before** the persist call below, **dispatch a
756
+ genuine fresh-context sub-agent** (`Agent` tool,
757
+ `subagent_type: general-purpose`) whose task is to read the
746
758
  [`epic-plan-premortem`](../../skills/core/epic-plan-premortem/SKILL.md)
747
- skill with `[Epic_ID]` as input. This is a **fresh-context critic** sibling
748
- to `epic-plan-consolidate`: it reads the drafted `tickets.json`, the Epic
749
- body (with its folded Tech Spec sections), **and the actual cited code
759
+ skill and execute its procedure with `[Epic_ID]` as input. Like the 8.3
760
+ consolidate pass, dispatching the critic as a sub-agent โ€” **not** activating
761
+ the skill inline in your authoring turn โ€” is what makes it a genuine
762
+ **fresh-context critic** sibling to `epic-plan-consolidate`: the sub-agent
763
+ does not inherit the authoring conversation, so its code-reading review is
764
+ independent of the draft it grades. It reads the drafted `tickets.json`, the
765
+ Epic body (with its folded Tech Spec sections), **and the actual cited code
750
766
  surfaces** (the files each Story's
751
767
  `changes[]` / `references[]` name), then emits predicted-rework findings โ€”
752
768
  unverifiable acceptance criteria, over- or under-specified Stories, and
@@ -756,7 +772,9 @@ node .agents/scripts/epic-plan-spec-validate.js \
756
772
  Unlike the consolidate critic it is **not** scope-preserving-only: it may
757
773
  recommend splitting an under-specified Story or tightening an AC. But it
758
774
  **never writes to GitHub** and never persists `tickets.json` โ€” it only emits
759
- the report. Its findings are shown in the **same Phase 8 HITL diff**, and on
775
+ the report and returns control to this operator session. Its findings are
776
+ shown in the **same Phase 8 HITL diff** (which stays in the operator
777
+ session), and on
760
778
  operator approval the author re-runs (Step 2) on the findings **before** the
761
779
  persist call. The critic runs **before** the deterministic validator (step
762
780
  7), so the persist below is the single GitHub write for the whole phase.
@@ -32,7 +32,15 @@ Each scheduled run:
32
32
  (`/audit-security`, `/audit-clean-code`, `/audit-dependencies`,
33
33
  `/audit-quality`, and any others the project relies on). Each audit writes a
34
34
  structured `temp/audits/audit-*-results.md` report โ€” that is the canonical
35
- artifact this loop consumes, not free-form prose.
35
+ artifact this loop consumes, not free-form prose. Because these audits are
36
+ **independent** of one another, a scheduled run **may fan them out to
37
+ parallel sub-agents** (one per audit) rather than walking them serially โ€”
38
+ the same cross-lens parallelization `/deliver` Phase 4 uses (see
39
+ [`../helpers/epic-audit.md` ยง "Optional: delegate the roster walk to an
40
+ audit-orchestrator sub-agent"](../helpers/epic-audit.md)). Each sub-agent
41
+ returns only its structured report; the scheduler/host owns the fan-out just
42
+ as it owns the cadence, and each per-audit strategy (sequential or
43
+ orchestrated) is unchanged by running under its own sub-agent.
36
44
  2. **Diff against the prior night.** Compare the fresh findings against the last
37
45
  sweep's reports and against already-open Issues. A finding seen before is
38
46
  not new signal; only genuinely fresh or regressed findings warrant a record.
@@ -124,6 +124,30 @@ are operator-input waits, not validators. The two *named* HITL STOP gates the
124
124
  Story tracks (gate #1, gate #2) are the load-bearing pair; these additional
125
125
  waits are auto-proceeded for the same headless reason.
126
126
 
127
+ ## Boot sweep
128
+
129
+ Before anything else โ€” ahead of the first-run preflight โ€” run the **protected
130
+ boot sweep** so `/plan` opens against a tidy local checkout instead of one
131
+ still carrying the merged refs of the last delivered Epic or Story:
132
+
133
+ ```bash
134
+ node .agents/scripts/boot-sweep.js \
135
+ --include 'story-*' --include 'epic/*' \
136
+ --include 'feat/*' --include 'fix/*' --include 'chore/*'
137
+ ```
138
+
139
+ This is the **safe subset** of the `/git-cleanup` phases: it fast-forwards the
140
+ base branch (`main`), prunes stale remote-tracking refs, and reaps every local
141
+ branch whose PR is **merged** and whose HEAD matches the merged `headRefOid`.
142
+ It **never** touches the stash stack, and its `evaluateProtection` partition
143
+ skips (never reaps) any candidate with unpushed work, a dirty worktree, or a
144
+ still-open parent Story ticket โ€” so it is safe to run unattended at the top of
145
+ a planning session. The sweep is **silent on a no-op**: with nothing to reap
146
+ and `main` already current it prints a single summary line
147
+ (`[boot-sweep] reaped 0 local + 0 remote; protected 0.`) and moves on. Its exit
148
+ code is always `0` โ€” a failed sweep is swallowed and reported in the summary,
149
+ never allowed to fail the planning run.
150
+
127
151
  ## First-run preflight
128
152
 
129
153
  Before routing to a path helper, run a **first-run preflight** to catch
@@ -169,18 +193,22 @@ stubbed docs, or an unready doctor verdict).
169
193
  1. **Parse args.** Exactly one of `<epicId>`, `--idea`, `--from-notes`, or
170
194
  `--body` must be present; anything else is a usage error naming the four
171
195
  forms. A `--body` invocation routes to the story path (no triage).
172
- 2. **First-run preflight.** Run the preflight above. Skip when all signals
196
+ 2. **Boot sweep.** Run the protected boot sweep above
197
+ (`node .agents/scripts/boot-sweep.js โ€ฆ`) to fast-forward `main`, prune
198
+ stale remotes, and reap merged-PR branches. Silent on a no-op; never fails
199
+ the run.
200
+ 3. **First-run preflight.** Run the preflight above. Skip when all signals
173
201
  are clear (healthy project).
174
- 3. **Triage (idea path only).** Run the
202
+ 4. **Triage (idea path only).** Run the
175
203
  [`core/scope-triage`](../skills/core/scope-triage/SKILL.md) skill on the
176
204
  seed. Record the verdict in chat (one line).
177
- 4. **Delegate.** Read the selected path helper **in full** and execute it
205
+ 5. **Delegate.** Read the selected path helper **in full** and execute it
178
206
  from its entry phase, forwarding the absorbed flags (including `--yes`).
179
207
  The helper's phase numbering, HITL gates, and scripts are unchanged โ€” this
180
208
  router adds no phase content. When `--yes` is present, the two HITL STOP
181
209
  gates auto-proceed per [Headless / non-interactive mode](#headless--non-interactive-mode---yes)
182
210
  above; every deterministic gate still runs.
183
- 5. **Internal returns.** When a path helper would historically have handed
211
+ 6. **Internal returns.** When a path helper would historically have handed
184
212
  off to the other planning command, switch helpers in-place and continue;
185
213
  surface the switch to the operator as a one-line note.
186
214
 
package/docs/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.87.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.86.0...mandrel-v1.87.0) (2026-07-08)
6
+
7
+
8
+ ### Added
9
+
10
+ * **boot-sweep:** report content-merged branches and align sweep docs ([#4396](https://github.com/dsj1984/mandrel/issues/4396)) ([#4398](https://github.com/dsj1984/mandrel/issues/4398)) ([8c9c938](https://github.com/dsj1984/mandrel/commit/8c9c938d34c0bcbdaeb607f5a148261925a58622))
11
+ * Epic [#4385](https://github.com/dsj1984/mandrel/issues/4385) ([#4392](https://github.com/dsj1984/mandrel/issues/4392)) ([0999dca](https://github.com/dsj1984/mandrel/commit/0999dcac00a708bca0d1a9664f46d8f79c9ffe11))
12
+ * **git-cleanup:** detect content-merged branches and surface silent skips (refs [#4395](https://github.com/dsj1984/mandrel/issues/4395)) ([#4397](https://github.com/dsj1984/mandrel/issues/4397)) ([a5ddabf](https://github.com/dsj1984/mandrel/commit/a5ddabf41f25a75cb5b63e0f51ed05e8dcfcf81d))
13
+ * **planning:** stamp authoring Mandrel version onto Epic and Story bodies (refs [#4382](https://github.com/dsj1984/mandrel/issues/4382)) ([#4383](https://github.com/dsj1984/mandrel/issues/4383)) ([db3de0a](https://github.com/dsj1984/mandrel/commit/db3de0a9302a8f3aa97b06ad74af04879aaba53a))
14
+
15
+
16
+ ### Fixed
17
+
18
+ * branchCleaner false-blocks a successfully-merged Epic when local branches are already reaped ([#4393](https://github.com/dsj1984/mandrel/issues/4393)) ([#4394](https://github.com/dsj1984/mandrel/issues/4394)) ([83a5604](https://github.com/dsj1984/mandrel/commit/83a5604b55aab470d9c4c08ee9d66b4b181af81a))
19
+
20
+ ## [1.86.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.85.0...mandrel-v1.86.0) (2026-07-07)
21
+
22
+
23
+ ### Added
24
+
25
+ * Epic [#4372](https://github.com/dsj1984/mandrel/issues/4372) ([#4376](https://github.com/dsj1984/mandrel/issues/4376)) ([98a82a4](https://github.com/dsj1984/mandrel/commit/98a82a4c27e5eafdfa2f1c54cfb42ed537a69a2e))
26
+
27
+
28
+ ### Fixed
29
+
30
+ * **baselines:** repair check-baselines auto-refresh + dedupe FF probes ([#4380](https://github.com/dsj1984/mandrel/issues/4380)) ([20a4ecd](https://github.com/dsj1984/mandrel/commit/20a4ecd97f92cb6a88be474c321b139fed95db56)), closes [#4379](https://github.com/dsj1984/mandrel/issues/4379)
31
+
5
32
  ## [1.85.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.84.0...mandrel-v1.85.0) (2026-07-06)
6
33
 
7
34
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandrel",
3
- "version": "1.85.0",
3
+ "version": "1.87.0",
4
4
  "description": "Claude Code-first opinionated workflow framework: instructions, personas, skills, and SDLC workflows that govern AI coding assistants.",
5
5
  "files": [
6
6
  ".agents/",