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.
- package/.agents/README.md +6 -3
- package/.agents/agents/auditor.md +5 -0
- package/.agents/docs/SDLC.md +21 -12
- package/.agents/instructions.md +17 -16
- package/.agents/scripts/audit-to-stories.js +510 -66
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +39 -0
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +290 -0
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +94 -3
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +10 -0
- package/.agents/scripts/lib/label-constants.js +18 -0
- package/.agents/scripts/lib/label-taxonomy.js +18 -5
- package/.agents/scripts/lib/orchestration/epic-container.js +186 -0
- package/.agents/scripts/lib/orchestration/epic-expansion.js +148 -0
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +320 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +18 -0
- package/.agents/scripts/lib/orchestration/run-epilogue.js +130 -1
- package/.agents/scripts/plan-persist.js +39 -1
- package/.agents/scripts/providers/github/sub-issue-add.js +218 -0
- package/.agents/scripts/resolve-stories.js +42 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +169 -0
- package/.agents/workflows/audit-to-stories.md +85 -7
- package/.agents/workflows/helpers/audit-lens-core.md +24 -4
- package/.agents/workflows/helpers/deliver-reference.md +8 -0
- package/.agents/workflows/helpers/plan-reference.md +28 -0
- package/.agents/workflows/mandrel-deliver.md +47 -43
- package/.agents/workflows/mandrel-plan.md +44 -38
- package/docs/CHANGELOG.md +16 -0
- package/package.json +1 -1
|
@@ -7,14 +7,14 @@ description:
|
|
|
7
7
|
|
|
8
8
|
# /mandrel-plan
|
|
9
9
|
|
|
10
|
-
> **Lean spine.** Happy path + gate list; edge-case detail
|
|
10
|
+
> **Lean spine.** Happy path + gate list; edge-case detail is on demand in
|
|
11
11
|
> [`helpers/plan-reference.md`](helpers/plan-reference.md).
|
|
12
12
|
|
|
13
13
|
## Inputs
|
|
14
14
|
|
|
15
15
|
Single planning path — there is no Epic/Story router, no scope-triage
|
|
16
|
-
`epic|story` verdict
|
|
17
|
-
it, act**:
|
|
16
|
+
`epic|story` verdict (Gate #3's container groups, never routes). **Derive the
|
|
17
|
+
mode from what the operator typed, announce it, act**:
|
|
18
18
|
|
|
19
19
|
| Invocation | Mode | Behavior |
|
|
20
20
|
| --- | --- | --- |
|
|
@@ -25,9 +25,9 @@ it, act**:
|
|
|
25
25
|
| `/mandrel-plan 4712`, already delivered | amends | Amend a shipped Story from a **delta envelope**, not a re-interrogation. |
|
|
26
26
|
|
|
27
27
|
**Resolving a bare id.** Read live state rather than asking: `agent::done` can
|
|
28
|
-
only be amended, an open unplanned issue
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
only be amended, an open unplanned issue only planned. **Announce the derivation** —
|
|
29
|
+
"4712 is `agent::done` → amending". Ask **only** for an open Story already at
|
|
30
|
+
`agent::ready`.
|
|
31
31
|
|
|
32
32
|
## Saying what you want
|
|
33
33
|
|
|
@@ -36,7 +36,7 @@ No flags to remember — state intent; the workflow fills in the CLI
|
|
|
36
36
|
|
|
37
37
|
`--yes` is **runner-set, never operator-typed** — cron, `/loop`, and headless
|
|
38
38
|
dispatch set it to mean *nobody is at the keyboard*, which auto-proceeds the
|
|
39
|
-
gates below (#1 and #2). Never offer it to an operator
|
|
39
|
+
gates below (#1 and #2) and skips #3. Never offer it to an operator.
|
|
40
40
|
|
|
41
41
|
## Default-single split policy
|
|
42
42
|
|
|
@@ -62,46 +62,44 @@ and derives source ids from its `sourceTickets[]`; the CLI also writes
|
|
|
62
62
|
The envelope carries docs context, the story-author prompt, `sourceTickets[]`,
|
|
63
63
|
`duplicates[]` (open **Stories**, never Epics) and advisory `complexitySignals`
|
|
64
64
|
(**no routing authority**). A trivial scope can claim the lite route at
|
|
65
|
-
persist — shape-validated, failing closed to `full`
|
|
66
|
-
([detail](helpers/plan-reference.md)).
|
|
65
|
+
persist — shape-validated, failing closed to `full` ([detail](helpers/plan-reference.md)).
|
|
67
66
|
|
|
68
67
|
**Triage each unknown by resolver** ([detail](helpers/plan-reference.md)): an
|
|
69
68
|
**AFK** unknown (research settles it) is resolved before authoring, never
|
|
70
|
-
assumed; a **HITL** unknown
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
decision-made-by-default.
|
|
69
|
+
assumed; a **HITL** unknown goes to Gate #1. Under `--yes` do not ask free-form
|
|
70
|
+
operator questions — AFK unknowns are still researched; only HITL unknowns land
|
|
71
|
+
in Key Assumptions, each a decision-made-by-default.
|
|
74
72
|
|
|
75
73
|
**Gate #1** — STOP to confirm the sharpened plan intent and any
|
|
76
74
|
duplicate-candidate review. Under `--yes`, auto-proceed.
|
|
77
75
|
|
|
78
|
-
On a truthy `memoryPoolAdvisory.recommend`, name
|
|
79
|
-
|
|
76
|
+
On a truthy `memoryPoolAdvisory.recommend`, name
|
|
77
|
+
[`/memory-consolidate`](memory-consolidate.md) quoting its `reasons[]` —
|
|
78
|
+
advisory, never invoked here.
|
|
80
79
|
|
|
81
80
|
On a truthy `deliverLightSuggestion.suggested`, offer — advisory, never an
|
|
82
|
-
automatic reroute — to deliver the seed instead; on confirm
|
|
81
|
+
automatic reroute — to deliver the seed instead; on confirm route **in this
|
|
83
82
|
session** into [`helpers/deliver-light.md`](helpers/deliver-light.md), its gate
|
|
84
|
-
filled from this envelope. A truthy `complexitySignals.uiSurface`
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
filled from this envelope. A truthy `complexitySignals.uiSurface` names
|
|
84
|
+
[`/prototype`](prototype.md) as an option; never invoke it here.
|
|
85
|
+
[Both offers](helpers/plan-reference.md).
|
|
87
86
|
|
|
88
87
|
### 2. Author
|
|
89
88
|
|
|
90
89
|
**One-shot authoring.** Start from `stories.template.json`; author
|
|
91
90
|
`stories.json` in one pass. `body` is markdown **or** a structured object;
|
|
92
91
|
persist parses either, serializes canonical markdown and syncs top-level
|
|
93
|
-
`acceptance[]` / `verify[]`
|
|
92
|
+
`acceptance[]` / `verify[]` in — never dual-author those lists.
|
|
94
93
|
|
|
95
94
|
**Grounding = your reads + Phase 8.** Nothing inventories the repo: read each
|
|
96
|
-
file you cite; persist
|
|
97
|
-
|
|
98
|
-
[reference](helpers/plan-reference.md).
|
|
95
|
+
file you cite; persist hard-errors on any `{path, assumption}` absent from
|
|
96
|
+
the tree. Fields: [reference](helpers/plan-reference.md).
|
|
99
97
|
|
|
100
98
|
Artifacts under `temp/plan-<slug>/`: `stories.json` (**length 1 by default**;
|
|
101
99
|
over-budget Specs fail closed — split or tighten, never under `docs/`); optional
|
|
102
|
-
`techspec.md` (**N===1 only
|
|
103
|
-
`acceptance-manifest.json` (N>1
|
|
104
|
-
|
|
100
|
+
`techspec.md` (**N===1 only**, folded into `## Spec`) and
|
|
101
|
+
`acceptance-manifest.json` (N>1 — `--plan-acceptance`). Use the envelope
|
|
102
|
+
`systemPrompts.story`; split only under the policy above.
|
|
105
103
|
|
|
106
104
|
**Tickets mode:** every Story authors a top-level `supersedes[]`; persist
|
|
107
105
|
refuses a partial map ([shape](helpers/plan-reference.md)).
|
|
@@ -115,9 +113,9 @@ node .agents/scripts/plan-critics.js \
|
|
|
115
113
|
```
|
|
116
114
|
|
|
117
115
|
Run **before** persist — the last point a finding folds into a re-author.
|
|
118
|
-
It exits 0 on **any** verdict (verdicts route work, they do not gate) and
|
|
119
|
-
**1** only on a usage/IO error — no critic ran
|
|
120
|
-
|
|
116
|
+
It exits 0 on **any** verdict (verdicts route work, they do not gate) and
|
|
117
|
+
exits **1** only on a usage/IO error — no critic ran: **do not proceed to
|
|
118
|
+
Persist**, fix and re-run.
|
|
121
119
|
|
|
122
120
|
- **Both `dispatch: false`** — proceed to Persist (each skip is ledgered).
|
|
123
121
|
- **Either `dispatch: true`** — dispatch **one fresh-context, maker-blind
|
|
@@ -125,16 +123,19 @@ proceed to Persist**, fix and re-run.
|
|
|
125
123
|
authoring transcript), fold findings into Gate #2 or a re-author round, re-run
|
|
126
124
|
this step. Pre-mortem triggers (incl. the external-dependency probe), the
|
|
127
125
|
advisory-only `textHygiene.findings[]` lints and dispatch shape:
|
|
128
|
-
[reference
|
|
126
|
+
[reference](helpers/plan-reference.md).
|
|
129
127
|
|
|
130
128
|
### 3. Persist
|
|
131
129
|
|
|
132
130
|
**Gate #2** — STOP for approval before persist **only** when the operator asked
|
|
133
131
|
to review (`--force-review`). Under `--yes`, auto-proceed.
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
([
|
|
133
|
+
**Gate #3 (N>2 only)** — offer a **container Epic**; on a yes add
|
|
134
|
+
`--epic-title` / `--epic-goal` below. It carries nothing a child does not
|
|
135
|
+
([shape](helpers/plan-reference.md)). Never below 3 Stories, never unasked.
|
|
136
|
+
|
|
137
|
+
Run persist with `--dry-run` **first** — same command, writes suppressed; every
|
|
138
|
+
gate runs before the first `createIssue` ([list](helpers/plan-reference.md)):
|
|
138
139
|
|
|
139
140
|
```bash
|
|
140
141
|
node .agents/scripts/plan-persist.js \
|
|
@@ -142,24 +143,29 @@ node .agents/scripts/plan-persist.js \
|
|
|
142
143
|
--plan-dir temp/plan-<slug> \
|
|
143
144
|
[--plan-acceptance temp/plan-<slug>/acceptance-manifest.json] \
|
|
144
145
|
[--tech-spec temp/plan-<slug>/techspec.md] \
|
|
145
|
-
[--source-tickets 123,456]
|
|
146
|
+
[--source-tickets 123,456] \
|
|
147
|
+
[--epic-title "<name>" --epic-goal "<one paragraph>"]
|
|
146
148
|
```
|
|
147
149
|
|
|
148
|
-
At lite shape
|
|
150
|
+
At lite shape `--chain-on-clean` folds a clean dry-run into the real persist;
|
|
149
151
|
a full plan keeps its review trip.
|
|
150
152
|
|
|
151
153
|
Persist creates `type::story` issue(s), a **metadata-only** `plan-run::<id>`
|
|
152
|
-
label,
|
|
154
|
+
label, `blocked by #<id>` footers for N>1 `depends_on` edges, and on a confirmed
|
|
155
|
+
Gate #3 a `type::epic` container linking every created Story.
|
|
153
156
|
`agent::ready` is the **terminal** flip after receipts land; stdout is pure
|
|
154
157
|
JSON. Tickets mode also comments on and closes each source id
|
|
155
158
|
([detail](helpers/plan-reference.md)).
|
|
156
159
|
|
|
157
160
|
## Constraints
|
|
158
161
|
|
|
159
|
-
- `/mandrel-plan` starts delivery **only** through a confirmed Gate #1 light
|
|
160
|
-
never off its own authored Stories, which land via
|
|
162
|
+
- `/mandrel-plan` starts delivery **only** through a confirmed Gate #1 light
|
|
163
|
+
route — never off its own authored Stories, which land via
|
|
164
|
+
[`/mandrel-deliver`](mandrel-deliver.md).
|
|
161
165
|
- Duplicate search targets open Stories (`type::story`), not Epics; and
|
|
162
166
|
deterministic gates still fail closed under `--yes`.
|
|
167
|
+
- A container Epic is never a work item, and no Story body gains an `Epic: #N`
|
|
168
|
+
footer: linkage is parent→child only.
|
|
163
169
|
|
|
164
170
|
## See also
|
|
165
171
|
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,22 @@ 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.40.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.39.0...mandrel-v2.40.0) (2026-09-06)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
* audit-to-stories --auto: persist the cross-run ledger via a `--ledger-commit` PR and ship the audit-sweep runbook template ([#5145](https://github.com/dsj1984/mandrel/issues/5145)) ([#5151](https://github.com/dsj1984/mandrel/issues/5151)) ([7274e6a](https://github.com/dsj1984/mandrel/commit/7274e6abe1bbf4fca6e1ed09abc8b4ebc9598d89))
|
|
24
|
+
* audit-to-stories: parse `####` findings under grouping headers and fail closed on a missing or mismatched `Severity tally:` line ([#5144](https://github.com/dsj1984/mandrel/issues/5144)) ([#5149](https://github.com/dsj1984/mandrel/issues/5149)) ([d9d8275](https://github.com/dsj1984/mandrel/commit/d9d827584989406e85d3e22110e6b741dab837e9))
|
|
25
|
+
* container Epic: /mandrel-plan offers one above 2 Stories, /mandrel-deliver expands an Epic id, /audit-to-stories requests one by default ([#5139](https://github.com/dsj1984/mandrel/issues/5139)) ([#5147](https://github.com/dsj1984/mandrel/issues/5147)) ([60dd912](https://github.com/dsj1984/mandrel/commit/60dd912f9d00dbf2fb7c17f8c98639b4008b5892))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
* audit-to-stories --wire-edges: carry the live provider's write ports through the dedup adapter ([#5143](https://github.com/dsj1984/mandrel/issues/5143)) ([#5146](https://github.com/dsj1984/mandrel/issues/5146)) ([380577e](https://github.com/dsj1984/mandrel/commit/380577e5e8f215bf28bb15ef8f2ac03c5958f0b8))
|
|
31
|
+
* **tests:** assert the report path separator-agnostically for Windows ([#5153](https://github.com/dsj1984/mandrel/issues/5153)) ([afe7fda](https://github.com/dsj1984/mandrel/commit/afe7fda7aa257bfb5e0745160363189ed84c2ad1))
|
|
32
|
+
* **tests:** import the provider fixture as a file URL for Windows ([#5150](https://github.com/dsj1984/mandrel/issues/5150)) ([797af46](https://github.com/dsj1984/mandrel/commit/797af46269e22e878fbd13293e5e5df6a044a1d3))
|
|
33
|
+
|
|
18
34
|
## [2.39.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.38.0...mandrel-v2.39.0) (2026-09-05)
|
|
19
35
|
|
|
20
36
|
|
package/package.json
CHANGED