mandrel 2.55.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 +4 -30
- package/.agents/docs/configuration.md +11 -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/rules/ci-remediation.md +39 -21
- package/.agents/schemas/agentrc.schema.json +28 -185
- package/.agents/schemas/story-deliver-terminal.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +107 -17
- package/.agents/scripts/audit-to-stories.js +222 -75
- 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/file-ci-gap.js +306 -0
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +15 -2
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +25 -1
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +40 -52
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +5 -1
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +162 -0
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +121 -0
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +1 -1
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +126 -0
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +11 -0
- 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 +49 -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/feedback-loop/graduator-core.js +53 -13
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +71 -25
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +18 -25
- package/.agents/scripts/lib/{audit-to-stories/ledger.js → findings/audit-ledger.js} +131 -24
- package/.agents/scripts/lib/findings/route-finding.js +38 -0
- package/.agents/scripts/lib/generated/agentrc-validator.js +1 -1
- package/.agents/scripts/lib/github/framework-repo.js +148 -2
- package/.agents/scripts/lib/label-constants.js +6 -1
- package/.agents/scripts/lib/observability/runtime-friction.js +1 -1
- package/.agents/scripts/lib/observability/source-classifier.js +2 -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/ci-gap-intake.js +605 -0
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +13 -8
- 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/audit-provenance.js +197 -0
- 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 +133 -299
- 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/run-epilogue.js +4 -4
- 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/story-follow-ups.js +32 -20
- 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/pr-watch-with-update.js +3 -2
- 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/audit-to-stories.md +63 -27
- 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 +56 -62
- package/.agents/workflows/helpers/deliver-story.md +9 -13
- package/.agents/workflows/helpers/plan-reference.md +132 -196
- package/.agents/workflows/mandrel-plan.md +28 -41
- package/.agents/workflows/memory-consolidate.md +9 -13
- package/docs/CHANGELOG.md +33 -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
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Limits
|
|
2
|
+
* Limits accessors (Epic #1720 Story #1739 — top-level reshape).
|
|
3
3
|
*
|
|
4
4
|
* Pre-reshape, every runtime ceiling lived under the legacy `agentSettings.limits.*` bag.
|
|
5
|
-
* Post-reshape, the surviving operator-configurable
|
|
6
|
-
* `
|
|
5
|
+
* Post-reshape, the surviving operator-configurable key is
|
|
6
|
+
* `delivery.execution.timeoutMs` (per-process execution timeout).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* `planning.context.{maxBytes, summaryMode}` (Story #4541 — the `applyBudget`
|
|
22
|
-
* pass they fed lost its last caller in the v2 cutover, and it bounded a field
|
|
23
|
-
* the envelope builders discarded; the live bound on planner-context size is
|
|
24
|
-
* the fixed `PLAN_CONTEXT_ENVELOPE_BYTE_CEILING` in
|
|
25
|
-
* `lib/orchestration/plan-context.js`).
|
|
8
|
+
* Dropped entirely: `maxTickets` (Story #5312 — the reviewability budget
|
|
9
|
+
* never fired on a real plan and duplicated the default-single split policy),
|
|
10
|
+
* `delivery.signals.{rework, retry}` with `SIGNALS_DEFAULTS` (Story #5313 —
|
|
11
|
+
* the detector thresholds bounded execution by count, not by risk),
|
|
12
|
+
* `maxInstructionSteps`, `friction.*`, `executionMaxBuffer`,
|
|
13
|
+
* `signals.{churn, idle, hotspot}`, `delivery.preflight`,
|
|
14
|
+
* `delivery.lease.ttlMs` (Story #5006 deleted the lease TTL: with no
|
|
15
|
+
* heartbeat source every foreign claim read live, so the window decided
|
|
16
|
+
* nothing), `delivery.maxTokenBudget` (planning no longer sizes against a
|
|
17
|
+
* token-budget envelope), and `planning.context.{maxBytes, summaryMode}`
|
|
18
|
+
* (Story #4541 — the `applyBudget` pass they fed lost its last caller in the
|
|
19
|
+
* v2 cutover; the live bound on planner-context size is the fixed
|
|
20
|
+
* `PLAN_CONTEXT_ENVELOPE_BYTE_CEILING` in `lib/orchestration/plan-context.js`).
|
|
26
21
|
*
|
|
27
22
|
* The historic combined accessor `getLimits(config)` is preserved as a
|
|
28
23
|
* compatibility surface: it returns a wrapper carrying the surviving
|
|
@@ -30,59 +25,19 @@
|
|
|
30
25
|
* working. New call sites should prefer the specific accessors below.
|
|
31
26
|
*/
|
|
32
27
|
|
|
33
|
-
/**
|
|
34
|
-
* Framework defaults for the performance-signal detector thresholds.
|
|
35
|
-
* `hotspot` was retired with its detector (Epic #4406); `churn` and `idle`
|
|
36
|
-
* were dropped earlier.
|
|
37
|
-
*/
|
|
38
|
-
export const SIGNALS_DEFAULTS = Object.freeze({
|
|
39
|
-
rework: Object.freeze({ editsPerFile: 5 }),
|
|
40
|
-
retry: Object.freeze({ repeatCount: 3 }),
|
|
41
|
-
});
|
|
42
|
-
|
|
43
28
|
/**
|
|
44
29
|
* Framework defaults for the surviving limits surface.
|
|
45
30
|
*/
|
|
46
31
|
export const LIMITS_DEFAULTS = Object.freeze({
|
|
47
|
-
maxTickets: 80,
|
|
48
32
|
executionTimeoutMs: 600000,
|
|
49
|
-
signals: SIGNALS_DEFAULTS,
|
|
50
33
|
});
|
|
51
34
|
|
|
52
|
-
/**
|
|
53
|
-
* Per-detector merge of an operator-supplied `delivery.signals.*` block
|
|
54
|
-
* with framework defaults. Each detector is shallow-overlaid so an
|
|
55
|
-
* operator can override a single threshold without re-listing the others.
|
|
56
|
-
*
|
|
57
|
-
* @param {object|undefined} userSignals
|
|
58
|
-
* @returns {{ rework: {editsPerFile: number}, retry: {repeatCount: number} }}
|
|
59
|
-
*/
|
|
60
|
-
function mergeSignals(userSignals) {
|
|
61
|
-
const user =
|
|
62
|
-
userSignals && typeof userSignals === 'object' ? userSignals : {};
|
|
63
|
-
const merged = {};
|
|
64
|
-
for (const detector of Object.keys(SIGNALS_DEFAULTS)) {
|
|
65
|
-
const userDetector =
|
|
66
|
-
user[detector] && typeof user[detector] === 'object'
|
|
67
|
-
? user[detector]
|
|
68
|
-
: {};
|
|
69
|
-
merged[detector] = { ...SIGNALS_DEFAULTS[detector], ...userDetector };
|
|
70
|
-
}
|
|
71
|
-
return merged;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
35
|
/**
|
|
75
36
|
* Resolve the surviving limits surface against a `.agentrc.json` shape
|
|
76
|
-
* (post-reshape)
|
|
77
|
-
* config); pulls `executionTimeoutMs` from `delivery.*`, pulls signals from
|
|
78
|
-
* `delivery.signals.*`.
|
|
37
|
+
* (post-reshape): `executionTimeoutMs` from `delivery.execution.*`.
|
|
79
38
|
*
|
|
80
39
|
* @param {object|undefined} config
|
|
81
|
-
* @returns {{
|
|
82
|
-
* maxTickets: number,
|
|
83
|
-
* executionTimeoutMs: number,
|
|
84
|
-
* signals: ReturnType<typeof mergeSignals>,
|
|
85
|
-
* }}
|
|
40
|
+
* @returns {{ executionTimeoutMs: number }}
|
|
86
41
|
*/
|
|
87
42
|
export function resolveLimits(config) {
|
|
88
43
|
const delivery =
|
|
@@ -94,10 +49,8 @@ export function resolveLimits(config) {
|
|
|
94
49
|
? delivery.execution
|
|
95
50
|
: {};
|
|
96
51
|
return {
|
|
97
|
-
maxTickets: LIMITS_DEFAULTS.maxTickets,
|
|
98
52
|
executionTimeoutMs:
|
|
99
53
|
execution.timeoutMs ?? LIMITS_DEFAULTS.executionTimeoutMs,
|
|
100
|
-
signals: mergeSignals(delivery.signals),
|
|
101
54
|
};
|
|
102
55
|
}
|
|
103
56
|
|
|
@@ -111,16 +64,3 @@ export function resolveLimits(config) {
|
|
|
111
64
|
export function getLimits(config) {
|
|
112
65
|
return resolveLimits(config ?? undefined);
|
|
113
66
|
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Read the merged `delivery.signals` block. Equivalent to
|
|
117
|
-
* `getLimits(config).signals` but exposed as a standalone accessor so
|
|
118
|
-
* detector wiring can import it without dragging the whole limits
|
|
119
|
-
* surface into their bundle.
|
|
120
|
-
*
|
|
121
|
-
* @param {object | null | undefined} config
|
|
122
|
-
* @returns {ReturnType<typeof resolveLimits>['signals']}
|
|
123
|
-
*/
|
|
124
|
-
export function getSignals(config) {
|
|
125
|
-
return getLimits(config).signals;
|
|
126
|
-
}
|
|
@@ -491,10 +491,15 @@ function resolveCoverageGate(userBlock) {
|
|
|
491
491
|
* before this value is ever read. `maintainability.tolerance` is the one
|
|
492
492
|
* documented MI-drop control now; see `lib/migrations/index.js` for the
|
|
493
493
|
* consumer-config migration that strips a leftover key on upgrade.
|
|
494
|
+
*
|
|
495
|
+
* `cyclomaticMustFix` was retired in Story #5313: the cyclomatic ratchet
|
|
496
|
+
* (`check-cyclomatic.js`) keeps a fixed ceiling of 12
|
|
497
|
+
* (`lib/cyclomatic-ceiling.js#CYCLOMATIC_CEILING`), and `cyclomaticFlag` is
|
|
498
|
+
* the one advisory knob left — `quality-preview.js` reports over-flag
|
|
499
|
+
* methods without failing on them.
|
|
494
500
|
*/
|
|
495
501
|
export const CODING_GUARDRAILS_DEFAULTS = Object.freeze({
|
|
496
502
|
cyclomaticFlag: 8,
|
|
497
|
-
cyclomaticMustFix: 12,
|
|
498
503
|
requireSiblingTest: false,
|
|
499
504
|
});
|
|
500
505
|
|
|
@@ -512,8 +517,6 @@ export function resolveCodingGuardrails(userBlock) {
|
|
|
512
517
|
);
|
|
513
518
|
return {
|
|
514
519
|
cyclomaticFlag: userBlock.cyclomaticFlag ?? defaults.cyclomaticFlag,
|
|
515
|
-
cyclomaticMustFix:
|
|
516
|
-
userBlock.cyclomaticMustFix ?? defaults.cyclomaticMustFix,
|
|
517
520
|
requireSiblingTest:
|
|
518
521
|
typeof userBlock.requireSiblingTest === 'boolean'
|
|
519
522
|
? userBlock.requireSiblingTest
|
|
@@ -49,10 +49,11 @@ const DEFAULT_DELIVER_RUNNER = Object.freeze({
|
|
|
49
49
|
* Default auto-fix loop ceilings for /mandrel-deliver code-review. Operators
|
|
50
50
|
* override via `delivery.codeReview.*` in `.agentrc.json` (Story #2611,
|
|
51
51
|
* Epic #2586; `autoFixSeverity` default `'medium'` per Story #4399).
|
|
52
|
+
* `maxFixScopeFiles` was retired in Story #5313 — it bounded a fix by file
|
|
53
|
+
* count rather than by risk.
|
|
52
54
|
*/
|
|
53
55
|
export const DEFAULT_CODE_REVIEW = Object.freeze({
|
|
54
56
|
maxFixAttempts: 3,
|
|
55
|
-
maxFixScopeFiles: 5,
|
|
56
57
|
autoFixSeverity: 'medium',
|
|
57
58
|
});
|
|
58
59
|
|
|
@@ -62,7 +63,7 @@ export const DEFAULT_CODE_REVIEW = Object.freeze({
|
|
|
62
63
|
* @param {object | null | undefined} config
|
|
63
64
|
* @returns {{
|
|
64
65
|
* deliverRunner: { concurrencyCap: number, footprintGuard: 'enforce'|'advisory' },
|
|
65
|
-
* codeReview: { maxFixAttempts: number,
|
|
66
|
+
* codeReview: { maxFixAttempts: number, autoFixSeverity: 'high'|'medium' },
|
|
66
67
|
* decomposer: { concurrencyCap: number },
|
|
67
68
|
* }}
|
|
68
69
|
*/
|
|
@@ -173,49 +173,6 @@ const WORKTREE_ISOLATION_SCHEMA = {
|
|
|
173
173
|
],
|
|
174
174
|
};
|
|
175
175
|
|
|
176
|
-
/**
|
|
177
|
-
* `delivery.signals` — detector thresholds for the surviving
|
|
178
|
-
* performance-signal categories. `hotspot` was retired with its detector
|
|
179
|
-
* (Epic #4406); `churn` and `idle` were dropped earlier (low signal-to-noise).
|
|
180
|
-
* Each block is shallow-merged by the resolver.
|
|
181
|
-
*/
|
|
182
|
-
const SIGNALS_SCHEMA = {
|
|
183
|
-
type: 'object',
|
|
184
|
-
description:
|
|
185
|
-
'Detector thresholds for the surviving performance-signal categories. Each block is shallow-merged by the resolver.',
|
|
186
|
-
properties: {
|
|
187
|
-
rework: {
|
|
188
|
-
type: 'object',
|
|
189
|
-
description: 'Rework detector — repeated edits to one file in a run.',
|
|
190
|
-
properties: {
|
|
191
|
-
editsPerFile: {
|
|
192
|
-
type: 'integer',
|
|
193
|
-
minimum: 1,
|
|
194
|
-
description:
|
|
195
|
-
'Edits to a single file within one run that trip the rework signal.',
|
|
196
|
-
default: LIMITS_DEFAULTS.signals.rework.editsPerFile,
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
additionalProperties: false,
|
|
200
|
-
},
|
|
201
|
-
retry: {
|
|
202
|
-
type: 'object',
|
|
203
|
-
description: 'Retry detector — the same command failing repeatedly.',
|
|
204
|
-
properties: {
|
|
205
|
-
repeatCount: {
|
|
206
|
-
type: 'integer',
|
|
207
|
-
minimum: 1,
|
|
208
|
-
description:
|
|
209
|
-
'Repeats of an identical failing command that trip the retry signal.',
|
|
210
|
-
default: LIMITS_DEFAULTS.signals.retry.repeatCount,
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
|
-
additionalProperties: false,
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
additionalProperties: false,
|
|
217
|
-
};
|
|
218
|
-
|
|
219
176
|
/**
|
|
220
177
|
* `delivery.mergeWatch` — knobs consumed by the close-and-land merge wait
|
|
221
178
|
* listener (Story #2896, Epic #2880) and by the close-and-land merge wait
|
|
@@ -294,19 +251,19 @@ const MERGE_WATCH_SCHEMA = {
|
|
|
294
251
|
* (`CODE_REVIEW_SCHEMA` imported from the quality schema module).
|
|
295
252
|
*/
|
|
296
253
|
|
|
297
|
-
// Epic #4478 (M7-B) — role-scoped-agent kill-switch
|
|
254
|
+
// Epic #4478 (M7-B) — role-scoped-agent kill-switch.
|
|
298
255
|
// Stage 6 dropped `delivery.routing.singleDelivery` (v1 epic route switch).
|
|
299
256
|
// `delivery.routing.roleScopedAgents` (default true via getDeliveryRouting)
|
|
300
257
|
// flips converted delivery spawns onto their `.claude/agents/<role>.md` boot
|
|
301
258
|
// context; false falls back to `subagent_type: general-purpose` (the instant
|
|
302
259
|
// per-consumer revert + the escape for hosts that ignore `.claude/agents/`).
|
|
303
|
-
// `delivery.routing.freshCriticSampleRate` (
|
|
304
|
-
// maker-checker sampling floor
|
|
305
|
-
//
|
|
260
|
+
// Story #5313 retired `delivery.routing.freshCriticSampleRate` (the
|
|
261
|
+
// maker-checker sampling floor): the standard profile now routes purely off
|
|
262
|
+
// the derived change level.
|
|
306
263
|
const ROUTING_SCHEMA = {
|
|
307
264
|
type: 'object',
|
|
308
265
|
description:
|
|
309
|
-
'v2 delivery-spawn routing: role-scoped boot contexts and
|
|
266
|
+
'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.',
|
|
310
267
|
properties: {
|
|
311
268
|
roleScopedAgents: {
|
|
312
269
|
type: 'boolean',
|
|
@@ -314,19 +271,11 @@ const ROUTING_SCHEMA = {
|
|
|
314
271
|
'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.',
|
|
315
272
|
default: DELIVERY_ROUTING_DEFAULTS.roleScopedAgents,
|
|
316
273
|
},
|
|
317
|
-
freshCriticSampleRate: {
|
|
318
|
-
type: 'number',
|
|
319
|
-
minimum: 0,
|
|
320
|
-
maximum: 1,
|
|
321
|
-
description:
|
|
322
|
-
'Epic #4478 (M7-B, Part 2). Maker-checker sampling floor. Under the standard profile, a change set touching no sensitive path routes its acceptance clusters down the contract-identical inline critic path, but this fraction of them is still forced through a fresh-context critic so a low derived level never means zero independent checking. Clamped to [0, 1]; 0 disables the floor, 1 forces every cluster fresh. Consumed by resolveCeremonyForRisk (lib/orchestration/ceremony-routing.js).',
|
|
323
|
-
default: DELIVERY_ROUTING_DEFAULTS.freshCriticSampleRate,
|
|
324
|
-
},
|
|
325
274
|
ceremonyProfile: {
|
|
326
275
|
type: 'string',
|
|
327
276
|
enum: ['minimal', 'standard', 'strict'],
|
|
328
277
|
description:
|
|
329
|
-
'Acceptance-ceremony depth. minimal = always inline critic; strict = always fresh-context critic; standard (default) = routed off the change level derived from the Story diff
|
|
278
|
+
'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.',
|
|
330
279
|
default: DELIVERY_ROUTING_DEFAULTS.ceremonyProfile,
|
|
331
280
|
},
|
|
332
281
|
closeAndLand: {
|
|
@@ -458,23 +407,22 @@ const REFACTOR_STAGE_SCHEMA = {
|
|
|
458
407
|
* re-evaluates — capped at `maxRounds` redraft rounds.
|
|
459
408
|
*
|
|
460
409
|
* `maxRounds` is the operator-tunable redraft ceiling (default 2 via
|
|
461
|
-
* `lib/config/acceptance-eval.js`).
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
* hard cutover, always on, per `rules/git-conventions.md`.
|
|
410
|
+
* `lib/config/acceptance-eval.js`). Story #5313 dropped the hard ceiling and
|
|
411
|
+
* the floor-of-one clamp: `maxRounds: 0` is valid and means one pass scored
|
|
412
|
+
* once with no redraft round. There is intentionally **no** `enabled` flag —
|
|
413
|
+
* the scoring pass is a hard cutover, always on, per
|
|
414
|
+
* `rules/git-conventions.md`.
|
|
467
415
|
*/
|
|
468
416
|
const ACCEPTANCE_EVAL_SCHEMA = {
|
|
469
417
|
type: 'object',
|
|
470
418
|
description:
|
|
471
|
-
'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
|
|
419
|
+
'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).',
|
|
472
420
|
properties: {
|
|
473
421
|
maxRounds: {
|
|
474
422
|
type: 'integer',
|
|
475
|
-
minimum:
|
|
423
|
+
minimum: 0,
|
|
476
424
|
description:
|
|
477
|
-
'Maximum number of redraft rounds before escalation. Default 2;
|
|
425
|
+
'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).',
|
|
478
426
|
default: ACCEPTANCE_EVAL_DEFAULTS.maxRounds,
|
|
479
427
|
},
|
|
480
428
|
},
|
|
@@ -656,14 +604,13 @@ const TEMP_RETENTION_SCHEMA = {
|
|
|
656
604
|
export const DELIVERY_SCHEMA = {
|
|
657
605
|
type: 'object',
|
|
658
606
|
description:
|
|
659
|
-
'Everything `/mandrel-deliver` and `single-story-close` consume: execution timeouts, worktree isolation, runner concurrency, docs freshness,
|
|
607
|
+
'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.',
|
|
660
608
|
properties: {
|
|
661
609
|
execution: EXECUTION_SCHEMA,
|
|
662
610
|
docsFreshness: DOCS_FRESHNESS_SCHEMA,
|
|
663
611
|
tempRetention: TEMP_RETENTION_SCHEMA,
|
|
664
612
|
deliverRunner: DELIVER_RUNNER_SCHEMA,
|
|
665
613
|
worktreeIsolation: WORKTREE_ISOLATION_SCHEMA,
|
|
666
|
-
signals: SIGNALS_SCHEMA,
|
|
667
614
|
// `quality.gates.crap.incrementalCoverage` (Story #4981) is declared in
|
|
668
615
|
// `config/gates/crap.schema.js` and reaches AJV validation through this
|
|
669
616
|
// property — QUALITY_SCHEMA → GATES_SCHEMA → CRAP_GATE. No separate
|
|
@@ -40,13 +40,6 @@ const CODING_GUARDRAILS_SCHEMA = {
|
|
|
40
40
|
'Cyclomatic complexity at which a new or changed method is flagged for a refactor look.',
|
|
41
41
|
default: CODING_GUARDRAILS_DEFAULTS.cyclomaticFlag,
|
|
42
42
|
},
|
|
43
|
-
cyclomaticMustFix: {
|
|
44
|
-
type: 'integer',
|
|
45
|
-
minimum: 1,
|
|
46
|
-
description:
|
|
47
|
-
'Cyclomatic complexity at which a new or changed method must be decomposed before the diff closes.',
|
|
48
|
-
default: CODING_GUARDRAILS_DEFAULTS.cyclomaticMustFix,
|
|
49
|
-
},
|
|
50
43
|
requireSiblingTest: {
|
|
51
44
|
type: 'boolean',
|
|
52
45
|
description:
|
|
@@ -356,13 +349,6 @@ export const CODE_REVIEW_SCHEMA = {
|
|
|
356
349
|
'Maximum auto-fix retry attempts per finding in /mandrel-deliver Phase 5 (code-review). 0 disables auto-fix. Default 3.',
|
|
357
350
|
default: DEFAULT_CODE_REVIEW.maxFixAttempts,
|
|
358
351
|
},
|
|
359
|
-
maxFixScopeFiles: {
|
|
360
|
-
type: 'integer',
|
|
361
|
-
minimum: 1,
|
|
362
|
-
description:
|
|
363
|
-
'Maximum file count a single auto-fix may modify before escalating to agent::blocked. Default 5.',
|
|
364
|
-
default: DEFAULT_CODE_REVIEW.maxFixScopeFiles,
|
|
365
|
-
},
|
|
366
352
|
autoFixSeverity: {
|
|
367
353
|
type: 'string',
|
|
368
354
|
enum: ['high', 'medium'],
|
|
@@ -16,6 +16,7 @@ import { SHELL_INJECTION_PATTERN_STRING } from './config-schema-shared.js';
|
|
|
16
16
|
// resolved AGENTRC_SCHEMA is unchanged.
|
|
17
17
|
import { DELIVERY_SCHEMA } from './config-settings-schema-delivery.js';
|
|
18
18
|
import compiledAgentrcValidator from './generated/agentrc-validator.js';
|
|
19
|
+
import { DEFAULT_FRAMEWORK_REPO } from './github/framework-repo.js';
|
|
19
20
|
import { SKILL_ID_RE } from './skills/walk-skill-files.js';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -63,22 +64,6 @@ const NULLABLE_NONEMPTY_SAFE_STRING = {
|
|
|
63
64
|
not: { type: 'string', pattern: SHELL_INJECTION_PATTERN_STRING },
|
|
64
65
|
};
|
|
65
66
|
|
|
66
|
-
/** A list-valued config key may be a plain array (replace) or an extender
|
|
67
|
-
* object `{ append, prepend }` that deep-merges with framework defaults. */
|
|
68
|
-
const LIST_OR_EXTENDER_OF_STRINGS = {
|
|
69
|
-
oneOf: [
|
|
70
|
-
{ type: 'array', items: { type: 'string' } },
|
|
71
|
-
{
|
|
72
|
-
type: 'object',
|
|
73
|
-
properties: {
|
|
74
|
-
append: { type: 'array', items: { type: 'string' } },
|
|
75
|
-
prepend: { type: 'array', items: { type: 'string' } },
|
|
76
|
-
},
|
|
77
|
-
additionalProperties: false,
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
};
|
|
81
|
-
|
|
82
67
|
/**
|
|
83
68
|
* Backwards-compatible export used by a handful of call sites that historically
|
|
84
69
|
* scanned the schema for string-shaped fields. Post-reshape, the only
|
|
@@ -386,6 +371,37 @@ const MERGE_METHODS_SCHEMA = {
|
|
|
386
371
|
additionalProperties: false,
|
|
387
372
|
};
|
|
388
373
|
|
|
374
|
+
/**
|
|
375
|
+
* Where follow-up work is filed when the repository that surfaced it does not
|
|
376
|
+
* own it. Ownership splits three ways — consumer / framework / platform — and
|
|
377
|
+
* `github.owner`/`github.repo` already carry the consumer bucket, so only the
|
|
378
|
+
* other two are configured here. Routing itself lives in
|
|
379
|
+
* `lib/github/framework-repo.js`; an unset bucket is reported as unroutable
|
|
380
|
+
* rather than silently re-pointed at the consumer's own tracker.
|
|
381
|
+
*/
|
|
382
|
+
const FOLLOW_UP_REPOS_SCHEMA = {
|
|
383
|
+
type: 'object',
|
|
384
|
+
description:
|
|
385
|
+
'Repository slugs for the non-consumer follow-up ownership buckets, used when a CI gap, retro proposal, or audit finding belongs to someone other than the repo that surfaced it.',
|
|
386
|
+
properties: {
|
|
387
|
+
framework: {
|
|
388
|
+
type: 'string',
|
|
389
|
+
pattern: '^[^/\\s]+/[^/\\s]+$',
|
|
390
|
+
description:
|
|
391
|
+
'`<owner>/<repo>` that owns framework-level defects. Defaults to the Mandrel mirror — the one bucket with a knowable default.',
|
|
392
|
+
default: DEFAULT_FRAMEWORK_REPO,
|
|
393
|
+
},
|
|
394
|
+
platform: {
|
|
395
|
+
type: ['string', 'null'],
|
|
396
|
+
pattern: '^[^/\\s]+/[^/\\s]+$',
|
|
397
|
+
description:
|
|
398
|
+
'`<owner>/<repo>` for a shared platform or infrastructure tracker (a shared base config, a runner fleet, a cross-repo toolchain). No default — nothing can guess a shared repo. Left unset, platform-owned findings file locally and say so.',
|
|
399
|
+
default: null,
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
additionalProperties: false,
|
|
403
|
+
};
|
|
404
|
+
|
|
389
405
|
const GITHUB_SCHEMA = {
|
|
390
406
|
type: 'object',
|
|
391
407
|
description:
|
|
@@ -432,6 +448,7 @@ const GITHUB_SCHEMA = {
|
|
|
432
448
|
'Default `timeoutMs` applied to every `gh` subprocess the provider facade spawns, so a stalled socket or long-poll cannot hang an orchestration indefinitely. A `GhExecTimeoutError` from a hit ceiling is classified `transient` and retried by `withTransientRetry`. Story #2860.',
|
|
433
449
|
default: 60000,
|
|
434
450
|
},
|
|
451
|
+
followUpRepos: FOLLOW_UP_REPOS_SCHEMA,
|
|
435
452
|
branchProtection: BRANCH_PROTECTION_SCHEMA,
|
|
436
453
|
mergeMethods: MERGE_METHODS_SCHEMA,
|
|
437
454
|
notifications: NOTIFICATIONS_SCHEMA,
|
|
@@ -461,149 +478,38 @@ const GITHUB_SCHEMA = {
|
|
|
461
478
|
// `planning` carries `additionalProperties: false`, so a resurrected key fails
|
|
462
479
|
// loudly; the 2.20.0 retirement migration strips it on upgrade.
|
|
463
480
|
|
|
481
|
+
// Story #5312 — the planning diet. `riskHeuristics`, `complexityGate`,
|
|
482
|
+
// `memoryPool.{staleAfterDays, growthDelta}`, `failOnSharedEditors`,
|
|
483
|
+
// `requireExplicitCrossStoryDeps`, `failOnRegistryConflicts`,
|
|
484
|
+
// `failOnLargeFanOut`, `largeFanOutThreshold` and `crossCuttingRegistries`
|
|
485
|
+
// were retired together: every one either never fired on real work, duplicated
|
|
486
|
+
// a judgment the authoring model already makes, or guarded a consumer that no
|
|
487
|
+
// longer exists. The block stays `additionalProperties: false`, so a config
|
|
488
|
+
// still carrying one fails loudly; the 2.57.0 retirement migration strips them
|
|
489
|
+
// on upgrade.
|
|
490
|
+
|
|
464
491
|
const PLANNING_SCHEMA = {
|
|
465
492
|
type: 'object',
|
|
466
493
|
description:
|
|
467
|
-
'Inputs to `/mandrel-plan`:
|
|
494
|
+
'Inputs to `/mandrel-plan`: the memory-hygiene advisory ceiling and the opt-in navigability reachability gate.',
|
|
468
495
|
properties: {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
description:
|
|
472
|
-
'Prose heuristics the planner escalates a Story against. A plain array replaces the framework list; the `{ append, prepend }` extender form deep-merges with it.',
|
|
473
|
-
default: [
|
|
474
|
-
'Destructive or irreversible data mutations (dropping tables, deleting rows without soft-delete or backup, truncating production state).',
|
|
475
|
-
'Modifications to shared security or auth infrastructure (IAM policies, auth middleware, session or token handling, secret rotation).',
|
|
476
|
-
'Changes to CI/CD, deployment pipelines, or release gating that could disable safety checks or ship unverified code to production.',
|
|
477
|
-
'Monorepo-wide AST or text replacements touching overlapping files in parallel (catastrophic merge-conflict risk across concurrent agents).',
|
|
478
|
-
'Schema migrations that rewrite existing rows or drop columns without a backfill or rollback plan.',
|
|
479
|
-
],
|
|
480
|
-
},
|
|
481
|
-
// Story #4722 (superseding #4683's word-count gate) — shape-derived
|
|
482
|
-
// ceremony-lite routing. Complexity routes on the objective shape of the
|
|
483
|
-
// authored work (changes[] count, acceptance count, creates-vs-refactors
|
|
484
|
-
// mix, sensitive-path classes), never on seed word count: `maxSeedWords`
|
|
485
|
-
// was removed in the hard cutover and is rejected as an additional
|
|
486
|
-
// property. The lite path never relaxes a non-negotiable (Story ticket,
|
|
487
|
-
// PR-to-main, repo gates, security baseline). Defaults live on
|
|
488
|
-
// DEFAULT_COMPLEXITY_GATE in `lib/orchestration/complexity-gate.js`;
|
|
489
|
-
// shape ceilings are the framework constants STORY_SHAPE_CEILINGS.
|
|
490
|
-
complexityGate: {
|
|
491
|
-
type: 'object',
|
|
492
|
-
description:
|
|
493
|
-
'Shape-derived ceremony-lite complexity routing. A lite claim is validated against the authored Story shape at persist and re-derived from the Story body at dispatch; conservative (full on any doubt). Never relaxes the Story-ticket / PR-to-main / repo-gates / security-baseline non-negotiables.',
|
|
494
|
-
properties: {
|
|
495
|
-
enabled: {
|
|
496
|
-
type: 'boolean',
|
|
497
|
-
description:
|
|
498
|
-
'Master switch. When false, lite routing is disabled everywhere: persist refuses lite claims and dispatch always takes the sub-agent path. Default true.',
|
|
499
|
-
},
|
|
500
|
-
maxArtifacts: {
|
|
501
|
-
type: 'integer',
|
|
502
|
-
minimum: 0,
|
|
503
|
-
description:
|
|
504
|
-
'Enumerated-artifact threshold reported by the plan-context complexity signals. An input signal for the planner verdict — carries no routing authority. Default 1.',
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
|
-
additionalProperties: false,
|
|
508
|
-
},
|
|
509
|
-
// Story #5182 — the `/mandrel-plan` Phase 0 memory-hygiene advisory's two
|
|
510
|
-
// arms. The count arm this replaced was an absolute ceiling, which no
|
|
511
|
-
// consolidation pass could ever bring a pool back under; `growthDelta`
|
|
512
|
-
// measures entries written since the last pass instead, which a pass
|
|
513
|
-
// does reset. Both are advisory thresholds — nothing here gates a plan.
|
|
496
|
+
// The `/mandrel-plan` Phase 0 memory-hygiene advisory's one surviving
|
|
497
|
+
// arm (Story #5285; the age and growth arms went with Story #5312).
|
|
514
498
|
memoryPool: {
|
|
515
499
|
type: 'object',
|
|
516
500
|
description:
|
|
517
|
-
'
|
|
501
|
+
'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.',
|
|
518
502
|
properties: {
|
|
519
|
-
staleAfterDays: {
|
|
520
|
-
type: 'integer',
|
|
521
|
-
minimum: 1,
|
|
522
|
-
description:
|
|
523
|
-
"Recommend a consolidation pass once the pool's stamp is older than this many days. Default 30.",
|
|
524
|
-
default: 30,
|
|
525
|
-
},
|
|
526
|
-
growthDelta: {
|
|
527
|
-
type: 'integer',
|
|
528
|
-
minimum: 1,
|
|
529
|
-
description:
|
|
530
|
-
'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.',
|
|
531
|
-
default: 25,
|
|
532
|
-
},
|
|
533
503
|
indexByteCeiling: {
|
|
534
504
|
type: 'integer',
|
|
535
505
|
minimum: 1,
|
|
536
506
|
description:
|
|
537
|
-
"Recommend a consolidation pass once the pool's `MEMORY.md` index exceeds this many bytes.
|
|
507
|
+
"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.",
|
|
538
508
|
default: 24576,
|
|
539
509
|
},
|
|
540
510
|
},
|
|
541
511
|
additionalProperties: false,
|
|
542
512
|
},
|
|
543
|
-
|
|
544
|
-
// Cross-Story conflict-finding severity gates. Off by default so
|
|
545
|
-
// existing repos keep advisory-only behaviour; flipping either to
|
|
546
|
-
// `true` upgrades the matching finding class to `'hard'`, which routes
|
|
547
|
-
// it through the validator's `errors[]` channel and trips the bounded
|
|
548
|
-
// decompose loop's re-prompt gate.
|
|
549
|
-
// `planning.modelCapacity` was collapsed to the framework constant
|
|
550
|
-
// `DEFAULT_MODEL_CAPACITY` in ticket-validator-sizing.js (authored-
|
|
551
|
-
// tokens-only mass); setting it in a config is rejected as an
|
|
552
|
-
// additional property.
|
|
553
|
-
failOnSharedEditors: {
|
|
554
|
-
type: 'boolean',
|
|
555
|
-
description:
|
|
556
|
-
'When true, upgrade shared-editor conflict findings to hard errors (default false — advisory soft findings only).',
|
|
557
|
-
default: false,
|
|
558
|
-
},
|
|
559
|
-
requireExplicitCrossStoryDeps: {
|
|
560
|
-
type: 'boolean',
|
|
561
|
-
description:
|
|
562
|
-
'When true, upgrade implicit cross-Story dependency findings to hard errors (default false — advisory soft findings only).',
|
|
563
|
-
default: false,
|
|
564
|
-
},
|
|
565
|
-
// Cross-cutting registry conflict knobs consumed by
|
|
566
|
-
// `ticket-validator-conflicts.js` (wired through
|
|
567
|
-
// `epic-plan-decompose/phases/planning-artifacts.js`).
|
|
568
|
-
// `crossCuttingRegistries` names the registry paths whose concurrent
|
|
569
|
-
// edits are flagged; `failOnRegistryConflicts` upgrades that finding to
|
|
570
|
-
// `'hard'`. `failOnLargeFanOut` / `largeFanOutThreshold` gate the
|
|
571
|
-
// delete blast-radius finding (call sites of a module a Story marks
|
|
572
|
-
// `assumption: "deletes"`).
|
|
573
|
-
crossCuttingRegistries: {
|
|
574
|
-
...LIST_OR_EXTENDER_OF_STRINGS,
|
|
575
|
-
description:
|
|
576
|
-
'Registry path patterns whose concurrent edits across Stories are flagged as conflicts. Defaults to the framework listener/handler index patterns when omitted.',
|
|
577
|
-
// Mirrors DEFAULT_REGISTRY_PATTERNS in
|
|
578
|
-
// `lib/orchestration/ticket-validator-conflicts.js`. Restated rather
|
|
579
|
-
// than imported: that module pulls in the story-body parser and the
|
|
580
|
-
// reachability walker, which have no business loading behind a schema
|
|
581
|
-
// declaration. The rewritten parity suite asserts the two agree.
|
|
582
|
-
default: [
|
|
583
|
-
'lib/orchestration/lifecycle/listeners/index.js',
|
|
584
|
-
'**/listeners/index.js',
|
|
585
|
-
'**/handlers/index.js',
|
|
586
|
-
],
|
|
587
|
-
},
|
|
588
|
-
failOnRegistryConflicts: {
|
|
589
|
-
type: 'boolean',
|
|
590
|
-
description:
|
|
591
|
-
'When true, upgrade cross-cutting registry conflict findings to hard errors (default false).',
|
|
592
|
-
default: false,
|
|
593
|
-
},
|
|
594
|
-
failOnLargeFanOut: {
|
|
595
|
-
type: 'boolean',
|
|
596
|
-
description:
|
|
597
|
-
'When true, upgrade fan-out-warning findings (delete blast radius) to hard errors (default false — soft advisory).',
|
|
598
|
-
default: false,
|
|
599
|
-
},
|
|
600
|
-
largeFanOutThreshold: {
|
|
601
|
-
type: 'integer',
|
|
602
|
-
minimum: 0,
|
|
603
|
-
description:
|
|
604
|
-
'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.',
|
|
605
|
-
default: 10,
|
|
606
|
-
},
|
|
607
513
|
// Navigability-reachability config consumed by the plan-persist draft
|
|
608
514
|
// reachability gate (Epic #4131 F7; demoted into persist by #4474 PR6).
|
|
609
515
|
// Opt-in: absent or empty routeGlobs degrades to a silent no-op.
|
|
@@ -648,7 +554,7 @@ const PLANNING_SCHEMA = {
|
|
|
648
554
|
* - `project` — identity, paths, commands, docs context.
|
|
649
555
|
* - `github` — provider identity, branch protection, merge methods,
|
|
650
556
|
* notifications.
|
|
651
|
-
* - `planning` —
|
|
557
|
+
* - `planning` — the memory-hygiene advisory ceiling, navigability gate.
|
|
652
558
|
* - `delivery` — execution timeouts, worktree isolation, deliver-runner
|
|
653
559
|
* concurrency, docs-freshness, signals, quality.
|
|
654
560
|
*
|