mandrel 2.39.0 → 2.40.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 (28) hide show
  1. package/.agents/README.md +6 -3
  2. package/.agents/agents/auditor.md +5 -0
  3. package/.agents/docs/SDLC.md +21 -12
  4. package/.agents/instructions.md +17 -16
  5. package/.agents/scripts/audit-to-stories.js +510 -66
  6. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +39 -0
  7. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +290 -0
  8. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +94 -3
  9. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +10 -0
  10. package/.agents/scripts/lib/label-constants.js +18 -0
  11. package/.agents/scripts/lib/label-taxonomy.js +18 -5
  12. package/.agents/scripts/lib/orchestration/epic-container.js +186 -0
  13. package/.agents/scripts/lib/orchestration/epic-expansion.js +148 -0
  14. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +320 -0
  15. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +18 -0
  16. package/.agents/scripts/lib/orchestration/run-epilogue.js +130 -1
  17. package/.agents/scripts/plan-persist.js +39 -1
  18. package/.agents/scripts/providers/github/sub-issue-add.js +218 -0
  19. package/.agents/scripts/resolve-stories.js +42 -2
  20. package/.agents/templates/docs/audit-sweep-runbook.md +169 -0
  21. package/.agents/workflows/audit-to-stories.md +85 -7
  22. package/.agents/workflows/helpers/audit-lens-core.md +24 -4
  23. package/.agents/workflows/helpers/deliver-reference.md +8 -0
  24. package/.agents/workflows/helpers/plan-reference.md +28 -0
  25. package/.agents/workflows/mandrel-deliver.md +47 -43
  26. package/.agents/workflows/mandrel-plan.md +44 -38
  27. package/docs/CHANGELOG.md +16 -0
  28. package/package.json +1 -1
package/.agents/README.md CHANGED
@@ -322,9 +322,12 @@ in `runtime-deps.json`.
322
322
  Orchestration and planning are **Story-only** (`type::story`) — `/mandrel-plan`
323
323
  persists Stories with inline `acceptance[]` / `verify[]` and a folded
324
324
  `## Spec`; `/mandrel-deliver` runs `helpers/deliver-story` on `story-<id>` → PR →
325
- `main`. There is no `type::epic` / `type::task` label, Epic issue form, or
326
- `epic/<id>` integration branch; a ticket carrying an `Epic: #N` footer is
327
- refused by `/mandrel-deliver`. The execution-model contract is owned by
325
+ `main`. There is no `type::task` label, Epic issue form, or `epic/<id>`
326
+ integration branch; a ticket carrying an `Epic: #N` footer is refused by
327
+ `/mandrel-deliver`. `type::epic` exists as a **pure container** — a goal plus a
328
+ child checklist, never delivered itself, expanded to its open Stories by
329
+ `/mandrel-deliver <epicId>` — and its linkage is parent→child only, which is
330
+ what keeps that footer refused. The execution-model contract is owned by
328
331
  [`instructions.md` § 5.B](instructions.md) and [`docs/SDLC.md`](docs/SDLC.md).
329
332
 
330
333
  ---
@@ -130,6 +130,11 @@ Record the outcome in the Executive Summary as a single line —
130
130
  `Self-cross-check: kept <k> / dropped <d>.` — and, when `d > 0`, name the
131
131
  dropped findings with their reason. The line's absence is itself a defect.
132
132
 
133
+ Beside it, carry one machine-readable tally of the findings you kept —
134
+ `Severity tally: Critical <n> / High <n> / Medium <n> / Low <n>`, zeros
135
+ included, `Info` never counted. `audit-to-stories` cross-checks that line
136
+ against its parse and refuses a report whose tally is missing or wrong.
137
+
133
138
  ## Fan-out (heavyweight lenses)
134
139
 
135
140
  When your caller dispatches you for a single dimension of a heavyweight lens
@@ -7,12 +7,13 @@ each Story is delivered on its own `story-<id>` branch and reaches `main`
7
7
  through its own PR.
