mandrel 1.71.0 → 1.72.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/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +35 -5
- package/.agents/workflows/helpers/plan-epic.md +51 -8
- package/.agents/workflows/helpers/plan-story.md +18 -2
- package/.agents/workflows/plan.md +71 -3
- package/docs/CHANGELOG.md +12 -0
- package/package.json +1 -1
|
@@ -26,6 +26,15 @@
|
|
|
26
26
|
* "clean sprint" retro trailer), emit `epic.merge.ready`. Otherwise emit
|
|
27
27
|
* `epic.merge.blocked` with a non-empty reason.
|
|
28
28
|
*
|
|
29
|
+
* Code-review parse-miss policy (Story #4222): a code-review comment that is
|
|
30
|
+
* present but whose severity bullets cannot be parsed is treated as a DISTINCT
|
|
31
|
+
* condition — surfaced via the `codeReviewUnparseable` signal — and FAILS OPEN
|
|
32
|
+
* rather than blocking. Failing closed on a format miss is indistinguishable,
|
|
33
|
+
* to the operator and to downstream telemetry, from a real disqualifying
|
|
34
|
+
* finding; a parser miss must never masquerade as "the signal said no" inside
|
|
35
|
+
* a generic `epic.merge.blocked`. Genuine critical/high findings still block,
|
|
36
|
+
* because those require the counts to have parsed.
|
|
37
|
+
*
|
|
29
38
|
* Critical contract:
|
|
30
39
|
* - The verdict for any given input set is byte-identical to the
|
|
31
40
|
* pre-inlining legacy module's output — this file is its
|
|
@@ -229,11 +238,30 @@ function evaluateCodeReviewSignals(codeReview, reasons) {
|
|
|
229
238
|
: { critical: null, high: null, medium: null, suggestion: null };
|
|
230
239
|
if (!codeReviewFound) {
|
|
231
240
|
reasons.push('code-review structured comment not found on Epic');
|
|
232
|
-
return { codeReviewFound, severity };
|
|
241
|
+
return { codeReviewFound, codeReviewUnparseable: false, severity };
|
|
233
242
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
// "Present but unparseable" is a DISTINCT condition from "present and says
|
|
244
|
+
// no" (Story #4222). The canonical renderer
|
|
245
|
+
// (`review-providers/findings-renderer.js`) always emits all four severity
|
|
246
|
+
// bullets, so a body whose critical/high counts we cannot extract is a
|
|
247
|
+
// FORMAT MISS, not a disqualifying signal. Failing closed here — pushing a
|
|
248
|
+
// generic block reason — is indistinguishable, to the operator and to
|
|
249
|
+
// downstream telemetry (the mandrel-bench Autonomy dimension), from a real
|
|
250
|
+
// critical finding: it stalls an otherwise-clean unattended run for a
|
|
251
|
+
// non-reason.
|
|
252
|
+
//
|
|
253
|
+
// Chosen policy: FAIL OPEN on an unparseable code-review body. We surface
|
|
254
|
+
// the condition explicitly via the `codeReviewUnparseable` signal so
|
|
255
|
+
// telemetry can tell a parser miss from a true HITL hand-off, but we do NOT
|
|
256
|
+
// add a disqualifying `reasons[]` entry — the absence of a parseable
|
|
257
|
+
// critical/high count cannot, on its own, block a run whose other signals
|
|
258
|
+
// are clean. Genuine disqualifying review findings (critical > 0 /
|
|
259
|
+
// high > 0) still block below, because those require the counts to have
|
|
260
|
+
// parsed successfully.
|
|
261
|
+
const codeReviewUnparseable =
|
|
262
|
+
severity.critical === null || severity.high === null;
|
|
263
|
+
if (codeReviewUnparseable) {
|
|
264
|
+
return { codeReviewFound, codeReviewUnparseable, severity };
|
|
237
265
|
}
|
|
238
266
|
if (severity.critical > 0) {
|
|
239
267
|
reasons.push(`code-review has ${severity.critical} 🔴 Critical Blocker(s)`);
|
|
@@ -241,7 +269,7 @@ function evaluateCodeReviewSignals(codeReview, reasons) {
|
|
|
241
269
|
if (severity.high > 0) {
|
|
242
270
|
reasons.push(`code-review has ${severity.high} 🟠 High Risk finding(s)`);
|
|
243
271
|
}
|
|
244
|
-
return { codeReviewFound, severity };
|
|
272
|
+
return { codeReviewFound, codeReviewUnparseable, severity };
|
|
245
273
|
}
|
|
246
274
|
|
|
247
275
|
function evaluateRetroSignals(retro, reasons) {
|
|
@@ -287,6 +315,7 @@ function evaluateRetroSignals(retro, reasons) {
|
|
|
287
315
|
* storyStatuses: string[],
|
|
288
316
|
* storyBlockers: number,
|
|
289
317
|
* severity: { critical: number|null, high: number|null, medium: number|null, suggestion: number|null },
|
|
318
|
+
* codeReviewUnparseable: boolean,
|
|
290
319
|
* retroCompact: boolean,
|
|
291
320
|
* codeReviewFound: boolean,
|
|
292
321
|
* retroFound: boolean,
|
|
@@ -308,6 +337,7 @@ export function deriveAutoMergeVerdict({ state, codeReview, retro }) {
|
|
|
308
337
|
storyStatuses: stateSig.storyStatuses,
|
|
309
338
|
storyBlockers: stateSig.storyBlockers,
|
|
310
339
|
severity: reviewSig.severity,
|
|
340
|
+
codeReviewUnparseable: reviewSig.codeReviewUnparseable,
|
|
311
341
|
retroCompact: retroSig.retroCompact,
|
|
312
342
|
codeReviewFound: reviewSig.codeReviewFound,
|
|
313
343
|
retroFound: retroSig.retroFound,
|
|
@@ -74,14 +74,22 @@ Phase 5 (Re-Plan Detection).
|
|
|
74
74
|
one-pager feeds the scope-triage gate below, whose verdict folds into
|
|
75
75
|
the **same** Phase 1 HITL confirmation. Do not stop twice.
|
|
76
76
|
|
|
77
|
-
3. **HITL stop — confirm the sharpened one-pager
|
|
78
|
-
to the operator and **STOP**. Do not proceed to Phase 2
|
|
79
|
-
user explicitly confirms the direction. This is the same gate
|
|
80
|
-
skill's own Phase 3 enforces; surfacing it here makes the wait
|
|
77
|
+
3. **HITL stop — confirm the sharpened one-pager** (**gate #1**): Display
|
|
78
|
+
the one-pager to the operator and **STOP**. Do not proceed to Phase 2
|
|
79
|
+
until the user explicitly confirms the direction. This is the same gate
|
|
80
|
+
the skill's own Phase 3 enforces; surfacing it here makes the wait
|
|
81
81
|
contract visible to `/plan` callers. When the Phase 1.5 verdict is
|
|
82
82
|
`story` or `borderline`, this stop carries the three-way choice the
|
|
83
83
|
triage gate defines (below) instead of a plain confirm.
|
|
84
84
|
|
|
85
|
+
> **`--yes` (headless) auto-proceed.** When `/plan` was invoked with
|
|
86
|
+
> `--yes`, this gate does **not** STOP: the one-pager confirm resolves as
|
|
87
|
+
> **approved** and the run continues to Phase 2. A `story` / `borderline`
|
|
88
|
+
> triage verdict resolves to its **Recommended** branch (below) rather
|
|
89
|
+
> than prompting the three-way choice. Display the one-pager and the
|
|
90
|
+
> verdict line for the record, then proceed without waiting. See
|
|
91
|
+
> [`plan.md` § Headless / non-interactive mode](../plan.md#headless--non-interactive-mode---yes).
|
|
92
|
+
|
|
85
93
|
## Phase 1.5: Scope Triage (ideation path only)
|
|
86
94
|
|
|
87
95
|
This phase runs **only** on the ideation path, immediately after Phase 1
|
|
@@ -124,6 +132,15 @@ skill states once).
|
|
|
124
132
|
avoid the ceremony tax of pushing a story-sized scope through the full Epic
|
|
125
133
|
pipeline.
|
|
126
134
|
|
|
135
|
+
> **`--yes` (headless) exception.** "Never auto-route" is the interactive
|
|
136
|
+
> contract. Under `--yes` the operator has *pre-authorized* the
|
|
137
|
+
> recommendation: the three-way choice resolves to its **Recommended**
|
|
138
|
+
> branch deterministically — `single Story` hands off to
|
|
139
|
+
> `/plan --from-notes <path>` (carrying `--yes` so the receiving story
|
|
140
|
+
> path also auto-proceeds), and an `epic` verdict simply continues to
|
|
141
|
+
> Phase 2. No operator wait. This is the only sanctioned auto-route, and it
|
|
142
|
+
> exists solely to make `/plan` driveable headlessly.
|
|
143
|
+
|
|
127
144
|
## Phase 2: Cross-Epic Duplicate Search
|
|
128
145
|
|
|
129
146
|
Runs immediately after Phase 1 (and only on the s-plan-ideation path).
|
|
@@ -396,6 +413,19 @@ for the scoring logic.
|
|
|
396
413
|
permission") is honored — no `gh issue edit` call until the
|
|
397
414
|
operator confirms.
|
|
398
415
|
|
|
416
|
+
> **`--yes` (headless) auto-proceed.** This refinement-diff confirm is the
|
|
417
|
+
> clarity-gate face of `/plan`'s **gate #1** on the existing-Epic
|
|
418
|
+
> (`/plan <epicId>`) path — it is an operator *wait*, not a deterministic
|
|
419
|
+
> validator (the deterministic half is the section-presence *scoring* in
|
|
420
|
+
> step 1, which always runs). When `/plan` was invoked with `--yes`, this
|
|
421
|
+
> confirm does **not** STOP: the sharpened body is auto-**approved** and the
|
|
422
|
+
> run proceeds to step 6 (persist). The blast-radius note is still displayed
|
|
423
|
+
> for the record; only the operator wait is suppressed. This keeps
|
|
424
|
+
> `/plan <epicId> --yes` driveable headlessly even when the Epic body needs
|
|
425
|
+
> refinement (`gh issue edit` still runs only via the step 6 persist call,
|
|
426
|
+
> which the auto-approval authorizes). See
|
|
427
|
+
> [`plan.md` § Headless / non-interactive mode](../plan.md#headless--non-interactive-mode---yes).
|
|
428
|
+
|
|
399
429
|
6. **Persist**: On approval, run the persist mode:
|
|
400
430
|
|
|
401
431
|
```bash
|
|
@@ -556,18 +586,31 @@ for the scoring logic.
|
|
|
556
586
|
`planningRisk.requiresReview` unless the operator passed
|
|
557
587
|
`--force-review`:
|
|
558
588
|
- **High risk** (`requiresReview === true`) or **operator override**
|
|
559
|
-
(`--force-review`)
|
|
560
|
-
PRD, Tech Spec, and Acceptance Spec on GitHub. Approval is
|
|
561
|
-
user's verbal OK in this session — the three context tickets stay
|
|
589
|
+
(`--force-review`) — **gate #2**: **STOP**. Ask the USER to review the
|
|
590
|
+
generated PRD, Tech Spec, and Acceptance Spec on GitHub. Approval is
|
|
591
|
+
the user's verbal OK in this session — the three context tickets stay
|
|
562
592
|
**open** through delivery and are closed automatically by
|
|
563
593
|
`/deliver` when the Epic PR opens. Do NOT proceed
|
|
564
594
|
to decomposition until the user confirms the plan is accurate.
|
|
595
|
+
|
|
596
|
+
> **`--yes` (headless) auto-proceed.** When `/plan` was invoked with
|
|
597
|
+
> `--yes`, this review gate does **not** STOP, even when
|
|
598
|
+
> `requiresReview === true` or `--force-review` was also passed: the
|
|
599
|
+
> review resolves as **approved** and the run **continues directly to
|
|
600
|
+
> Phase 8**, exactly as the low-risk auto-proceed branch below. The
|
|
601
|
+
> three context tickets stay **open** through delivery as usual; only
|
|
602
|
+
> the operator *wait* is suppressed. This is `/plan`'s **gate #2** —
|
|
603
|
+
> the second and last HITL STOP `--yes` suppresses. `--yes` does
|
|
604
|
+
> **not** alter risk routing or the review criteria themselves; it
|
|
605
|
+
> only forces a proceed where this gate would otherwise STOP. See
|
|
606
|
+
> [`plan.md` § Headless / non-interactive mode](../plan.md#headless--non-interactive-mode---yes).
|
|
565
607
|
- **Low risk** (`requiresReview === false` and no `--force-review`):
|
|
566
608
|
Emit the auto-proceed message from the persist stdout
|
|
567
609
|
(`reviewRouting.operatorMessage`) and **continue directly to Phase 8**
|
|
568
610
|
without an extra review stop. The Epic still carries
|
|
569
611
|
`agent::review-spec` until decomposition completes; the routing
|
|
570
|
-
decision is recorded in the `epic-plan-state` checkpoint.
|
|
612
|
+
decision is recorded in the `epic-plan-state` checkpoint. (`--yes` is
|
|
613
|
+
a no-op on this branch — there is no STOP to suppress.)
|
|
571
614
|
|
|
572
615
|
5. **Tech Spec freshness check (advisory)**: After the Tech Spec issue
|
|
573
616
|
is created, `epic-plan-spec.js` runs
|
|
@@ -68,6 +68,9 @@ to authoring the standalone Story body from the handed-off one-pager.
|
|
|
68
68
|
|
|
69
69
|
# Inspect the draft body without creating an Issue:
|
|
70
70
|
/plan --dry-run --body temp/single-story-draft.md
|
|
71
|
+
|
|
72
|
+
# Headless / non-interactive (auto-proceeds the draft-confirm gate):
|
|
73
|
+
/plan --idea "rip out the unused TaskBodyMigrator export" --yes
|
|
71
74
|
```
|
|
72
75
|
|
|
73
76
|
## Phase 1 — Emit Context
|
|
@@ -153,8 +156,18 @@ add a second stop.
|
|
|
153
156
|
|
|
154
157
|
Display the draft to the operator and **STOP**. Do not call the persist phase
|
|
155
158
|
until the operator explicitly confirms the draft. This mirrors the HITL gate
|
|
156
|
-
`/plan` Phase 3 enforces before opening the Epic Issue.
|
|
157
|
-
|
|
159
|
+
`/plan` Phase 3 enforces before opening the Epic Issue. This is the
|
|
160
|
+
story-path face of `/plan`'s **gate #1** (the ideation one-pager /
|
|
161
|
+
scope-triage confirm). The scope-triage verdict folds into this same stop:
|
|
162
|
+
|
|
163
|
+
> **`--yes` (headless) auto-proceed.** When `/plan` was invoked with `--yes`,
|
|
164
|
+
> this gate does **not** STOP: the draft confirm resolves as **approved** and
|
|
165
|
+
> the run proceeds to Phase 3 (persist). An `epic` verdict resolves to its
|
|
166
|
+
> **Recommended** branch — escalate to `/plan --idea` (carrying `--yes`),
|
|
167
|
+
> abandoning the draft — rather than prompting the three-way choice. Display
|
|
168
|
+
> the draft and the verdict line for the record, then proceed without
|
|
169
|
+
> waiting. See
|
|
170
|
+
> [`plan.md` § Headless / non-interactive mode](../plan.md#headless--non-interactive-mode---yes).
|
|
158
171
|
|
|
159
172
|
- **`story` verdict (or gate skipped via handoff)** → no extra prompt. The
|
|
160
173
|
operator confirms the draft as usual and the run proceeds to Phase 3
|
|
@@ -177,6 +190,9 @@ verdict folds into this same stop:
|
|
|
177
190
|
|
|
178
191
|
**Never auto-route.** The verdict is advisory; the operator always decides,
|
|
179
192
|
and no `agent::*` / label transition happens on either side of the choice.
|
|
193
|
+
(**`--yes` exception:** headless mode pre-authorizes the **Recommended**
|
|
194
|
+
branch deterministically — see the `--yes` note above — the only sanctioned
|
|
195
|
+
auto-route, present solely to make `/plan` driveable without an operator.)
|
|
180
196
|
|
|
181
197
|
## Phase 3 — Persist (`gh issue create`)
|
|
182
198
|
|
|
@@ -44,6 +44,7 @@ forwards them to the active path helper:
|
|
|
44
44
|
| `--force` | Epic | Close + recreate an existing ticket tree on re-plan. |
|
|
45
45
|
| `--force-review` | Epic | Force the operator review gate even when risk routing would skip it. |
|
|
46
46
|
| `--allow-over-budget` | Epic | Permit a decomposition that exceeds the framework `maxTickets` reviewability budget. |
|
|
47
|
+
| `--yes` | both | **Non-interactive / headless mode.** Deterministically auto-proceeds the two `/plan` HITL STOP gates — the ideation one-pager / scope-triage confirm (gate #1) and the Phase-7 Epic operator review gate (gate #2) — without waiting for operator input. Parallel to [`/deliver --yes`](deliver.md). Composes with `--allow-over-budget` and with the risk-routed Phase-7 skip (it forces a proceed where those do not apply). Default (flag absent) behavior is unchanged: both gates still STOP for interactive use. |
|
|
47
48
|
| `--steal` | Epic | Forcibly transfer a foreign Epic-lease. |
|
|
48
49
|
| `--dry-run` | both | Author + validate without GitHub writes. |
|
|
49
50
|
| `--body <path>` | Story | Pre-authored Story body file; validate (and create, unless `--dry-run`) without re-authoring. |
|
|
@@ -58,6 +59,71 @@ commands (story-sized Epic ↘ Story; epic-sized Story draft ↗ Epic) is now
|
|
|
58
59
|
an **internal branch switch** inside this router: same skills, same
|
|
59
60
|
helpers, no command hop and no operator re-entry.
|
|
60
61
|
|
|
62
|
+
### Headless / non-interactive mode (`--yes`)
|
|
63
|
+
|
|
64
|
+
`--yes` is the headless escape hatch for an unattended driver (CI, a
|
|
65
|
+
benchmark harness, or any `claude -p` run with no human at the keyboard). It
|
|
66
|
+
is the `/plan`-side parallel of [`/deliver --yes`](deliver.md), which
|
|
67
|
+
suppresses that command's segment-plan confirmation. `/plan` has exactly
|
|
68
|
+
**two** HITL STOP gates, and `--yes` deterministically auto-proceeds **both**
|
|
69
|
+
without waiting for operator input:
|
|
70
|
+
|
|
71
|
+
1. **Gate #1 — the ideation one-pager / scope-triage / clarity confirm.**
|
|
72
|
+
This single conceptual gate has three faces depending on the entry form,
|
|
73
|
+
and `--yes` auto-proceeds **all three**:
|
|
74
|
+
- On the `--idea` Epic path,
|
|
75
|
+
[`helpers/plan-epic.md`](helpers/plan-epic.md) Phase 1 (folding in the
|
|
76
|
+
Phase 1.5 scope-triage verdict) STOPs to confirm the sharpened one-pager.
|
|
77
|
+
- On the `--idea` Story path,
|
|
78
|
+
[`helpers/plan-story.md`](helpers/plan-story.md) Phase 2 STOPs to
|
|
79
|
+
confirm the drafted Story body.
|
|
80
|
+
- On the existing-Epic (`/plan <epicId>`) path, the Phase 6 Epic Clarity
|
|
81
|
+
Gate's **needs-refinement** branch STOPs to confirm the refined-body
|
|
82
|
+
diff before persisting it.
|
|
83
|
+
|
|
84
|
+
Under `--yes` each auto-proceeds: the one-pager / draft / refined-body
|
|
85
|
+
confirm resolves as **approved**, and a `story` / `borderline` triage
|
|
86
|
+
verdict resolves to its **recommended** branch (the one the gate prose
|
|
87
|
+
marks "Recommended") rather than prompting the three-way choice. The
|
|
88
|
+
verdict / clarity scoring is still recorded in chat (one line); only the
|
|
89
|
+
*wait* is suppressed. The clarity-gate *scoring* itself (deterministic
|
|
90
|
+
section-presence in Phase 6 step 1) still runs — `--yes` suppresses only
|
|
91
|
+
the operator confirm of the proposed refinement.
|
|
92
|
+
2. **Gate #2 — the Phase-7 Epic operator review gate.** When risk routing
|
|
93
|
+
forces a review (`planningRisk.requiresReview === true`, or the operator
|
|
94
|
+
also passed `--force-review`),
|
|
95
|
+
[`helpers/plan-epic.md`](helpers/plan-epic.md) Phase 7 STOPs for operator
|
|
96
|
+
approval of the PRD / Tech Spec / Acceptance Spec before decomposition.
|
|
97
|
+
Under `--yes` this review auto-proceeds straight to Phase 8 — the three
|
|
98
|
+
context tickets stay **open** through delivery exactly as on the low-risk
|
|
99
|
+
auto-proceed path.
|
|
100
|
+
|
|
101
|
+
**Composition.** `--yes` is orthogonal to the other planning flags and
|
|
102
|
+
composes cleanly:
|
|
103
|
+
|
|
104
|
+
- With **`--allow-over-budget`**: `--yes` suppresses the gate *waits* while
|
|
105
|
+
`--allow-over-budget` still governs the `maxTickets` over-budget persist —
|
|
106
|
+
passing `--yes` alone does **not** waive the budget gate.
|
|
107
|
+
- With the **risk-routed Phase-7 skip**: when risk routing already skips the
|
|
108
|
+
Phase-7 review (low-risk, no `--force-review`), `--yes` is a no-op for that
|
|
109
|
+
gate — it only *forces a proceed where the gate would otherwise STOP*, it
|
|
110
|
+
never *adds* a stop or relaxes any non-HITL validator.
|
|
111
|
+
|
|
112
|
+
**`--yes` suppresses only the HITL operator *waits* above.** It does **not**
|
|
113
|
+
relax any deterministic gate — the Phase 6 Epic Clarity Gate **scoring**
|
|
114
|
+
(section-presence), the Phase 7.5 Tech Spec Section Gate, the file-assumption
|
|
115
|
+
/ DAG validators, the Phase 10 readiness healthcheck, and the `agent::blocked`
|
|
116
|
+
runtime pause all behave exactly as without the flag. A `--yes` run that hits
|
|
117
|
+
one of those still fails closed; the flag is an operator-input suppressor, not
|
|
118
|
+
a validation override. The other operator-input *waits* in the pipeline also
|
|
119
|
+
auto-proceed under `--yes` — the non-blocking Phase 2 duplicate-search pause
|
|
120
|
+
(distinct-Epic confirmed), the Phase 6 clarity refinement-diff confirm
|
|
121
|
+
(refined body approved), and the advisory Phase 8.3/8.4/8.5
|
|
122
|
+
consolidation/critic diffs (consolidated/critic output applied) — since they
|
|
123
|
+
are operator-input waits, not validators. The two *named* HITL STOP gates the
|
|
124
|
+
Story tracks (gate #1, gate #2) are the load-bearing pair; these additional
|
|
125
|
+
waits are auto-proceeded for the same headless reason.
|
|
126
|
+
|
|
61
127
|
## First-run preflight
|
|
62
128
|
|
|
63
129
|
Before routing to a path helper, run a **first-run preflight** to catch
|
|
@@ -109,9 +175,11 @@ stubbed docs, or an unready doctor verdict).
|
|
|
109
175
|
[`core/scope-triage`](../skills/core/scope-triage/SKILL.md) skill on the
|
|
110
176
|
seed. Record the verdict in chat (one line).
|
|
111
177
|
4. **Delegate.** Read the selected path helper **in full** and execute it
|
|
112
|
-
from its entry phase, forwarding the absorbed flags
|
|
113
|
-
numbering, HITL gates, and scripts are unchanged — this
|
|
114
|
-
phase content.
|
|
178
|
+
from its entry phase, forwarding the absorbed flags (including `--yes`).
|
|
179
|
+
The helper's phase numbering, HITL gates, and scripts are unchanged — this
|
|
180
|
+
router adds no phase content. When `--yes` is present, the two HITL STOP
|
|
181
|
+
gates auto-proceed per [Headless / non-interactive mode](#headless--non-interactive-mode---yes)
|
|
182
|
+
above; every deterministic gate still runs.
|
|
115
183
|
5. **Internal returns.** When a path helper would historically have handed
|
|
116
184
|
off to the other planning command, switch helpers in-place and continue;
|
|
117
185
|
surface the switch to the operator as a one-line note.
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.72.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.71.0...mandrel-v1.72.0) (2026-06-17)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
* **plan:** add a headless/non-interactive flag to suppress the ideation one-pager + Phase-7 review gate ([#4223](https://github.com/dsj1984/mandrel/issues/4223)) ([#4226](https://github.com/dsj1984/mandrel/issues/4226)) ([9ffa355](https://github.com/dsj1984/mandrel/commit/9ffa35543f897199c096ad45a568de39b0424ba7))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
* **deliver:** fail open on unparseable code-review severity bullets in auto-merge gate (refs [#4222](https://github.com/dsj1984/mandrel/issues/4222)) ([#4224](https://github.com/dsj1984/mandrel/issues/4224)) ([ca949bd](https://github.com/dsj1984/mandrel/commit/ca949bd7d98eea440571db6636f8be2f2128c3b9))
|
|
16
|
+
|
|
5
17
|
## [1.71.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.70.0...mandrel-v1.71.0) (2026-06-16)
|
|
6
18
|
|
|
7
19
|
|
package/package.json
CHANGED