mandrel 2.56.0 → 2.57.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/plan-critic.md +13 -18
- package/.agents/agents/story-worker.md +25 -34
- package/.agents/docs/agentrc-reference.json +0 -30
- package/.agents/docs/configuration.md +8 -28
- package/.agents/docs/execution-reference.md +5 -5
- package/.agents/docs/quality-gates.md +8 -7
- package/.agents/instructions.md +9 -10
- package/.agents/schemas/agentrc.schema.json +9 -185
- package/.agents/schemas/story-deliver-terminal.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +107 -17
- package/.agents/scripts/ceremony-derive.js +191 -0
- package/.agents/scripts/check-context-budget.js +28 -33
- package/.agents/scripts/check-cyclomatic.js +4 -3
- package/.agents/scripts/deliver-light.js +31 -94
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +15 -2
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +110 -0
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +25 -0
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +223 -0
- package/.agents/scripts/lib/bdd-scenario-budget.js +21 -3
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -1
- package/.agents/scripts/lib/close-validation/gates.js +52 -1
- package/.agents/scripts/lib/config/acceptance-eval.js +25 -57
- package/.agents/scripts/lib/config/delivery-routing.js +7 -33
- package/.agents/scripts/lib/config/explain.js +0 -19
- package/.agents/scripts/lib/config/limits.js +18 -78
- package/.agents/scripts/lib/config/quality.js +6 -3
- package/.agents/scripts/lib/config/runners.js +3 -2
- package/.agents/scripts/lib/config-settings-schema-delivery.js +15 -68
- package/.agents/scripts/lib/config-settings-schema-quality.js +0 -14
- package/.agents/scripts/lib/config-settings-schema.js +16 -143
- package/.agents/scripts/lib/crap-engine.js +35 -4
- package/.agents/scripts/lib/crap-utils.js +17 -1
- package/.agents/scripts/lib/cyclomatic-ceiling.js +19 -7
- package/.agents/scripts/lib/generated/agentrc-validator.js +1 -1
- package/.agents/scripts/lib/observability/runtime-friction.js +1 -1
- package/.agents/scripts/lib/observability/source-classifier.js +1 -0
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +5 -4
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +19 -73
- package/.agents/scripts/lib/orchestration/complexity-gate.js +46 -212
- package/.agents/scripts/lib/orchestration/file-assumptions.js +32 -17
- package/.agents/scripts/lib/orchestration/light-escalation.js +3 -3
- package/.agents/scripts/lib/orchestration/light-suitability.js +66 -233
- package/.agents/scripts/lib/orchestration/plan-context.js +181 -387
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +42 -153
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +14 -70
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +300 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +131 -168
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +118 -297
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +55 -0
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +16 -65
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +22 -35
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +30 -139
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +61 -223
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +5 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +46 -16
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +213 -0
- package/.agents/scripts/lib/orchestration/task-body-validator.js +10 -63
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +33 -539
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +21 -414
- package/.agents/scripts/lib/orchestration/ticket-validator.js +54 -118
- package/.agents/scripts/lib/orchestration/verify-credit.js +69 -24
- package/.agents/scripts/lib/story-body/body-format-lints.js +15 -85
- package/.agents/scripts/lib/story-body/story-body.js +17 -237
- package/.agents/scripts/lib/templates/decomposer-prompts.js +84 -121
- package/.agents/scripts/lib/test-isolate/cli-options.js +93 -0
- package/.agents/scripts/lib/test-isolate/progress-log.js +45 -0
- package/.agents/scripts/lib/test-isolate/render-report.js +97 -0
- package/.agents/scripts/lib/test-isolate/run-isolate.js +87 -0
- package/.agents/scripts/lib/test-run-credit.js +266 -0
- package/.agents/scripts/lib/wave-runner/footprint.js +48 -358
- package/.agents/scripts/lib/wave-runner/ready-set.js +6 -5
- package/.agents/scripts/lib/workers/crap-worker.js +32 -41
- package/.agents/scripts/plan-context.js +7 -9
- package/.agents/scripts/plan-critics.js +28 -54
- package/.agents/scripts/plan-persist.js +25 -68
- package/.agents/scripts/quality-preview.js +51 -0
- package/.agents/scripts/run-tests.js +12 -0
- package/.agents/scripts/stories-wave-tick.js +23 -45
- package/.agents/scripts/test-isolate.js +13 -180
- package/.agents/scripts/update-coverage-baseline.js +25 -70
- package/.agents/scripts/update-crap-baseline.js +19 -123
- package/.agents/skills/core/scope-triage/SKILL.md +3 -3
- package/.agents/workflows/audit-clean-code.md +4 -3
- package/.agents/workflows/helpers/acceptance-self-eval.md +41 -41
- package/.agents/workflows/helpers/code-quality-guardrails.md +4 -4
- package/.agents/workflows/helpers/code-review.md +2 -3
- package/.agents/workflows/helpers/deliver-digest.md +41 -57
- package/.agents/workflows/helpers/deliver-light.md +40 -105
- package/.agents/workflows/helpers/deliver-reference.md +1 -1
- package/.agents/workflows/helpers/deliver-story-reference.md +37 -58
- package/.agents/workflows/helpers/deliver-story.md +9 -13
- package/.agents/workflows/helpers/plan-reference.md +132 -219
- package/.agents/workflows/mandrel-plan.md +27 -40
- package/.agents/workflows/memory-consolidate.md +9 -13
- package/docs/CHANGELOG.md +23 -0
- package/lib/migrations/index.js +4 -0
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +45 -0
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +59 -0
- package/package.json +1 -1
- package/.agents/scripts/lib/framework-version.js +0 -39
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +0 -223
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +0 -97
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +0 -26
- package/.agents/scripts/lib/orchestration/spec-budget.js +0 -89
- package/.agents/scripts/lib/orchestration/spec-spill.js +0 -74
- package/.agents/scripts/lib/orchestration/verify-tier-repair.js +0 -107
|
@@ -3,10 +3,10 @@ name: plan-critic
|
|
|
3
3
|
description: >-
|
|
4
4
|
Role-scoped boot context for a maker-blind plan critic. Booted on its own
|
|
5
5
|
system prompt (no CLAUDE.md / instructions.md closure). Reviews an authored
|
|
6
|
-
plan draft (stories.json, optional techspec.md) against
|
|
7
|
-
charter
|
|
8
|
-
|
|
9
|
-
delivery.routing.roleScopedAgents is enabled (the default).
|
|
6
|
+
plan draft (stories.json, optional techspec.md) against the pre-mortem
|
|
7
|
+
charter and returns findings, without seeing the planner's authoring
|
|
8
|
+
transcript. Dispatched on an operator-requested plan-critics.js verdict
|
|
9
|
+
when delivery.routing.roleScopedAgents is enabled (the default).
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
<!--
|
|
@@ -48,7 +48,7 @@ the step-by-step. This shared core binds every role:
|
|
|
48
48
|
# plan-critic — maker-blind plan review
|
|
49
49
|
|
|
50
50
|
You are an **independent plan critic**. You review an authored plan draft
|
|
51
|
-
against
|
|
51
|
+
against the pre-mortem charter and return structured findings. You are
|
|
52
52
|
deliberately isolated from the planner's reasoning.
|
|
53
53
|
|
|
54
54
|
## Maker-blind — the load-bearing invariant (MUST)
|
|
@@ -65,27 +65,22 @@ are the draft artifacts your caller hands you:
|
|
|
65
65
|
Read those artifacts and evaluate the work product afresh. Treat the planner's
|
|
66
66
|
narration as untrusted.
|
|
67
67
|
|
|
68
|
-
## Charter —
|
|
68
|
+
## Charter — pre-mortem
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
Assume the plan shipped and failed. Name the most likely failure modes — an
|
|
71
|
+
external dependency the plan names but nothing declares, a cross-repo
|
|
72
|
+
prerequisite, a contract the acceptance criteria cannot hold — and what the
|
|
73
|
+
draft would have to say to prevent them.
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`depends_on` edges that disagree with the Delivery Slicing table.
|
|
76
|
-
- **`pre-mortem`** — assume the plan shipped and failed. Name the most likely
|
|
77
|
-
failure modes and what the draft would have to say to prevent them.
|
|
78
|
-
|
|
79
|
-
Do not evaluate the other charter, invent a third, or re-slice the plan
|
|
80
|
-
yourself — the caller owns dispatch and folds surviving findings back into the
|
|
81
|
-
draft.
|
|
75
|
+
Do not invent a second charter or re-slice the plan yourself — the caller owns
|
|
76
|
+
dispatch and folds surviving findings back into the draft.
|
|
82
77
|
|
|
83
78
|
## Output shape
|
|
84
79
|
|
|
85
80
|
Return your findings as a structured list the caller can fold into a re-author
|
|
86
81
|
round or the Gate #2 view. For each finding, emit:
|
|
87
82
|
|
|
88
|
-
- `charter` — `
|
|
83
|
+
- `charter` — `pre-mortem`.
|
|
89
84
|
- `severity` — `blocker` | `advisory` (advisory findings inform the operator's
|
|
90
85
|
Gate #2 decision; they are not an automatic re-author mandate).
|
|
91
86
|
- `target` — the Story slug / id (or `plan` for a whole-draft finding) the
|
|
@@ -83,34 +83,25 @@ Do **not** re-read every file in `project.docsContextFiles`. Read the
|
|
|
83
83
|
digest your caller passes, then pull files on demand at the lines it
|
|
84
84
|
names. A null digest path means no docs mandate.
|
|
85
85
|
|
|
86
|
-
## Close gates — one
|
|
86
|
+
## Close gates — one full-suite run
|
|
87
87
|
|
|
88
88
|
`single-story-close.js` runs the canonical close-validation chain
|
|
89
89
|
(**typecheck, lint, test, format, maintainability, coverage, crap**) and is
|
|
90
|
-
the authoritative gate — do not pre-run it. The **one** exception is
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
`
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
comes first. Never spawn a task to poll or `sleep`-loop
|
|
106
|
-
against it; a waiter with a wrong condition outlives the agent. Share
|
|
107
|
-
`lint` / `typecheck` evidence with close via `evidence-gate.js`; never
|
|
108
|
-
stamp coverage / CRAP fresh any other way.
|
|
109
|
-
|
|
110
|
-
**It can legitimately run nothing.** With nothing changed under the CRAP
|
|
111
|
-
`targetDirs` it skips capture and exits 0. An exit code is never evidence a
|
|
112
|
-
gate did work — its **output** is: no credit was deposited. Run the scoped
|
|
113
|
-
projects for the roots you changed plus `verify[]`, not the whole suite.
|
|
90
|
+
the authoritative gate — do not pre-run it. The **one** exception is the
|
|
91
|
+
full suite: after the self-eval loop's last fix commit, run `npm test`
|
|
92
|
+
exactly once in `<workCwd>`. A green full run on `story-<storyId>`
|
|
93
|
+
deposits the `test` credit close reads, keyed on the tree; a later commit
|
|
94
|
+
voids it, and close captures coverage itself when the CRAP gate needs an
|
|
95
|
+
artifact. If the suite outruns the host's sync Bash ceiling, dispatch it in
|
|
96
|
+
the **background** — its completion notification re-invokes you. Never
|
|
97
|
+
spawn a task to poll or `sleep`-loop against it; a waiter with a wrong
|
|
98
|
+
condition outlives the agent. An exit code is never evidence a gate did
|
|
99
|
+
work — the runner's **output** is: it prints whether it deposited credit,
|
|
100
|
+
and a run off the Story branch or of a partial tier deposits nothing and
|
|
101
|
+
says so. Redraft rounds run the scoped projects for the roots you changed
|
|
102
|
+
plus `verify[]`, not the whole suite. Share `lint` / `typecheck` evidence
|
|
103
|
+
with close via `evidence-gate.js`; never stamp coverage / CRAP fresh any
|
|
104
|
+
other way.
|
|
114
105
|
|
|
115
106
|
Gate output that lies: [`known-tooling-behavior.md`](../rules/known-tooling-behavior.md).
|
|
116
107
|
Waiter traps: [`parallel-tooling.md`](../workflows/helpers/parallel-tooling.md) Rule 2.
|
|
@@ -119,12 +110,13 @@ Waiter traps: [`parallel-tooling.md`](../workflows/helpers/parallel-tooling.md)
|
|
|
119
110
|
|
|
120
111
|
**Before** flipping to `closing`, run the bounded self-eval loop
|
|
121
112
|
([`acceptance-self-eval.md`](../workflows/helpers/acceptance-self-eval.md)).
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
**
|
|
127
|
-
|
|
113
|
+
Derive the change set, level and ceremony with
|
|
114
|
+
`node <main-repo>/.agents/scripts/ceremony-derive.js --story <storyId> --cwd <workCwd>`
|
|
115
|
+
and hand its `files` to the critic — never one it re-derives. It scores
|
|
116
|
+
each `acceptance[]` item, consuming `verify[]` output as evidence.
|
|
117
|
+
**proceed** → flip to `closing`, run the suite, push, hand off;
|
|
118
|
+
**redraft** → fix the criteria, commit, re-eval; **block** → take the
|
|
119
|
+
blocked path below. Never hand off an unscored branch.
|
|
128
120
|
|
|
129
121
|
## Lifecycle: progress & blocked (MUST)
|
|
130
122
|
|
|
@@ -146,9 +138,8 @@ the only sanctioned landing.
|
|
|
146
138
|
## Your turn ends at a pushed branch (MUST)
|
|
147
139
|
|
|
148
140
|
You do **not** run close. Push `story-<storyId>` to `origin` — confirming
|
|
149
|
-
the remote ref moved —
|
|
150
|
-
|
|
151
|
-
ends unpushed reads as unfinished work. The orchestrator runs
|
|
141
|
+
the remote ref moved — then return: a turn that ends unpushed reads as
|
|
142
|
+
unfinished work. The orchestrator runs
|
|
152
143
|
`single-story-close.js` in its own session, serialized against your
|
|
153
144
|
siblings. Do not open the PR, flip `agent::done`, or spawn a child to
|
|
154
145
|
close for you. If the push fails, take the blocked path above.
|
|
@@ -70,28 +70,9 @@
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
"planning": {
|
|
73
|
-
"riskHeuristics": [
|
|
74
|
-
"Destructive or irreversible data mutations (dropping tables, deleting rows without soft-delete or backup, truncating production state).",
|
|
75
|
-
"Modifications to shared security or auth infrastructure (IAM policies, auth middleware, session or token handling, secret rotation).",
|
|
76
|
-
"Changes to CI/CD, deployment pipelines, or release gating that could disable safety checks or ship unverified code to production.",
|
|
77
|
-
"Monorepo-wide AST or text replacements touching overlapping files in parallel (catastrophic merge-conflict risk across concurrent agents).",
|
|
78
|
-
"Schema migrations that rewrite existing rows or drop columns without a backfill or rollback plan."
|
|
79
|
-
],
|
|
80
73
|
"memoryPool": {
|
|
81
|
-
"staleAfterDays": 30,
|
|
82
|
-
"growthDelta": 25,
|
|
83
74
|
"indexByteCeiling": 24576
|
|
84
75
|
},
|
|
85
|
-
"failOnSharedEditors": false,
|
|
86
|
-
"requireExplicitCrossStoryDeps": false,
|
|
87
|
-
"crossCuttingRegistries": [
|
|
88
|
-
"lib/orchestration/lifecycle/listeners/index.js",
|
|
89
|
-
"**/listeners/index.js",
|
|
90
|
-
"**/handlers/index.js"
|
|
91
|
-
],
|
|
92
|
-
"failOnRegistryConflicts": false,
|
|
93
|
-
"failOnLargeFanOut": false,
|
|
94
|
-
"largeFanOutThreshold": 10,
|
|
95
76
|
"navigation": {
|
|
96
77
|
"routeGlobs": [],
|
|
97
78
|
"navRegistry": []
|
|
@@ -134,14 +115,6 @@
|
|
|
134
115
|
".agents/instructions.local.md"
|
|
135
116
|
]
|
|
136
117
|
},
|
|
137
|
-
"signals": {
|
|
138
|
-
"rework": {
|
|
139
|
-
"editsPerFile": 5
|
|
140
|
-
},
|
|
141
|
-
"retry": {
|
|
142
|
-
"repeatCount": 3
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
118
|
"quality": {
|
|
146
119
|
"gateScoping": {
|
|
147
120
|
"scope": "diff",
|
|
@@ -288,7 +261,6 @@
|
|
|
288
261
|
},
|
|
289
262
|
"codingGuardrails": {
|
|
290
263
|
"cyclomaticFlag": 8,
|
|
291
|
-
"cyclomaticMustFix": 12,
|
|
292
264
|
"requireSiblingTest": false
|
|
293
265
|
},
|
|
294
266
|
"autoRefresh": {
|
|
@@ -336,7 +308,6 @@
|
|
|
336
308
|
}
|
|
337
309
|
],
|
|
338
310
|
"maxFixAttempts": 3,
|
|
339
|
-
"maxFixScopeFiles": 5,
|
|
340
311
|
"autoFixSeverity": "medium"
|
|
341
312
|
},
|
|
342
313
|
"refactorStage": {
|
|
@@ -363,7 +334,6 @@
|
|
|
363
334
|
},
|
|
364
335
|
"routing": {
|
|
365
336
|
"roleScopedAgents": true,
|
|
366
|
-
"freshCriticSampleRate": 0.2,
|
|
367
337
|
"ceremonyProfile": "standard",
|
|
368
338
|
"closeAndLand": true
|
|
369
339
|
}
|
|
@@ -122,31 +122,19 @@ GitHub provider identity plus the remote stance the bootstrap enforces. `owner`,
|
|
|
122
122
|
|
|
123
123
|
### `planning` (optional)
|
|
124
124
|
|
|
125
|
-
Inputs to `/mandrel-plan`:
|
|
125
|
+
Inputs to `/mandrel-plan`: the memory-hygiene advisory ceiling and the opt-in navigability reachability gate.
|
|
126
126
|
|
|
127
127
|
| Key | Required | Type | Default | Description |
|
|
128
128
|
| --- | --- | --- | --- | --- |
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `complexityGate.enabled` | No | `boolean` | — | Master switch. When false, lite routing is disabled everywhere: persist refuses lite claims and dispatch always takes the sub-agent path. Default true. |
|
|
132
|
-
| `complexityGate.maxArtifacts` | No | `integer` | — | Enumerated-artifact threshold reported by the plan-context complexity signals. An input signal for the planner verdict — carries no routing authority. Default 1. |
|
|
133
|
-
| `memoryPool` | No | `object` | — | Thresholds for the memory-hygiene advisory `/mandrel-plan` surfaces at Gate #1. Advisory only: it recommends `/memory-consolidate` and never gates, reroutes, or mutates the memory pool. |
|
|
134
|
-
| `memoryPool.staleAfterDays` | No | `integer` | `30` | Recommend a consolidation pass once the pool's stamp is older than this many days. Default 30. |
|
|
135
|
-
| `memoryPool.growthDelta` | No | `integer` | `25` | Recommend a consolidation pass once this many entries have been written since the last one. Measured against the entry count the last pass stamped, so a stamp predating that field leaves growth unmeasured and only the age threshold applies. Default 25. |
|
|
136
|
-
| `memoryPool.indexByteCeiling` | No | `integer` | `24576` | Recommend a consolidation pass once the pool's `MEMORY.md` index exceeds this many bytes. Independent of the age and growth thresholds: the harness truncates the index it loads into each session at its own byte cap, so an oversized index is a loss already happening — every entry listed after the cut is invisible — rather than a hygiene forecast. Default 24576, the harness cap itself. |
|
|
137
|
-
| `failOnSharedEditors` | No | `boolean` | `false` | When true, upgrade shared-editor conflict findings to hard errors (default false — advisory soft findings only). |
|
|
138
|
-
| `requireExplicitCrossStoryDeps` | No | `boolean` | `false` | When true, upgrade implicit cross-Story dependency findings to hard errors (default false — advisory soft findings only). |
|
|
139
|
-
| `crossCuttingRegistries` | No | `string[]` or `{ append?, prepend? }` | `["lib/orchestration/lifecycle/listeners/index.js","**/listeners/index.js","**/handlers/index.js"]` | Registry path patterns whose concurrent edits across Stories are flagged as conflicts. Defaults to the framework listener/handler index patterns when omitted. |
|
|
140
|
-
| `failOnRegistryConflicts` | No | `boolean` | `false` | When true, upgrade cross-cutting registry conflict findings to hard errors (default false). |
|
|
141
|
-
| `failOnLargeFanOut` | No | `boolean` | `false` | When true, upgrade fan-out-warning findings (delete blast radius) to hard errors (default false — soft advisory). |
|
|
142
|
-
| `largeFanOutThreshold` | No | `integer` | `10` | Call-site count above which a Story that deletes a module emits a fan-out-warning. Counts base-branch references to the deleted path basename. Soft by default; does not size or reject Stories. Default 10. |
|
|
129
|
+
| `memoryPool` | No | `object` | — | Threshold for the memory-hygiene advisory `/mandrel-plan` surfaces at Gate #1. Advisory only: it recommends `/memory-consolidate` and never gates, reroutes, or mutates the memory pool. |
|
|
130
|
+
| `memoryPool.indexByteCeiling` | No | `integer` | `24576` | Recommend a consolidation pass once the pool's `MEMORY.md` index exceeds this many bytes. The harness truncates the index it loads into each session at its own byte cap, so an oversized index is a loss already happening — every entry listed after the cut is invisible — rather than a hygiene forecast. Default 24576, the harness cap itself. |
|
|
143
131
|
| `navigation` | No | `object` | — | Opt-in navigability reachability gate. Absent or empty routeGlobs is a silent no-op. |
|
|
144
132
|
| `navigation.routeGlobs` | No | `array<string>` | `[]` | Glob patterns (e.g. pages/**, app/**/route.ts) marking paths that add a user-facing route. |
|
|
145
133
|
| `navigation.navRegistry` | No | `array<string>` | `[]` | Tokens identifying the nav-registry SSOT a route-adding Story is expected to reference. |
|
|
146
134
|
|
|
147
135
|
### `delivery` (optional)
|
|
148
136
|
|
|
149
|
-
Everything `/mandrel-deliver` and `single-story-close` consume: execution timeouts, worktree isolation, runner concurrency, docs freshness,
|
|
137
|
+
Everything `/mandrel-deliver` and `single-story-close` consume: execution timeouts, worktree isolation, runner concurrency, docs freshness, quality gates, merge/CI watch, review ceremony, and the feedback loop.
|
|
150
138
|
|
|
151
139
|
| Key | Required | Type | Default | Description |
|
|
152
140
|
| --- | --- | --- | --- | --- |
|
|
@@ -175,11 +163,6 @@ Everything `/mandrel-deliver` and `single-story-close` consume: execution timeou
|
|
|
175
163
|
| `worktreeIsolation.allowSymlinkOnWindows` | No | `boolean` | `false` | Permit the `symlink` strategy on win32, where it needs Developer Mode or elevation. Off by default so a Windows consumer fails over to a strategy that works. |
|
|
176
164
|
| `worktreeIsolation.reapOnSuccess` | No | `boolean` | `true` | Remove the Story's worktree once its PR merges. False keeps it for post-mortem inspection. |
|
|
177
165
|
| `worktreeIsolation.bootstrapFiles` | No | `array<string>` | `[".env",".mcp.json",".agentrc.local.json",".agents/instructions.local.md"]` | Gitignored files copied from the main checkout into every new worktree. A worktree checks out tracked files only, so local secrets and overrides would otherwise be missing. |
|
|
178
|
-
| `signals` | No | `object` | — | Detector thresholds for the surviving performance-signal categories. Each block is shallow-merged by the resolver. |
|
|
179
|
-
| `signals.rework` | No | `object` | — | Rework detector — repeated edits to one file in a run. |
|
|
180
|
-
| `signals.rework.editsPerFile` | No | `integer` | `5` | Edits to a single file within one run that trip the rework signal. |
|
|
181
|
-
| `signals.retry` | No | `object` | — | Retry detector — the same command failing repeatedly. |
|
|
182
|
-
| `signals.retry.repeatCount` | No | `integer` | `3` | Repeats of an identical failing command that trip the retry signal. |
|
|
183
166
|
| `quality` | No | `object` | — | Quality-gate configuration. Every gate lives under `gates.<tier>` and shares the same `{ enabled, baselinePath, tolerance, floors, components }` base; shared scoping lives at this block root. |
|
|
184
167
|
| `quality.gateScoping` | No | `object` | — | Shared scope applied to every gate that supports one, unless the gate overrides it. |
|
|
185
168
|
| `quality.gateScoping.scope` | No | `"diff"` \| `"full"` | `"diff"` | Score only the files changed against `diffRef` (`diff`) or every file in the gate target dirs (`full`). |
|
|
@@ -280,7 +263,6 @@ Everything `/mandrel-deliver` and `single-story-close` consume: execution timeou
|
|
|
280
263
|
| `quality.formatAutofix.timeoutMs` | No | `integer` | `60000` | Timeout (ms) for the format-write spawn. |
|
|
281
264
|
| `quality.codingGuardrails` | No | `object` | — | Authoring-time cyclomatic-complexity advisories surfaced by the quality-preview pre-commit gate. |
|
|
282
265
|
| `quality.codingGuardrails.cyclomaticFlag` | No | `integer` | `8` | Cyclomatic complexity at which a new or changed method is flagged for a refactor look. |
|
|
283
|
-
| `quality.codingGuardrails.cyclomaticMustFix` | No | `integer` | `12` | Cyclomatic complexity at which a new or changed method must be decomposed before the diff closes. |
|
|
284
266
|
| `quality.codingGuardrails.requireSiblingTest` | No | `boolean` | `false` | When true, a new source file with no colocated sibling test is reported by the guardrails pass. |
|
|
285
267
|
| `quality.autoRefresh` | No | `object` | — | Baseline-attribution auto-refresh: when a gate can prove a regression is a legitimate consequence of the diff, it rewrites the baseline instead of blocking. |
|
|
286
268
|
| `quality.autoRefresh.enabled` | No | `boolean` | `true` | Master switch for the auto-refresh path. When false, every baseline refresh is a deliberate operator action. |
|
|
@@ -310,14 +292,13 @@ Everything `/mandrel-deliver` and `single-story-close` consume: execution timeou
|
|
|
310
292
|
| `codeReview.providers[]` | No | `array<object>` | `[{"name":"native"},{"name":"security-review","scopes":["story"],"optional":true},{"name":"ultrareview","scopes":["story"],"manualPrompt":true,"when":{"label":"risk::high"}}]` | Review-provider chain (Story #2871). When unset or empty, defaults to [{ name: "native" }]. The orchestrator iterates inline entries in declaration order and merges their Finding[] before posting one structured comment; manual-prompt entries (e.g. ultrareview) contribute a trailing 'Manual review suggestions' section. Selecting an adapter whose probe fails hard-fails at factory construction unless declared `optional: true` in the chain. Each item has: name, scopes, optional, manualPrompt, when. |
|
|
311
293
|
| `codeReview.providerConfig` | No | `object` | — | Optional escape hatch for adapter-specific configuration. No documented keys in Epic #2815; reserved so future adapters can be configured without another schema migration. |
|
|
312
294
|
| `codeReview.maxFixAttempts` | No | `integer` | `3` | Maximum auto-fix retry attempts per finding in /mandrel-deliver Phase 5 (code-review). 0 disables auto-fix. Default 3. |
|
|
313
|
-
| `codeReview.maxFixScopeFiles` | No | `integer` | `5` | Maximum file count a single auto-fix may modify before escalating to agent::blocked. Default 5. |
|
|
314
295
|
| `codeReview.autoFixSeverity` | No | `"high"` \| `"medium"` | `"medium"` | Severity threshold for on-branch remediation in /mandrel-deliver Phase 5 (code-review). `medium` (default) routes 🔴/🟠/🟡 findings into the host-LLM focused-fix routing (Mediums batched per lens: one commit per lens, a single validation + rescan at the end) while 🟢 suggestions still graduate to follow-up issues; `high` reproduces the pre-4399 Critical/High-only routing. Hard cutover — no back-compat flag. |
|
|
315
296
|
| `review` | No | `object` | — | Close-scope review tuning (Story #4699). Governs the Story-scope local-lens pass that runs inside the close subprocess; the maker-blind code-review pass and all hard gates are unaffected. |
|
|
316
297
|
| `review.lensDiffFloor` | No | `integer` | — | Changed-line floor for the close-scope lens walk (Story #4699). A diff strictly below this many changed lines (additions + deletions) with zero sensitive-path hits skips lens materialization and records the skip in the findings-yield ledger. Default 40; 0 disables the skip. Hard gates and the maker-blind code-review pass are unaffected. |
|
|
317
298
|
| `refactorStage` | No | `object` | — | Opt-in, config-gated post-green refactor checkpoint wired into story-deliver (Story #3430, Epic #3418). Strictly additive and default-OFF: when disabled, story-deliver behaves exactly as before. Advisory only — never changes existing close-validation gate semantics. |
|
|
318
299
|
| `refactorStage.enabled` | No | `boolean` | `false` | When true, story-deliver runs an advisory post-green refactor stage (core/code-review-and-quality skill, Post-Green Refactor Pass) after the suite is green. Default false — when unset the stage is skipped and close-validation gate semantics are unchanged. |
|
|
319
|
-
| `acceptanceEval` | No | `object` | — | Story #3819. Bounded per-Story acceptance self-eval loop. After the implementation commits land and before the Story-implementation phase flips to `closing`, an independent (fresh-context) critic pass scores the caller-injected change set against each inline `acceptance[]` item, redrafts the unmet items, and re-evaluates — capped at `maxRounds` redraft rounds, then escalates to `agent::blocked` when criteria remain unmet. There is no `enabled` flag: the
|
|
320
|
-
| `acceptanceEval.maxRounds` | No | `integer` | `2` | Maximum number of redraft rounds before escalation. Default 2;
|
|
300
|
+
| `acceptanceEval` | No | `object` | — | Story #3819. Bounded per-Story acceptance self-eval loop. After the implementation commits land and before the Story-implementation phase flips to `closing`, an independent (fresh-context) critic pass scores the caller-injected change set against each inline `acceptance[]` item, redrafts the unmet items, and re-evaluates — capped at `maxRounds` redraft rounds (0 = scored once, no redraft), then escalates to `agent::blocked` when criteria remain unmet. There is no `enabled` flag: the scoring pass is a hard cutover (always on). |
|
|
301
|
+
| `acceptanceEval.maxRounds` | No | `integer` | `2` | Maximum number of redraft rounds before escalation. Default 2; 0 means the verdict is scored once with no redraft round (Story #5313 dropped the hard ceiling and the floor-of-one clamp). |
|
|
321
302
|
| `feedbackLoop` | No | `object` | — | Opt-out toggles for the close-time auto-file graduators. All default to auto-filing on. |
|
|
322
303
|
| `feedbackLoop.auditResultsAutoFile` | No | `boolean` | `true` | When true (default), the close-time audit-results graduator auto-files non-blocking audit-results findings as follow-up issues routed by source classification. Set to false to suppress auto-filing; findings remain accessible in the structured comments on the Story. |
|
|
323
304
|
| `feedbackLoop.retroProposals` | No | `boolean` | `true` | When true (default), the retro auto-files its actionable routed proposals as meta::<framework-gap\|consumer-improvement> + friction::<category> issues via the graduator pre-parsed-findings seam, and the rendered retro sections list the filed issue numbers instead of paste-ready gh command stanzas. Set to false to fall back to the command stanzas. |
|
|
@@ -335,10 +316,9 @@ Everything `/mandrel-deliver` and `single-story-close` consume: execution timeou
|
|
|
335
316
|
| `ci.blockOnAdvisoryFailure` | No | `boolean` | `true` | Story #5096. When true (default), delivery refuses to arm — and disarms — GitHub native auto-merge while a non-required (advisory) check is genuinely red on the PR head and GitHub reports the PR mergeable anyway (mergeStateStatus=UNSTABLE). `--auto` waits on REQUIRED contexts only, so without this a red advisory quality gate merges unattended. Set false to restore the pre-#5096 behaviour verbatim. |
|
|
336
317
|
| `ci.advisoryAllowlist` | No | `array<string>` | `[]` | Story #5096. Check-run names exempt from blockOnAdvisoryFailure — a red run whose name matches exactly never blocks arming. Matching is exact; an unnamed run can never match and always blocks. |
|
|
337
318
|
| `ci.rerunAdvisory` | No | `integer` | `0` | Story #5266. How many times close may re-run a failed advisory workflow run before blocking on it, per close invocation. Default 0: close spends no CI minutes and issues no GitHub mutation on an advisory red unless asked. At n > 0 the failed run(s) are re-run within that allowance and the merge wait re-polls inside its existing budget, landing or blocking on the re-run verdict. Overridden per invocation by --rerun-advisory <n>. |
|
|
338
|
-
| `routing` | No | `object` | — | v2 delivery-spawn routing: role-scoped boot contexts and
|
|
319
|
+
| `routing` | No | `object` | — | v2 delivery-spawn routing: role-scoped boot contexts and the ceremony profile. The v1 singleDelivery epic-route kill-switch was removed in Stage 6; the freshCriticSampleRate sampling floor was retired in Story #5313. |
|
|
339
320
|
| `routing.roleScopedAgents` | No | `boolean` | `true` | Epic #4478 (M7-B). Kill-switch for the role-scoped boot contexts. When true (default), a converted delivery spawn (`story-worker`, `acceptance-critic`) boots on its own `.claude/agents/<role>.md` system prompt instead of re-paying the full CLAUDE.md @-import closure. When false, every converted spawn falls back to `subagent_type: general-purpose` — the instant, code-rollback-free per-consumer revert, and the universal escape for hosts that ignore `.claude/agents/`. The fallback is the full-closure agent that ran before M7-B, so flipping it off never drops a gate. |
|
|
340
|
-
| `routing.
|
|
341
|
-
| `routing.ceremonyProfile` | No | `"minimal"` \| `"standard"` \| `"strict"` | `"standard"` | Acceptance-ceremony depth. minimal = always inline critic; strict = always fresh-context critic; standard (default) = routed off the change level derived from the Story diff, with the maker-checker sampling floor. |
|
|
321
|
+
| `routing.ceremonyProfile` | No | `"minimal"` \| `"standard"` \| `"strict"` | `"standard"` | Acceptance-ceremony depth. minimal = always inline critic; strict = always fresh-context critic; standard (default) = routed off the change level derived from the Story diff: high or underivable → fresh, low → inline. |
|
|
342
322
|
| `routing.closeAndLand` | No | `boolean` | `true` | When true (default), single-story-close lands through merge in one close. Opt out per-run with --no-wait-merge. |
|
|
343
323
|
|
|
344
324
|
### `qa` (optional)
|
|
@@ -88,7 +88,8 @@ over-ceiling envelope or an over-budget Story count.
|
|
|
88
88
|
> on planner-context size. Separately, the `ContextEnvelope` SDK this section
|
|
89
89
|
> used to credit with limiting hydrated prompt size had no production caller
|
|
90
90
|
> and was deleted in Story #5005; only its `estimateTokens` helper survived,
|
|
91
|
-
>
|
|
91
|
+
> now private to `lib/audit-suite/checklist-threading.js` (Story #5312 deleted
|
|
92
|
+
> `spec-spill.js` with the Spec token budget).
|
|
92
93
|
|
|
93
94
|
### Planner-context envelope (`/mandrel-plan`)
|
|
94
95
|
|
|
@@ -120,9 +121,8 @@ over-ceiling envelope or an over-budget Story count.
|
|
|
120
121
|
|
|
121
122
|
### Session-mass capacity (plan-time sizing)
|
|
122
123
|
|
|
123
|
-
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
override via `opts.modelCapacity` on validateTickets / runPlanPersist only.
|
|
124
|
+
- **Retired (Story #5312).** `DEFAULT_MODEL_CAPACITY` and the plan-time
|
|
125
|
+
Story sizing ceilings are gone: a Story is as large as the work needs, and
|
|
126
|
+
nothing at plan time scores its authored mass.
|
|
127
127
|
- **Host runtime**: session billing, quota exhaustion, and operator overrides
|
|
128
128
|
are enforced by your provider (e.g. Claude Code), not by Mandrel scripts.
|
|
@@ -302,8 +302,9 @@ default and the deep-merge extender form).
|
|
|
302
302
|
|
|
303
303
|
## Cyclomatic ceiling ratchet
|
|
304
304
|
|
|
305
|
-
|
|
306
|
-
|
|
305
|
+
A fixed per-function complexity ceiling of `12` is enforced by
|
|
306
|
+
`check-cyclomatic.js` (`lib/cyclomatic-ceiling.js#CYCLOMATIC_CEILING`; the
|
|
307
|
+
`cyclomaticMustFix` config key was retired in Story #5313). It is a
|
|
307
308
|
**standalone ratchet** — the same slot as `check-arch-cycles.js`,
|
|
308
309
|
`check-dead-exports.js`, and `check-context-budget.js` — not a
|
|
309
310
|
`delivery.quality.gates` kind, so it needs no gate block and no floor.
|
|
@@ -330,9 +331,10 @@ The scan reuses `delivery.quality.gates.maintainability.targetDirs` /
|
|
|
330
331
|
`ignoreGlobs` — both instruments read the same coverage-free escomplex
|
|
331
332
|
surface, so a separate scope declaration could only ever restate it.
|
|
332
333
|
|
|
333
|
-
`cyclomaticFlag` (default `8`) is the
|
|
334
|
-
|
|
335
|
-
|
|
334
|
+
`cyclomaticFlag` (default `8`) is the one advisory knob: it is not gated, and
|
|
335
|
+
names the ceiling `quality:preview` counts new methods against in its
|
|
336
|
+
`new-method count over c=<flag>` column. The preview also lists every scanned
|
|
337
|
+
method at cyclomatic 12 or above as an advisory and exits 0 on it.
|
|
336
338
|
|
|
337
339
|
---
|
|
338
340
|
|
|
@@ -825,8 +827,7 @@ correct shape for a gate with no rescoring path of its own.
|
|
|
825
827
|
## HITL blocker escalation
|
|
826
828
|
|
|
827
829
|
`risk::high` is planning/audit metadata only — it never pauses runtime. The
|
|
828
|
-
sole runtime HITL pause point is `agent::blocked
|
|
829
|
-
is the rubric for what should escalate. The full model is owned by
|
|
830
|
+
sole runtime HITL pause point is `agent::blocked`. The full model is owned by
|
|
830
831
|
[`.agents/instructions.md`](../instructions.md) § 1.J and
|
|
831
832
|
[`SDLC.md` § HITL model](SDLC.md#hitl-human-in-the-loop-model).
|
|
832
833
|
|
package/.agents/instructions.md
CHANGED
|
@@ -96,8 +96,7 @@ metadata only — no automatic runtime pause. The single runtime pause
|
|
|
96
96
|
point is **`agent::blocked`**: on an unresolvable blocker or an unsafe
|
|
97
97
|
destructive action without explicit authorization, transition to
|
|
98
98
|
`agent::blocked`, summarize the blocker, and wait for operator resume
|
|
99
|
-
(`agent::executing` or equivalent)
|
|
100
|
-
`planning.riskHeuristics` in `.agentrc.json`.
|
|
99
|
+
(`agent::executing` or equivalent).
|
|
101
100
|
|
|
102
101
|
### K. Precedence & Conflict Resolution
|
|
103
102
|
|
|
@@ -113,8 +112,8 @@ always wins regardless of tier.
|
|
|
113
112
|
## 2. FinOps & Token Budgeting (Economic Guardrails)
|
|
114
113
|
|
|
115
114
|
Mandrel does not enforce live LLM spend; your host owns session quota.
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
The one fixed framework ceiling (the `/mandrel-plan` context envelope)
|
|
116
|
+
truncates with a note naming what was cut:
|
|
118
117
|
[`docs/execution-reference.md`](docs/execution-reference.md#finops--token-budgeting-economic-guardrails).
|
|
119
118
|
|
|
120
119
|
---
|
|
@@ -169,8 +168,8 @@ Do NOT manually update issue descriptions or status fields unless prompted.
|
|
|
169
168
|
### B. Ticket hierarchy
|
|
170
169
|
|
|
171
170
|
The Story is the only executable ticket: `acceptance[]` / `verify[]`
|
|
172
|
-
inline plus the folded Tech Spec in `## Spec` (
|
|
173
|
-
|
|
171
|
+
inline plus the folded Tech Spec in `## Spec` (as long as the work
|
|
172
|
+
needs; never under `docs/`). Optional `depends_on`
|
|
174
173
|
edges order rare multi-Story runs, resolved by `/mandrel-deliver` from
|
|
175
174
|
live state; `plan-run::<id>` is filter metadata. Commit subjects
|
|
176
175
|
reference the Story via `(refs #<storyId>)`. There is no `type::task`.
|
|
@@ -194,9 +193,9 @@ anything under it.
|
|
|
194
193
|
|
|
195
194
|
`/mandrel-plan` sizes each Story as a **capability slice a frontier model
|
|
196
195
|
delivers and self-verifies in one pass** — a broad footprint is normal
|
|
197
|
-
when the change is cohesive
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
196
|
+
when the change is cohesive, and no plan-time ceiling scores it; do not
|
|
197
|
+
re-slice it into per-module fragments. On a `⚠️ COMPLEXITY WARNING` or
|
|
198
|
+
out-of-scope task: **plan first** (numbered cohesive sub-steps in a
|
|
199
|
+
`<!-- DECOMPOSITION -->`
|
|
201
200
|
block), **commit incrementally** per sub-step, and **fail fast** — STOP
|
|
202
201
|
and report if any sub-step fails validation.
|