8
8
 
9
9
  An Epic may still exist as an **optional untyped human umbrella issue**
10
- (no `type::epic` label and no shipped Epic issue form only
11
- `.github/ISSUE_TEMPLATE/story.yml`), but **delivery and planning
12
- orchestration are Story-only**: there is no Epic wave loop, no
13
- `epic/<id>` integration branch, no `epic.yaml` reconciler, and any ticket
14
- that still carries an `Epic: #N` footer is **refused** by `/mandrel-deliver`
15
- (close it or re-plan it as a v2 Story).
10
+ (the only shipped issue form is `.github/ISSUE_TEMPLATE/story.yml`), and
11
+ **delivery and planning orchestration are Story-only**: there is no Epic
12
+ wave loop, no `epic/<id>` integration branch, no `epic.yaml` reconciler,
13
+ and any ticket that still carries an `Epic: #N` footer is **refused** by
14
+ `/mandrel-deliver` (close it or re-plan it as a v2 Story). `type::epic`
15
+ exists as a **container only** a grouping ticket with no execution
16
+ payload, expanded to its children at delivery (ADR `20260905-5139`).
16
17
 
17
18
  The framework is **Claude Code-first**: `.claude/`, hooks, skills, and
18
19
  the slash-command surface lean in on Claude Code as the reference
@@ -247,9 +248,10 @@ self-eval, ceremony, close, CI watch, confirm-merge, cleanup) lives in the
247
248
 
248
249
  The single operator-facing entry point is `/mandrel-deliver`. It performs no
249
250
  git/label mutations itself — `deliver-story` owns every script invocation
250
- per Story. Any ticket that is not `type::story`, or that still carries an
251
- `Epic: #N` reference, is a hard error naming the ID and the fix (close or
252
- re-plan as a v2 Story).
251
+ per Story. A `type::epic` id expands to its open child Stories before
252
+ resolution. Any ticket that is neither of those two types, or that still
253
+ carries an `Epic: #N` reference, is a hard error naming the ID and the fix
254
+ (close or re-plan as a v2 Story).
253
255
 
254
256
  ### Branch model (authoritative)
255
257
 
@@ -560,9 +562,15 @@ Editing the main checkout's `.agentrc.json` only affects **the next**
560
562
 
561
563
  ### `Epic: #N` refusal
562
564
 
563
- `/mandrel-deliver` refuses any ticket that still carries an `Epic: #N` footer or is
564
- not `type::story`. This is expected — v2 has no Epic delivery path. Close
565
- the ticket or re-plan the work as a v2 Story via `/mandrel-plan --tickets <id>`.
565
+ `/mandrel-deliver` refuses any ticket that still carries an `Epic: #N` footer,
566
+ or that is neither `type::story` nor `type::epic`. This is expected — v2 has
567
+ no Epic *delivery* path. Close the ticket or re-plan the work as a v2 Story
568
+ via `/mandrel-plan --tickets <id>`.
569
+
570
+ The container Epic (ADR `20260905-5139`) does **not** soften this. Its linkage
571
+ runs parent→child only — the Epic body lists its children, and no Story body
572
+ ever gains a footer pointing back — so a ticket carrying `Epic: #N` is still a
573
+ v1 ticket and still refused.
566
574
 
567
575
  ---
568
576
 
@@ -573,6 +581,7 @@ the ticket or re-plan the work as a v2 Story via `/mandrel-plan --tickets <id>`.
573
581
  | `npx mandrel init` | Cold-start — install `mandrel` (if absent), `mandrel sync`, `bootstrap.js` (provisions repo + Projects V2 board, labels, branch protection), then the onboarding tail (stack detection, docs scaffolding, doctor gate, `/mandrel-plan` handoff). |
574
582
  | `/mandrel-plan --seed "<text>"` | Plan from chat text — interrogate → author **one Story by default** → persist `type::story`. |
575
583
  | `/mandrel-plan --seed-file <path>` | Plan from on-disk notes / a plan seed (the `/audit-to-stories` handoff). |
584
+ | `/mandrel-deliver <epicId>` | Deliver every open Story under a container Epic — the id expands before resolution. |
576
585
  | `/mandrel-plan --tickets <ids>` | Analyze existing issue(s) into proper Stories (prefer an N=1 rewrite). |
577
586
  | `/mandrel-deliver <storyId>` | Deliver one Story via `helpers/deliver-story` — `story-<id>` → PR → `main`. |
578
587
  | `/mandrel-deliver <storyId> [<storyId>…]` | Deliver multiple Stories in `depends_on` order (resolved from live state), then run the per-run epilogue. |
@@ -147,9 +147,9 @@ sizing) **fail closed** naming what to trim:
147
147
  spawn only when the work justifies replicating context. One objective
148
148
  per subagent; depth compounds the cost (every nested level re-pays).
149
149
  - **Anti-Laziness / No Dead Code.** NEVER use placeholder comments like
150
- `// ... existing code ...`; every edit must leave complete, runnable
151
- code. Remove unused imports, commented-out code, and dead branches
152
- before finalizing.
150
+ `// ... existing code ...`; every edit must leave complete, runnable code.
151
+ Remove unused imports, commented-out code, and dead branches before
152
+ finalizing.
153
153
  - **Verification.** Include explicit verification steps in every plan.
154
154
 
155
155
  ---
@@ -157,28 +157,29 @@ sizing) **fail closed** naming what to trim:
157
157
  ## 5. Git & Story Protocol (Strict Standards)
158
158
 
159
159
  [`rules/git-conventions.md`](rules/git-conventions.md) is the canonical
160
- reference: `story-<storyId>` branches seeded by `single-story-init.js`,
161
- every Story reaching `main` via its own PR
162
- (`helpers/deliver-story` / `single-story-close.js`).
160
+ reference for branch shapes and commit subjects, and is always loaded —
161
+ this section does not restate it.
163
162
 
164
163
  ### A. Status Tracking & Commit Standards
165
164
 
166
165
  State mutations are GitHub labels (`agent::ready`, `agent::executing`,
167
166
  `agent::done`) via
168
167
  `node .agents/scripts/update-ticket-state.js --ticket [ID] --state [STATUS]`.
169
- Do NOT manually update issue descriptions or status fields unless
170
- prompted.
168
+ Do NOT manually update issue descriptions or status fields unless prompted.
171
169
 
172
- ### B. Ticket hierarchy (Story-only)
170
+ ### B. Ticket hierarchy
173
171
 
174
- The v2 ticket model is Story-only: `acceptance[]` / `verify[]` live
172
+ The Story is the only executable ticket: `acceptance[]` / `verify[]`
175
173
  inline plus the folded Tech Spec in `## Spec` (over-budget Specs fail
176
- closed — split or tighten; never write Specs under `docs/`). Optional
177
- `depends_on` edges order rare multi-Story runs, resolved by `/mandrel-deliver`
178
- from live state; the `plan-run::<id>` label is filter metadata only.
179
- Commit subjects reference the Story via `(refs #<storyId>)`. There is no
180
- `type::epic` / `type::task` label; `/mandrel-deliver` refuses tickets carrying an
181
- `Epic: #N` footer.
174
+ closed — split or tighten; never under `docs/`). Optional `depends_on`
175
+ edges order rare multi-Story runs, resolved by `/mandrel-deliver` from
176
+ live state; `plan-run::<id>` is filter metadata. Commit subjects
177
+ reference the Story via `(refs #<storyId>)`. There is no `type::task`.
178
+
179
+ `type::epic` is a container only (goal + child checklist, no `agent::*`,
180
+ never delivered): `/mandrel-plan` offers one above 2 Stories and
181
+ `/mandrel-deliver <epicId>` expands it. Linkage is parent→child only, so
182
+ an `Epic: #N` footer is still refused.
182
183
 
183
184
  ---
184
185