mandrel 1.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.
Files changed (843) hide show
  1. package/.agents/README.md +954 -0
  2. package/.agents/docs/SDLC.md +1420 -0
  3. package/.agents/docs/agentrc-reference.json +278 -0
  4. package/.agents/docs/configuration.md +1040 -0
  5. package/.agents/docs/workflows.md +59 -0
  6. package/.agents/instructions.md +384 -0
  7. package/.agents/personas/architect.md +107 -0
  8. package/.agents/personas/devops-engineer.md +36 -0
  9. package/.agents/personas/engineer-mobile.md +119 -0
  10. package/.agents/personas/engineer-web.md +110 -0
  11. package/.agents/personas/engineer.md +90 -0
  12. package/.agents/personas/product.md +88 -0
  13. package/.agents/personas/project-manager.md +110 -0
  14. package/.agents/personas/qa-engineer.md +91 -0
  15. package/.agents/personas/refactorer.md +110 -0
  16. package/.agents/personas/security-engineer.md +112 -0
  17. package/.agents/personas/sre.md +86 -0
  18. package/.agents/personas/technical-writer.md +100 -0
  19. package/.agents/personas/ux-designer.md +95 -0
  20. package/.agents/rules/api-conventions.md +75 -0
  21. package/.agents/rules/changelog-style.md +238 -0
  22. package/.agents/rules/gherkin-standards.md +146 -0
  23. package/.agents/rules/git-conventions.md +146 -0
  24. package/.agents/rules/orchestration-error-handling.md +35 -0
  25. package/.agents/rules/security-baseline.md +92 -0
  26. package/.agents/rules/shell-conventions.md +70 -0
  27. package/.agents/rules/test-seams.md +59 -0
  28. package/.agents/rules/testing-standards.md +177 -0
  29. package/.agents/runtime-deps.json +18 -0
  30. package/.agents/schemas/acceptance-eval-verdict.schema.json +93 -0
  31. package/.agents/schemas/agentrc.schema.json +1583 -0
  32. package/.agents/schemas/audit-results.schema.json +69 -0
  33. package/.agents/schemas/audit-rules.json +134 -0
  34. package/.agents/schemas/audit-rules.schema.json +69 -0
  35. package/.agents/schemas/baselines/baseline-envelope.schema.json +44 -0
  36. package/.agents/schemas/baselines/bundle-size.schema.json +47 -0
  37. package/.agents/schemas/baselines/coverage.schema.json +50 -0
  38. package/.agents/schemas/baselines/crap.schema.json +52 -0
  39. package/.agents/schemas/baselines/duplication.schema.json +62 -0
  40. package/.agents/schemas/baselines/lighthouse.schema.json +59 -0
  41. package/.agents/schemas/baselines/lint.schema.json +47 -0
  42. package/.agents/schemas/baselines/maintainability.schema.json +71 -0
  43. package/.agents/schemas/baselines/mutation.schema.json +52 -0
  44. package/.agents/schemas/crap-baseline.schema.json +57 -0
  45. package/.agents/schemas/crap-report.schema.json +102 -0
  46. package/.agents/schemas/dispatch-manifest.json +232 -0
  47. package/.agents/schemas/epic-perf-report.schema.json +89 -0
  48. package/.agents/schemas/epic-spec.schema.json +183 -0
  49. package/.agents/schemas/friction-event.schema.json +56 -0
  50. package/.agents/schemas/lifecycle/README.md +18 -0
  51. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +13 -0
  52. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +13 -0
  53. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +13 -0
  54. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +12 -0
  55. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +13 -0
  56. package/.agents/schemas/lifecycle/checkpoint.written.schema.json +13 -0
  57. package/.agents/schemas/lifecycle/close-validate.end.schema.json +18 -0
  58. package/.agents/schemas/lifecycle/close-validate.start.schema.json +13 -0
  59. package/.agents/schemas/lifecycle/code-review.end.schema.json +30 -0
  60. package/.agents/schemas/lifecycle/code-review.start.schema.json +12 -0
  61. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +14 -0
  62. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +13 -0
  63. package/.agents/schemas/lifecycle/epic.blocked.schema.json +13 -0
  64. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +12 -0
  65. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +12 -0
  66. package/.agents/schemas/lifecycle/epic.close.end.schema.json +12 -0
  67. package/.agents/schemas/lifecycle/epic.complete.schema.json +13 -0
  68. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +13 -0
  69. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +12 -0
  70. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +13 -0
  71. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +14 -0
  72. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +17 -0
  73. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +15 -0
  74. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +18 -0
  75. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +12 -0
  76. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +16 -0
  77. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +12 -0
  78. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +28 -0
  79. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +16 -0
  80. package/.agents/schemas/lifecycle/intervention.recorded.schema.json +15 -0
  81. package/.agents/schemas/lifecycle/ledger-record.schema.json +59 -0
  82. package/.agents/schemas/lifecycle/notification.emitted.schema.json +18 -0
  83. package/.agents/schemas/lifecycle/pr.created.schema.json +14 -0
  84. package/.agents/schemas/lifecycle/retro.end.schema.json +16 -0
  85. package/.agents/schemas/lifecycle/retro.start.schema.json +12 -0
  86. package/.agents/schemas/lifecycle/story.blocked.schema.json +13 -0
  87. package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +17 -0
  88. package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +15 -0
  89. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +20 -0
  90. package/.agents/schemas/lifecycle/story.merged.schema.json +13 -0
  91. package/.agents/schemas/mi-report.schema.json +58 -0
  92. package/.agents/schemas/model-attribution.schema.json +49 -0
  93. package/.agents/schemas/qa-finding.schema.json +133 -0
  94. package/.agents/schemas/qa-ledger.schema.json +89 -0
  95. package/.agents/schemas/risk-verdict.schema.json +53 -0
  96. package/.agents/schemas/signal-event.schema.json +58 -0
  97. package/.agents/schemas/skill.schema.json +31 -0
  98. package/.agents/schemas/skills-index.schema.json +81 -0
  99. package/.agents/schemas/story-perf-summary.schema.json +73 -0
  100. package/.agents/schemas/validation-evidence.schema.json +78 -0
  101. package/.agents/scripts/README.md +93 -0
  102. package/.agents/scripts/acceptance-eval.js +284 -0
  103. package/.agents/scripts/acceptance-spec-reconciler.js +556 -0
  104. package/.agents/scripts/agents-bootstrap-github.js +634 -0
  105. package/.agents/scripts/analyze-execution.js +369 -0
  106. package/.agents/scripts/assert-branch.js +83 -0
  107. package/.agents/scripts/audit-labels-bootstrap.js +253 -0
  108. package/.agents/scripts/audit-to-stories.js +257 -0
  109. package/.agents/scripts/bootstrap.js +1378 -0
  110. package/.agents/scripts/check-baselines.js +81 -0
  111. package/.agents/scripts/check-dead-exports.js +311 -0
  112. package/.agents/scripts/check-doc-links.js +401 -0
  113. package/.agents/scripts/check-gherkin-placeholders.js +663 -0
  114. package/.agents/scripts/check-lifecycle-doc-drift.js +402 -0
  115. package/.agents/scripts/check-lifecycle-lint.js +379 -0
  116. package/.agents/scripts/check-prepush-recovery.js +90 -0
  117. package/.agents/scripts/check-windows-git-perf.js +138 -0
  118. package/.agents/scripts/cleanup-repo-test-temp.js +67 -0
  119. package/.agents/scripts/coverage-capture.js +112 -0
  120. package/.agents/scripts/detect-merges.js +111 -0
  121. package/.agents/scripts/diagnose-friction.js +257 -0
  122. package/.agents/scripts/diagnose.js +240 -0
  123. package/.agents/scripts/dispatcher.js +295 -0
  124. package/.agents/scripts/drain-pending-cleanup.js +147 -0
  125. package/.agents/scripts/epic-audit-prepare.js +419 -0
  126. package/.agents/scripts/epic-audit-recheck.js +241 -0
  127. package/.agents/scripts/epic-deliver-note-intervention.js +192 -0
  128. package/.agents/scripts/epic-deliver-preflight.js +407 -0
  129. package/.agents/scripts/epic-deliver-prepare.js +383 -0
  130. package/.agents/scripts/epic-execute-record-wave.js +463 -0
  131. package/.agents/scripts/epic-plan-clarity.js +201 -0
  132. package/.agents/scripts/epic-plan-decompose.js +79 -0
  133. package/.agents/scripts/epic-plan-healthcheck.js +363 -0
  134. package/.agents/scripts/epic-plan-spec-validate.js +111 -0
  135. package/.agents/scripts/epic-plan-spec.js +198 -0
  136. package/.agents/scripts/epic-reconcile.js +637 -0
  137. package/.agents/scripts/evidence-gate.js +235 -0
  138. package/.agents/scripts/generate-config-docs.js +516 -0
  139. package/.agents/scripts/generate-lifecycle-docs.js +224 -0
  140. package/.agents/scripts/generate-skills-index.js +252 -0
  141. package/.agents/scripts/generate-workflows-doc.js +168 -0
  142. package/.agents/scripts/git-cleanup.js +124 -0
  143. package/.agents/scripts/git-pr-quality-gate.js +203 -0
  144. package/.agents/scripts/git-rebase-and-resolve.js +234 -0
  145. package/.agents/scripts/hierarchy-gate.js +176 -0
  146. package/.agents/scripts/hydrate-context.js +179 -0
  147. package/.agents/scripts/install-matrix-assert.js +282 -0
  148. package/.agents/scripts/lib/Graph.js +326 -0
  149. package/.agents/scripts/lib/ITicketingProvider.js +349 -0
  150. package/.agents/scripts/lib/Logger.js +194 -0
  151. package/.agents/scripts/lib/audit-suite/cli.js +64 -0
  152. package/.agents/scripts/lib/audit-suite/findings.js +164 -0
  153. package/.agents/scripts/lib/audit-suite/frontmatter-lint.js +32 -0
  154. package/.agents/scripts/lib/audit-suite/frontmatter.js +110 -0
  155. package/.agents/scripts/lib/audit-suite/index.js +22 -0
  156. package/.agents/scripts/lib/audit-suite/runner.js +233 -0
  157. package/.agents/scripts/lib/audit-suite/selector.js +235 -0
  158. package/.agents/scripts/lib/audit-suite/substitutions.js +124 -0
  159. package/.agents/scripts/lib/audit-suite/workflow-loader.js +49 -0
  160. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +130 -0
  161. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +114 -0
  162. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +93 -0
  163. package/.agents/scripts/lib/audit-to-stories/group-findings.js +265 -0
  164. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +246 -0
  165. package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +160 -0
  166. package/.agents/scripts/lib/auto-refresh-baselines.js +308 -0
  167. package/.agents/scripts/lib/baseline-loader.js +0 -0
  168. package/.agents/scripts/lib/baseline-schema-registry.js +69 -0
  169. package/.agents/scripts/lib/baseline-snapshot.js +716 -0
  170. package/.agents/scripts/lib/baselines/component-matcher.js +21 -0
  171. package/.agents/scripts/lib/baselines/components.js +126 -0
  172. package/.agents/scripts/lib/baselines/diff-scope-cli.js +203 -0
  173. package/.agents/scripts/lib/baselines/duplication-scanner.js +220 -0
  174. package/.agents/scripts/lib/baselines/env-overrides.js +129 -0
  175. package/.agents/scripts/lib/baselines/envelope.js +368 -0
  176. package/.agents/scripts/lib/baselines/exit-codes.js +89 -0
  177. package/.agents/scripts/lib/baselines/git-base.js +0 -0
  178. package/.agents/scripts/lib/baselines/kernel.js +111 -0
  179. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +220 -0
  180. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +157 -0
  181. package/.agents/scripts/lib/baselines/kinds/coverage.js +194 -0
  182. package/.agents/scripts/lib/baselines/kinds/crap.js +555 -0
  183. package/.agents/scripts/lib/baselines/kinds/duplication.js +197 -0
  184. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +185 -0
  185. package/.agents/scripts/lib/baselines/kinds/lint.js +172 -0
  186. package/.agents/scripts/lib/baselines/kinds/maintainability.js +340 -0
  187. package/.agents/scripts/lib/baselines/kinds/mutation.js +153 -0
  188. package/.agents/scripts/lib/baselines/path-canon.js +279 -0
  189. package/.agents/scripts/lib/baselines/preview-gates.js +298 -0
  190. package/.agents/scripts/lib/baselines/reader.js +321 -0
  191. package/.agents/scripts/lib/baselines/refresh-service.js +733 -0
  192. package/.agents/scripts/lib/baselines/scope.js +291 -0
  193. package/.agents/scripts/lib/baselines/writer.js +312 -0
  194. package/.agents/scripts/lib/bdd-runner-detect.js +417 -0
  195. package/.agents/scripts/lib/bdd-scenario-scanner.js +310 -0
  196. package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +202 -0
  197. package/.agents/scripts/lib/bootstrap/branch-protection.js +222 -0
  198. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +171 -0
  199. package/.agents/scripts/lib/bootstrap/commit-push.js +146 -0
  200. package/.agents/scripts/lib/bootstrap/gh-list.js +153 -0
  201. package/.agents/scripts/lib/bootstrap/gh-preflight.js +306 -0
  202. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +89 -0
  203. package/.agents/scripts/lib/bootstrap/install-ledger.js +174 -0
  204. package/.agents/scripts/lib/bootstrap/manifest.js +272 -0
  205. package/.agents/scripts/lib/bootstrap/merge-methods.js +108 -0
  206. package/.agents/scripts/lib/bootstrap/preflight.js +195 -0
  207. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +801 -0
  208. package/.agents/scripts/lib/bootstrap/prompt.js +480 -0
  209. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +370 -0
  210. package/.agents/scripts/lib/bootstrap/summary.js +75 -0
  211. package/.agents/scripts/lib/bootstrap/workflow-audit.js +256 -0
  212. package/.agents/scripts/lib/branch-name-guard.js +98 -0
  213. package/.agents/scripts/lib/c8-cli-path.js +21 -0
  214. package/.agents/scripts/lib/changed-files.js +184 -0
  215. package/.agents/scripts/lib/checks/baseline-drift-main-checkout.js +104 -0
  216. package/.agents/scripts/lib/checks/core-bare-clean.js +48 -0
  217. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +54 -0
  218. package/.agents/scripts/lib/checks/index.js +288 -0
  219. package/.agents/scripts/lib/checks/push-hook-parity.js +106 -0
  220. package/.agents/scripts/lib/checks/stale-origin-epic.js +49 -0
  221. package/.agents/scripts/lib/checks/state.js +558 -0
  222. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +186 -0
  223. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +182 -0
  224. package/.agents/scripts/lib/checks/windows-coverage-noise-floor.js +92 -0
  225. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +81 -0
  226. package/.agents/scripts/lib/checks/worktree-residue-biome.js +55 -0
  227. package/.agents/scripts/lib/cli/parse-numeric.js +60 -0
  228. package/.agents/scripts/lib/cli/standard-args.js +351 -0
  229. package/.agents/scripts/lib/cli-args.js +286 -0
  230. package/.agents/scripts/lib/cli-utils.js +69 -0
  231. package/.agents/scripts/lib/close-validation/projections/head-sha.js +44 -0
  232. package/.agents/scripts/lib/close-validation/projections/inputs.js +86 -0
  233. package/.agents/scripts/lib/close-validation/projections/maintainability.js +286 -0
  234. package/.agents/scripts/lib/close-validation.js +897 -0
  235. package/.agents/scripts/lib/codebase-snapshot.js +513 -0
  236. package/.agents/scripts/lib/command-header.js +33 -0
  237. package/.agents/scripts/lib/config/acceptance-eval.js +95 -0
  238. package/.agents/scripts/lib/config/baselines.js +60 -0
  239. package/.agents/scripts/lib/config/ci.js +30 -0
  240. package/.agents/scripts/lib/config/commands.js +36 -0
  241. package/.agents/scripts/lib/config/defaults.js +119 -0
  242. package/.agents/scripts/lib/config/explain.js +348 -0
  243. package/.agents/scripts/lib/config/gates/bundle-size.schema.js +23 -0
  244. package/.agents/scripts/lib/config/gates/coverage.schema.js +18 -0
  245. package/.agents/scripts/lib/config/gates/crap.schema.js +33 -0
  246. package/.agents/scripts/lib/config/gates/duplication.schema.js +26 -0
  247. package/.agents/scripts/lib/config/gates/index.js +36 -0
  248. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +23 -0
  249. package/.agents/scripts/lib/config/gates/lint.schema.js +9 -0
  250. package/.agents/scripts/lib/config/gates/maintainability.schema.js +20 -0
  251. package/.agents/scripts/lib/config/gates/mutation.schema.js +12 -0
  252. package/.agents/scripts/lib/config/gates/shared.js +117 -0
  253. package/.agents/scripts/lib/config/github.js +122 -0
  254. package/.agents/scripts/lib/config/lifecycle.js +40 -0
  255. package/.agents/scripts/lib/config/limits.js +211 -0
  256. package/.agents/scripts/lib/config/paths.js +73 -0
  257. package/.agents/scripts/lib/config/preflight.js +58 -0
  258. package/.agents/scripts/lib/config/quality.js +665 -0
  259. package/.agents/scripts/lib/config/retro.js +77 -0
  260. package/.agents/scripts/lib/config/runners.js +105 -0
  261. package/.agents/scripts/lib/config/runtime.js +167 -0
  262. package/.agents/scripts/lib/config/shared.js +46 -0
  263. package/.agents/scripts/lib/config/sync-agentrc.js +243 -0
  264. package/.agents/scripts/lib/config/temp-paths.js +373 -0
  265. package/.agents/scripts/lib/config/validate-orchestration.js +81 -0
  266. package/.agents/scripts/lib/config/worktree-isolation.js +80 -0
  267. package/.agents/scripts/lib/config-resolver.js +298 -0
  268. package/.agents/scripts/lib/config-schema-shared.js +32 -0
  269. package/.agents/scripts/lib/config-schema.js +20 -0
  270. package/.agents/scripts/lib/config-settings-schema-delivery.js +332 -0
  271. package/.agents/scripts/lib/config-settings-schema-quality.js +165 -0
  272. package/.agents/scripts/lib/config-settings-schema.js +420 -0
  273. package/.agents/scripts/lib/coverage-baseline.js +352 -0
  274. package/.agents/scripts/lib/coverage-capture.js +195 -0
  275. package/.agents/scripts/lib/coverage-utils.js +239 -0
  276. package/.agents/scripts/lib/cpu-pool.js +223 -0
  277. package/.agents/scripts/lib/crap-engine.js +119 -0
  278. package/.agents/scripts/lib/crap-utils.js +479 -0
  279. package/.agents/scripts/lib/degraded-mode.js +69 -0
  280. package/.agents/scripts/lib/dependency-parser.js +129 -0
  281. package/.agents/scripts/lib/duplicate-search.js +189 -0
  282. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +70 -0
  283. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +197 -0
  284. package/.agents/scripts/lib/dynamic-workflow/capability.js +396 -0
  285. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +80 -0
  286. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +72 -0
  287. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +90 -0
  288. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +43 -0
  289. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +83 -0
  290. package/.agents/scripts/lib/env-loader.js +52 -0
  291. package/.agents/scripts/lib/epic-merge-lock.js +239 -0
  292. package/.agents/scripts/lib/epic-plan-clarity.js +142 -0
  293. package/.agents/scripts/lib/epic-plan-ideation.js +228 -0
  294. package/.agents/scripts/lib/error-redactor.js +125 -0
  295. package/.agents/scripts/lib/errors/index.js +67 -0
  296. package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +230 -0
  297. package/.agents/scripts/lib/feedback-loop/code-review-graduator.js +207 -0
  298. package/.agents/scripts/lib/feedback-loop/graduator-core.js +421 -0
  299. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +480 -0
  300. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +229 -0
  301. package/.agents/scripts/lib/findings/classify-finding.js +195 -0
  302. package/.agents/scripts/lib/findings/promote-finding.js +353 -0
  303. package/.agents/scripts/lib/findings/route-finding.js +283 -0
  304. package/.agents/scripts/lib/findings/semantic-issue-search.js +179 -0
  305. package/.agents/scripts/lib/findings/severity.js +102 -0
  306. package/.agents/scripts/lib/gates/baseline-store.js +106 -0
  307. package/.agents/scripts/lib/gates/friction.js +43 -0
  308. package/.agents/scripts/lib/gh-exec.js +553 -0
  309. package/.agents/scripts/lib/git/cached-fetch.js +0 -0
  310. package/.agents/scripts/lib/git/sync-from-base.js +162 -0
  311. package/.agents/scripts/lib/git-branch-cleanup.js +213 -0
  312. package/.agents/scripts/lib/git-branch-lifecycle.js +353 -0
  313. package/.agents/scripts/lib/git-merge-orchestrator.js +261 -0
  314. package/.agents/scripts/lib/git-utils.js +363 -0
  315. package/.agents/scripts/lib/github-url.js +29 -0
  316. package/.agents/scripts/lib/install-cmd-parser.js +51 -0
  317. package/.agents/scripts/lib/issue-link-parser.js +74 -0
  318. package/.agents/scripts/lib/json-utils.js +60 -0
  319. package/.agents/scripts/lib/label-constants.js +169 -0
  320. package/.agents/scripts/lib/label-taxonomy.js +200 -0
  321. package/.agents/scripts/lib/maintainability-engine.js +164 -0
  322. package/.agents/scripts/lib/maintainability-utils.js +343 -0
  323. package/.agents/scripts/lib/mandrel-catalog.js +170 -0
  324. package/.agents/scripts/lib/mutation/baseline-snapshot.js +238 -0
  325. package/.agents/scripts/lib/mutation/config-detector.js +119 -0
  326. package/.agents/scripts/lib/mutation/stryker-runner.js +306 -0
  327. package/.agents/scripts/lib/mutation/survivor-report.js +160 -0
  328. package/.agents/scripts/lib/notifications/notifier.js +75 -0
  329. package/.agents/scripts/lib/observability/active-story-env.js +182 -0
  330. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +221 -0
  331. package/.agents/scripts/lib/observability/perf-aggregator.js +887 -0
  332. package/.agents/scripts/lib/observability/perf-report-readers.js +319 -0
  333. package/.agents/scripts/lib/observability/perf-report-render.js +182 -0
  334. package/.agents/scripts/lib/observability/signals-writer.js +296 -0
  335. package/.agents/scripts/lib/observability/source-classifier.js +103 -0
  336. package/.agents/scripts/lib/observability/tool-trace-hook.js +417 -0
  337. package/.agents/scripts/lib/onboard/detect-stack.js +300 -0
  338. package/.agents/scripts/lib/onboard/scaffold-docs.js +128 -0
  339. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +173 -0
  340. package/.agents/scripts/lib/orchestration/cascade-grouping.js +275 -0
  341. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +131 -0
  342. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +80 -0
  343. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +132 -0
  344. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +142 -0
  345. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +149 -0
  346. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +158 -0
  347. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +56 -0
  348. package/.agents/scripts/lib/orchestration/code-review.js +652 -0
  349. package/.agents/scripts/lib/orchestration/column-sync.js +286 -0
  350. package/.agents/scripts/lib/orchestration/context-envelope.js +280 -0
  351. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +581 -0
  352. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +88 -0
  353. package/.agents/scripts/lib/orchestration/detectors-phase.js +188 -0
  354. package/.agents/scripts/lib/orchestration/dispatch-engine.js +144 -0
  355. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +206 -0
  356. package/.agents/scripts/lib/orchestration/doc-reader.js +94 -0
  357. package/.agents/scripts/lib/orchestration/epic-cleanup.js +473 -0
  358. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +310 -0
  359. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/cli.js +167 -0
  360. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +151 -0
  361. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +74 -0
  362. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +78 -0
  363. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +72 -0
  364. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +155 -0
  365. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +321 -0
  366. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +75 -0
  367. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +86 -0
  368. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +235 -0
  369. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +197 -0
  370. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +48 -0
  371. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +94 -0
  372. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +414 -0
  373. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +55 -0
  374. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +105 -0
  375. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +235 -0
  376. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +120 -0
  377. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +118 -0
  378. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +295 -0
  379. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +186 -0
  380. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +50 -0
  381. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +146 -0
  382. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +110 -0
  383. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +392 -0
  384. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +217 -0
  385. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +235 -0
  386. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +69 -0
  387. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +32 -0
  388. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +291 -0
  389. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +175 -0
  390. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +37 -0
  391. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +127 -0
  392. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +400 -0
  393. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +285 -0
  394. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +66 -0
  395. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +797 -0
  396. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +619 -0
  397. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +335 -0
  398. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +230 -0
  399. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +363 -0
  400. package/.agents/scripts/lib/orchestration/error-journal.js +139 -0
  401. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +31 -0
  402. package/.agents/scripts/lib/orchestration/file-assumptions.js +506 -0
  403. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +116 -0
  404. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +241 -0
  405. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +489 -0
  406. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +88 -0
  407. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +219 -0
  408. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +309 -0
  409. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +99 -0
  410. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +123 -0
  411. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +57 -0
  412. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +114 -0
  413. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +426 -0
  414. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +84 -0
  415. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +365 -0
  416. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +72 -0
  417. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +69 -0
  418. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +214 -0
  419. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +137 -0
  420. package/.agents/scripts/lib/orchestration/label-transitions.js +43 -0
  421. package/.agents/scripts/lib/orchestration/lifecycle/bus.js +309 -0
  422. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +147 -0
  423. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +155 -0
  424. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +226 -0
  425. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +69 -0
  426. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +378 -0
  427. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +248 -0
  428. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +527 -0
  429. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +259 -0
  430. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +278 -0
  431. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +355 -0
  432. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +647 -0
  433. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +331 -0
  434. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +140 -0
  435. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +421 -0
  436. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +168 -0
  437. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +668 -0
  438. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +322 -0
  439. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +114 -0
  440. package/.agents/scripts/lib/orchestration/manifest-builder.js +216 -0
  441. package/.agents/scripts/lib/orchestration/model-attribution.js +390 -0
  442. package/.agents/scripts/lib/orchestration/parked-follow-ons.js +147 -0
  443. package/.agents/scripts/lib/orchestration/phase-runner.js +87 -0
  444. package/.agents/scripts/lib/orchestration/plan-review-routing.js +63 -0
  445. package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +86 -0
  446. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +212 -0
  447. package/.agents/scripts/lib/orchestration/planning-context-budget.js +213 -0
  448. package/.agents/scripts/lib/orchestration/planning-risk.js +155 -0
  449. package/.agents/scripts/lib/orchestration/planning-state-manager.js +318 -0
  450. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +56 -0
  451. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +33 -0
  452. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +78 -0
  453. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +68 -0
  454. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +118 -0
  455. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +396 -0
  456. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +205 -0
  457. package/.agents/scripts/lib/orchestration/pr-base-guard.js +47 -0
  458. package/.agents/scripts/lib/orchestration/preflight-cache.js +164 -0
  459. package/.agents/scripts/lib/orchestration/reassert-status-column.js +202 -0
  460. package/.agents/scripts/lib/orchestration/reconciler.js +137 -0
  461. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +152 -0
  462. package/.agents/scripts/lib/orchestration/recut.js +56 -0
  463. package/.agents/scripts/lib/orchestration/resolves-token.js +127 -0
  464. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +94 -0
  465. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +448 -0
  466. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +335 -0
  467. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +133 -0
  468. package/.agents/scripts/lib/orchestration/retro-heuristics.js +57 -0
  469. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +275 -0
  470. package/.agents/scripts/lib/orchestration/retro-proposals.js +395 -0
  471. package/.agents/scripts/lib/orchestration/retro-runner.js +171 -0
  472. package/.agents/scripts/lib/orchestration/review-depth.js +93 -0
  473. package/.agents/scripts/lib/orchestration/review-providers/codex.js +363 -0
  474. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +205 -0
  475. package/.agents/scripts/lib/orchestration/review-providers/native.js +805 -0
  476. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +73 -0
  477. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +396 -0
  478. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +373 -0
  479. package/.agents/scripts/lib/orchestration/review-providers/types.js +89 -0
  480. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +107 -0
  481. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +159 -0
  482. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +194 -0
  483. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +81 -0
  484. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +190 -0
  485. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +70 -0
  486. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +106 -0
  487. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +42 -0
  488. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +73 -0
  489. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +225 -0
  490. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +315 -0
  491. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +149 -0
  492. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +110 -0
  493. package/.agents/scripts/lib/orchestration/spec-freshness.js +320 -0
  494. package/.agents/scripts/lib/orchestration/spec-renderer.js +456 -0
  495. package/.agents/scripts/lib/orchestration/spec-section-validator.js +80 -0
  496. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +797 -0
  497. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +163 -0
  498. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +152 -0
  499. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +387 -0
  500. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +266 -0
  501. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +48 -0
  502. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +67 -0
  503. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +161 -0
  504. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +117 -0
  505. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +86 -0
  506. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +147 -0
  507. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +142 -0
  508. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +62 -0
  509. package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +221 -0
  510. package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +123 -0
  511. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +216 -0
  512. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +636 -0
  513. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +198 -0
  514. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +105 -0
  515. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +222 -0
  516. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +220 -0
  517. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +291 -0
  518. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +234 -0
  519. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +110 -0
  520. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +86 -0
  521. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +112 -0
  522. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +157 -0
  523. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +434 -0
  524. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +290 -0
  525. package/.agents/scripts/lib/orchestration/story-close-recovery.js +643 -0
  526. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +67 -0
  527. package/.agents/scripts/lib/orchestration/task-body-validator.js +391 -0
  528. package/.agents/scripts/lib/orchestration/ticket-lease.js +358 -0
  529. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +783 -0
  530. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +367 -0
  531. package/.agents/scripts/lib/orchestration/ticket-validator.js +691 -0
  532. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +723 -0
  533. package/.agents/scripts/lib/orchestration/ticketing/reads.js +474 -0
  534. package/.agents/scripts/lib/orchestration/ticketing/state.js +559 -0
  535. package/.agents/scripts/lib/orchestration/ticketing.js +55 -0
  536. package/.agents/scripts/lib/orchestration/wave-marker.js +28 -0
  537. package/.agents/scripts/lib/orchestration/wave-record-io.js +277 -0
  538. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +189 -0
  539. package/.agents/scripts/lib/orchestration/wave-record-projection.js +423 -0
  540. package/.agents/scripts/lib/path-security.js +25 -0
  541. package/.agents/scripts/lib/plan-phase-cleanup.js +125 -0
  542. package/.agents/scripts/lib/preflight-runner.js +196 -0
  543. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +95 -0
  544. package/.agents/scripts/lib/presentation/manifest-builder.js +245 -0
  545. package/.agents/scripts/lib/presentation/manifest-formatter.js +243 -0
  546. package/.agents/scripts/lib/presentation/manifest-helpers.js +213 -0
  547. package/.agents/scripts/lib/presentation/manifest-persistence.js +262 -0
  548. package/.agents/scripts/lib/presentation/manifest-procedures.js +55 -0
  549. package/.agents/scripts/lib/presentation/manifest-render-waves.js +252 -0
  550. package/.agents/scripts/lib/presentation/manifest-renderer.js +188 -0
  551. package/.agents/scripts/lib/presentation/manifest-story-views.js +119 -0
  552. package/.agents/scripts/lib/provider-factory.js +80 -0
  553. package/.agents/scripts/lib/push-epic-retry.js +209 -0
  554. package/.agents/scripts/lib/qa/console-allowlist.js +151 -0
  555. package/.agents/scripts/lib/qa/coverage-report.js +181 -0
  556. package/.agents/scripts/lib/qa/coverage-verdict.js +296 -0
  557. package/.agents/scripts/lib/qa/propose-missing-test.js +95 -0
  558. package/.agents/scripts/lib/qa/qa-context-hydrator.js +296 -0
  559. package/.agents/scripts/lib/qa/qa-session.js +197 -0
  560. package/.agents/scripts/lib/qa/redact-evidence.js +245 -0
  561. package/.agents/scripts/lib/qa/resolve-qa-contract.js +190 -0
  562. package/.agents/scripts/lib/qa/resolve-selection.js +373 -0
  563. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +100 -0
  564. package/.agents/scripts/lib/runtime-deps/manifest.js +96 -0
  565. package/.agents/scripts/lib/runtime-deps/preflight.js +78 -0
  566. package/.agents/scripts/lib/runtime-deps/scan-imports.js +202 -0
  567. package/.agents/scripts/lib/signals/detectors/common.js +36 -0
  568. package/.agents/scripts/lib/signals/detectors/hotspot.js +298 -0
  569. package/.agents/scripts/lib/signals/detectors/index.js +14 -0
  570. package/.agents/scripts/lib/signals/detectors/retry.js +289 -0
  571. package/.agents/scripts/lib/signals/detectors/rework.js +204 -0
  572. package/.agents/scripts/lib/signals/index.js +39 -0
  573. package/.agents/scripts/lib/signals/read.js +268 -0
  574. package/.agents/scripts/lib/signals/schema.js +225 -0
  575. package/.agents/scripts/lib/signals/span-tree.js +290 -0
  576. package/.agents/scripts/lib/signals/write.js +19 -0
  577. package/.agents/scripts/lib/single-story/confirm-merge.js +201 -0
  578. package/.agents/scripts/lib/single-story/story-merged-notify.js +126 -0
  579. package/.agents/scripts/lib/single-story-sweep/protection.js +274 -0
  580. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +169 -0
  581. package/.agents/scripts/lib/single-story-sweep.js +329 -0
  582. package/.agents/scripts/lib/skills/parse-skill.js +202 -0
  583. package/.agents/scripts/lib/skills/walk-skill-files.js +56 -0
  584. package/.agents/scripts/lib/spec/index.js +36 -0
  585. package/.agents/scripts/lib/spec/loader.js +425 -0
  586. package/.agents/scripts/lib/spec/state.js +217 -0
  587. package/.agents/scripts/lib/story-body/story-body.js +743 -0
  588. package/.agents/scripts/lib/story-init/blocker-validator.js +68 -0
  589. package/.agents/scripts/lib/story-init/branch-initializer.js +422 -0
  590. package/.agents/scripts/lib/story-init/context-resolver.js +92 -0
  591. package/.agents/scripts/lib/story-init/donor-precheck.js +207 -0
  592. package/.agents/scripts/lib/story-init/hierarchy-tracer.js +36 -0
  593. package/.agents/scripts/lib/story-init/state-transitioner.js +80 -0
  594. package/.agents/scripts/lib/story-init/task-graph-builder.js +114 -0
  595. package/.agents/scripts/lib/story-init/transition-summary.js +34 -0
  596. package/.agents/scripts/lib/story-lifecycle.js +186 -0
  597. package/.agents/scripts/lib/story-plan.js +246 -0
  598. package/.agents/scripts/lib/task-utils.js +26 -0
  599. package/.agents/scripts/lib/templates/decomposer-prompts.js +168 -0
  600. package/.agents/scripts/lib/test-env.js +30 -0
  601. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +52 -0
  602. package/.agents/scripts/lib/test-isolate/list-files.js +90 -0
  603. package/.agents/scripts/lib/test-isolate/parse-tap.js +75 -0
  604. package/.agents/scripts/lib/test-isolate/runner.js +483 -0
  605. package/.agents/scripts/lib/test-profile/parse-tap.js +136 -0
  606. package/.agents/scripts/lib/test-profile/render-report.js +45 -0
  607. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +35 -0
  608. package/.agents/scripts/lib/test-tiers.js +94 -0
  609. package/.agents/scripts/lib/util/concurrent-map.js +59 -0
  610. package/.agents/scripts/lib/util/phase-timer-state.js +72 -0
  611. package/.agents/scripts/lib/util/phase-timer.js +163 -0
  612. package/.agents/scripts/lib/util/poll-loop.js +86 -0
  613. package/.agents/scripts/lib/util/with-timeout.js +32 -0
  614. package/.agents/scripts/lib/validation-evidence.js +323 -0
  615. package/.agents/scripts/lib/wave-runner/tick.js +665 -0
  616. package/.agents/scripts/lib/wave-runner/wave-checkpoint.js +91 -0
  617. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +19 -0
  618. package/.agents/scripts/lib/workers/crap-worker.js +197 -0
  619. package/.agents/scripts/lib/workers/maintainability-report-worker.js +137 -0
  620. package/.agents/scripts/lib/workers/maintainability-worker.js +79 -0
  621. package/.agents/scripts/lib/workspace-provisioner.js +189 -0
  622. package/.agents/scripts/lib/worktree/bootstrapper.js +48 -0
  623. package/.agents/scripts/lib/worktree/inspector.js +140 -0
  624. package/.agents/scripts/lib/worktree/lifecycle/creation.js +118 -0
  625. package/.agents/scripts/lib/worktree/lifecycle/drift-detection.js +62 -0
  626. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +276 -0
  627. package/.agents/scripts/lib/worktree/lifecycle/gc.js +49 -0
  628. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +178 -0
  629. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +264 -0
  630. package/.agents/scripts/lib/worktree/lifecycle/precheck.js +100 -0
  631. package/.agents/scripts/lib/worktree/lifecycle/reap.js +588 -0
  632. package/.agents/scripts/lib/worktree/lifecycle/registry-sync.js +124 -0
  633. package/.agents/scripts/lib/worktree/lifecycle/shared.js +26 -0
  634. package/.agents/scripts/lib/worktree/lifecycle-manager.js +40 -0
  635. package/.agents/scripts/lib/worktree/node-modules-strategy.js +349 -0
  636. package/.agents/scripts/lib/worktree-manager.js +243 -0
  637. package/.agents/scripts/lifecycle-diff.js +206 -0
  638. package/.agents/scripts/lifecycle-emit-story-dispatch.js +194 -0
  639. package/.agents/scripts/lifecycle-emit.js +479 -0
  640. package/.agents/scripts/lint-baseline.js +507 -0
  641. package/.agents/scripts/lint-label-vocabulary.js +237 -0
  642. package/.agents/scripts/loc-delta.js +205 -0
  643. package/.agents/scripts/notify.js +307 -0
  644. package/.agents/scripts/package.json +3 -0
  645. package/.agents/scripts/post-structured-comment.js +127 -0
  646. package/.agents/scripts/pr-watch-with-update.js +152 -0
  647. package/.agents/scripts/providers/github/auth.js +65 -0
  648. package/.agents/scripts/providers/github/board-add.js +63 -0
  649. package/.agents/scripts/providers/github/branch-protection.js +186 -0
  650. package/.agents/scripts/providers/github/cache.js +72 -0
  651. package/.agents/scripts/providers/github/comments.js +131 -0
  652. package/.agents/scripts/providers/github/compose.js +111 -0
  653. package/.agents/scripts/providers/github/errors.js +242 -0
  654. package/.agents/scripts/providers/github/issues.js +242 -0
  655. package/.agents/scripts/providers/github/labels.js +179 -0
  656. package/.agents/scripts/providers/github/mappers.js +126 -0
  657. package/.agents/scripts/providers/github/merge-methods.js +82 -0
  658. package/.agents/scripts/providers/github/project-board.js +47 -0
  659. package/.agents/scripts/providers/github/projects-v2-graphql.js +472 -0
  660. package/.agents/scripts/providers/github/prs.js +103 -0
  661. package/.agents/scripts/providers/github/request-helpers.js +110 -0
  662. package/.agents/scripts/providers/github/sub-issues.js +369 -0
  663. package/.agents/scripts/providers/github/tickets.js +381 -0
  664. package/.agents/scripts/providers/github/transient-retry.js +62 -0
  665. package/.agents/scripts/providers/github.js +157 -0
  666. package/.agents/scripts/quality-preview.js +327 -0
  667. package/.agents/scripts/quality-watch.js +223 -0
  668. package/.agents/scripts/render-manifest.js +143 -0
  669. package/.agents/scripts/resync-status-column.js +176 -0
  670. package/.agents/scripts/retro-run.js +167 -0
  671. package/.agents/scripts/run-audit-suite.js +97 -0
  672. package/.agents/scripts/run-coverage.js +103 -0
  673. package/.agents/scripts/run-lint.js +94 -0
  674. package/.agents/scripts/run-test-profile.js +126 -0
  675. package/.agents/scripts/run-tests.js +185 -0
  676. package/.agents/scripts/run-verify.js +56 -0
  677. package/.agents/scripts/select-audits.js +155 -0
  678. package/.agents/scripts/signals-view.js +294 -0
  679. package/.agents/scripts/single-story-close.js +83 -0
  680. package/.agents/scripts/single-story-confirm-merge.js +183 -0
  681. package/.agents/scripts/single-story-init.js +692 -0
  682. package/.agents/scripts/stories-wave-tick.js +415 -0
  683. package/.agents/scripts/story-close.js +246 -0
  684. package/.agents/scripts/story-deliver-prepare.js +267 -0
  685. package/.agents/scripts/story-init.js +516 -0
  686. package/.agents/scripts/story-phase.js +327 -0
  687. package/.agents/scripts/story-plan.js +284 -0
  688. package/.agents/scripts/sync-agentrc.js +71 -0
  689. package/.agents/scripts/sync-branch-from-base.js +138 -0
  690. package/.agents/scripts/sync-claude-commands.js +151 -0
  691. package/.agents/scripts/test-isolate.js +222 -0
  692. package/.agents/scripts/test-wrapper.js +108 -0
  693. package/.agents/scripts/update-coverage-baseline.js +129 -0
  694. package/.agents/scripts/update-crap-baseline.js +177 -0
  695. package/.agents/scripts/update-duplication-baseline.js +134 -0
  696. package/.agents/scripts/update-maintainability-baseline.js +183 -0
  697. package/.agents/scripts/update-mutation-baseline.js +189 -0
  698. package/.agents/scripts/update-ticket-state.js +107 -0
  699. package/.agents/scripts/validate-docs-freshness.js +259 -0
  700. package/.agents/scripts/validate-skills.js +278 -0
  701. package/.agents/scripts/wave-tick.js +335 -0
  702. package/.agents/skills/core/analyze-execution/SKILL.md +98 -0
  703. package/.agents/skills/core/api-and-interface-design/SKILL.md +327 -0
  704. package/.agents/skills/core/baseline-refresh/SKILL.md +181 -0
  705. package/.agents/skills/core/browser-testing-with-devtools/SKILL.md +352 -0
  706. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +274 -0
  707. package/.agents/skills/core/ci-cd-and-automation/examples.md +211 -0
  708. package/.agents/skills/core/code-review-and-quality/SKILL.md +421 -0
  709. package/.agents/skills/core/code-simplification/SKILL.md +389 -0
  710. package/.agents/skills/core/context-engineering/SKILL.md +309 -0
  711. package/.agents/skills/core/context-engineering/examples.md +58 -0
  712. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +338 -0
  713. package/.agents/skills/core/deprecation-and-migration/SKILL.md +250 -0
  714. package/.agents/skills/core/diagnose-friction/SKILL.md +79 -0
  715. package/.agents/skills/core/documentation-and-adrs/SKILL.md +323 -0
  716. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +145 -0
  717. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +425 -0
  718. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +393 -0
  719. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +357 -0
  720. package/.agents/skills/core/git-workflow-and-versioning/SKILL.md +352 -0
  721. package/.agents/skills/core/hydrate-context/SKILL.md +118 -0
  722. package/.agents/skills/core/idea-refinement/SKILL.md +317 -0
  723. package/.agents/skills/core/idea-refinement/examples.md +437 -0
  724. package/.agents/skills/core/idea-refinement/frameworks.md +135 -0
  725. package/.agents/skills/core/idea-refinement/refinement-criteria.md +155 -0
  726. package/.agents/skills/core/idea-refinement/scripts/idea-refine.sh +15 -0
  727. package/.agents/skills/core/incremental-implementation/SKILL.md +271 -0
  728. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +213 -0
  729. package/.agents/skills/core/knowledge-transfer/SKILL.md +175 -0
  730. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +117 -0
  731. package/.agents/skills/core/performance-optimization/SKILL.md +314 -0
  732. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +277 -0
  733. package/.agents/skills/core/property-based-testing/SKILL.md +148 -0
  734. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +105 -0
  735. package/.agents/skills/core/refactoring-discipline/SKILL.md +111 -0
  736. package/.agents/skills/core/scope-triage/SKILL.md +127 -0
  737. package/.agents/skills/core/security-and-hardening/SKILL.md +400 -0
  738. package/.agents/skills/core/shipping-and-launch/SKILL.md +328 -0
  739. package/.agents/skills/core/spec-driven-development/SKILL.md +252 -0
  740. package/.agents/skills/core/test-driven-development/SKILL.md +475 -0
  741. package/.agents/skills/core/using-agent-skills/SKILL.md +232 -0
  742. package/.agents/skills/skills.index.json +596 -0
  743. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +31 -0
  744. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +51 -0
  745. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +48 -0
  746. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +31 -0
  747. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +33 -0
  748. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +31 -0
  749. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +51 -0
  750. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +54 -0
  751. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +29 -0
  752. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +30 -0
  753. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +57 -0
  754. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +9 -0
  755. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +48 -0
  756. package/.agents/skills/stack/frontend/astro/SKILL.md +62 -0
  757. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +30 -0
  758. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +29 -0
  759. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +50 -0
  760. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +58 -0
  761. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +34 -0
  762. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +51 -0
  763. package/.agents/skills/stack/qa/gherkin-authoring/SKILL.md +257 -0
  764. package/.agents/skills/stack/qa/gherkin-authoring/examples/invoice-issue.feature +41 -0
  765. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +199 -0
  766. package/.agents/skills/stack/qa/playwright/SKILL.md +50 -0
  767. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +188 -0
  768. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +142 -0
  769. package/.agents/skills/stack/qa/qa-harness/SKILL.md +220 -0
  770. package/.agents/skills/stack/qa/vitest/SKILL.md +51 -0
  771. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +68 -0
  772. package/.agents/starter-agentrc.json +22 -0
  773. package/.agents/templates/agent-protocol.md +72 -0
  774. package/.agents/templates/docs/architecture.md +30 -0
  775. package/.agents/templates/docs/decisions.md +24 -0
  776. package/.agents/templates/epic-from-idea.md +21 -0
  777. package/.agents/templates/single-story-body.md +17 -0
  778. package/.agents/workflows/agents-update.md +415 -0
  779. package/.agents/workflows/audit-architecture.md +312 -0
  780. package/.agents/workflows/audit-clean-code.md +179 -0
  781. package/.agents/workflows/audit-dependencies.md +91 -0
  782. package/.agents/workflows/audit-devops.md +110 -0
  783. package/.agents/workflows/audit-lighthouse.md +260 -0
  784. package/.agents/workflows/audit-performance.md +161 -0
  785. package/.agents/workflows/audit-privacy.md +104 -0
  786. package/.agents/workflows/audit-quality.md +191 -0
  787. package/.agents/workflows/audit-security.md +156 -0
  788. package/.agents/workflows/audit-seo.md +118 -0
  789. package/.agents/workflows/audit-sre.md +139 -0
  790. package/.agents/workflows/audit-to-stories.md +257 -0
  791. package/.agents/workflows/audit-ux-ui.md +102 -0
  792. package/.agents/workflows/epic-deliver.md +864 -0
  793. package/.agents/workflows/epic-plan.md +998 -0
  794. package/.agents/workflows/explain.md +118 -0
  795. package/.agents/workflows/git-cleanup.md +250 -0
  796. package/.agents/workflows/git-commit-all.md +15 -0
  797. package/.agents/workflows/git-merge-pr.md +377 -0
  798. package/.agents/workflows/git-pr-all.md +278 -0
  799. package/.agents/workflows/git-push.md +60 -0
  800. package/.agents/workflows/helpers/_merge-conflict-template.md +54 -0
  801. package/.agents/workflows/helpers/acceptance-self-eval.md +74 -0
  802. package/.agents/workflows/helpers/agents-sync-config.md +129 -0
  803. package/.agents/workflows/helpers/code-quality-guardrails.md +101 -0
  804. package/.agents/workflows/helpers/code-review.md +370 -0
  805. package/.agents/workflows/helpers/diagnose.md +117 -0
  806. package/.agents/workflows/helpers/epic-audit.md +295 -0
  807. package/.agents/workflows/helpers/epic-deliver-story.md +370 -0
  808. package/.agents/workflows/helpers/epic-plan-decompose.md +199 -0
  809. package/.agents/workflows/helpers/epic-plan-spec.md +184 -0
  810. package/.agents/workflows/helpers/epic-testing.md +125 -0
  811. package/.agents/workflows/helpers/parallel-tooling.md +88 -0
  812. package/.agents/workflows/helpers/signals.md +112 -0
  813. package/.agents/workflows/helpers/single-story-deliver.md +636 -0
  814. package/.agents/workflows/helpers/worktree-lifecycle.md +317 -0
  815. package/.agents/workflows/onboard.md +207 -0
  816. package/.agents/workflows/qa-assist.md +293 -0
  817. package/.agents/workflows/qa-explore.md +350 -0
  818. package/.agents/workflows/qa-run-harness.md +288 -0
  819. package/.agents/workflows/story-deliver.md +327 -0
  820. package/.agents/workflows/story-plan.md +233 -0
  821. package/LICENSE +21 -0
  822. package/README.md +193 -0
  823. package/bin/mandrel.js +56 -0
  824. package/bin/postinstall.js +195 -0
  825. package/lib/cli/__tests__/migrate.test.js +268 -0
  826. package/lib/cli/__tests__/sync-local-zone.test.js +247 -0
  827. package/lib/cli/__tests__/sync.test.js +372 -0
  828. package/lib/cli/__tests__/update-major.test.js +217 -0
  829. package/lib/cli/__tests__/update.test.js +696 -0
  830. package/lib/cli/__tests__/version-check.test.js +398 -0
  831. package/lib/cli/doctor.js +124 -0
  832. package/lib/cli/explain.js +107 -0
  833. package/lib/cli/migrate.js +260 -0
  834. package/lib/cli/registry.js +830 -0
  835. package/lib/cli/sync-commands.js +50 -0
  836. package/lib/cli/sync.js +200 -0
  837. package/lib/cli/uninstall.js +795 -0
  838. package/lib/cli/update.js +854 -0
  839. package/lib/cli/version-check.js +206 -0
  840. package/lib/migrations/README.md +69 -0
  841. package/lib/migrations/__tests__/index.test.js +216 -0
  842. package/lib/migrations/index.js +164 -0
  843. package/package.json +105 -0
@@ -0,0 +1,1040 @@
1
+ # Configuration Reference
2
+
3
+ `.agentrc.json` is the single configuration contract for the Mandrel
4
+ framework. It is parsed at the start of every script via
5
+ [`config-resolver.js`](../scripts/lib/config-resolver.js), validated
6
+ against AJV schemas at runtime, and consumed through grouped accessors
7
+ (`getCommands()`, `getQuality()`, `getPaths()`, etc.).
8
+
9
+ This document is the reader-facing reference for the post-Epic-#1720 grouped
10
+ shape. The authoritative contract is the JSON Schema mirror at
11
+ [`.agents/schemas/agentrc.schema.json`](../schemas/agentrc.schema.json),
12
+ which is itself a mirror of the AJV schemas under
13
+ [`.agents/scripts/lib/`](../scripts/lib/). A drift test
14
+ (`tests/config-schema-mirror-drift.test.js`) keeps the static mirror aligned
15
+ with the runtime validators.
16
+
17
+ > **Editor support.** `.agentrc.json`, `.agents/starter-agentrc.json`, and
18
+ > `.agents/docs/agentrc-reference.json` all declare
19
+ > `"$schema": "./.agents/schemas/agentrc.schema.json"`, so any editor with
20
+ > JSON Schema support gets autocomplete and inline validation.
21
+
22
+ ## Top-level shape
23
+
24
+ ```jsonc
25
+ {
26
+ "$schema": "./.agents/schemas/agentrc.schema.json",
27
+ "project": { /* paths, commands, baseBranch, docsContextFiles */ },
28
+ "github": { /* owner, repo, branchProtection, mergeMethods, notifications */ },
29
+ "planning": { /* riskHeuristics, maxTickets, codebaseSnapshot, context */ },
30
+ "delivery": { /* execution, quality, worktreeIsolation, deliverRunner, ... */ }
31
+ }
32
+ ```
33
+
34
+ The schema declares `additionalProperties: false` at the root — unknown
35
+ top-level keys are validation errors.
36
+
37
+ | Top-level key | Required | Purpose |
38
+ | ------------- | -------- | ---------------------------------------------------------------------------------- |
39
+ | `project` | **Yes** | Project-local paths, base branch, validation commands, and context-hydration files. |
40
+ | `github` | No | Ticketing provider config: owner/repo, branch protection, merge methods, notifications. |
41
+ | `planning` | No | `/epic-plan` tuning: ticket budget, risk heuristics, codebase snapshot, context cap. |
42
+ | `delivery` | No | `/epic-deliver` and `/story-deliver` tuning: quality gates, worktree isolation, runners, lifecycle. |
43
+ | `$schema` | No | JSON Schema pointer for editor tooling. |
44
+
45
+ ---
46
+
47
+ <!-- BEGIN GENERATED:agentrc -->
48
+
49
+ > Generated by `node .agents/scripts/generate-config-docs.js` from
50
+ > [`.agents/schemas/agentrc.schema.json`](../schemas/agentrc.schema.json).
51
+ > Edit the schema (and its AJV mirror under `.agents/scripts/lib/`),
52
+ > then re-run the generator — do not hand-edit this region.
53
+
54
+ ### `project` (required)
55
+
56
+ | Key | Required | Type | Default | Description |
57
+ | --- | --- | --- | --- | --- |
58
+ | `baseBranch` | No | `string` | — | — |
59
+ | `paths` | Yes | `object` | — | Nested configuration block. |
60
+ | `paths.agentRoot` | Yes | `string` | — | — |
61
+ | `paths.docsRoot` | Yes | `string` | — | — |
62
+ | `paths.tempRoot` | Yes | `string` | — | — |
63
+ | `docsContextFiles` | No | `array<string>` | — | — |
64
+ | `commands` | No | `object` | — | Nested configuration block. |
65
+ | `commands.lintBaseline` | No | `string` | — | — |
66
+ | `commands.test` | No | `string` | — | — |
67
+ | `commands.typecheck` | No | `string` \| `null` | — | — |
68
+ | `commands.formatCheck` | No | `string` | — | — |
69
+ | `commands.formatWrite` | No | `string` | — | — |
70
+
71
+ ### `github` (optional)
72
+
73
+ | Key | Required | Type | Default | Description |
74
+ | --- | --- | --- | --- | --- |
75
+ | `owner` | Yes | `string` | — | — |
76
+ | `repo` | Yes | `string` | — | — |
77
+ | `projectNumber` | No | `integer` \| `null` | — | — |
78
+ | `projectOwner` | No | `string` \| `null` | — | — |
79
+ | `operatorHandle` | Yes | `string` | — | — |
80
+ | `defaultTimeoutMs` | No | `integer` | — | Default `timeoutMs` (in milliseconds) applied to every `gh` subprocess spawned by the GitHub provider facade. Caps any single `gh api` / `gh issue ...` / `gh pr ...` invocation so a stalled TCP socket or long-poll cannot hang an orchestration indefinitely. A `GhExecTimeoutError` from a hit ceiling is classified `transient` and retried by `withTransientRetry`. Recommended floor 1000ms; recommended default 60000 (60s). Omit to use the in-code default of 60000. Story #2860. |
81
+ | `branchProtection` | No | `object` | — | Nested configuration block. |
82
+ | `branchProtection.enforce` | No | `boolean` | — | — |
83
+ | `branchProtection.requiredChecks[]` | No | `array<branchProtectionCheck>` | — | Each item (`branchProtectionCheck`) has: name, cmd. |
84
+ | `mergeMethods` | No | `object` | — | Nested configuration block. |
85
+ | `mergeMethods.allow_squash_merge` | No | `boolean` | — | — |
86
+ | `mergeMethods.allow_rebase_merge` | No | `boolean` | — | — |
87
+ | `mergeMethods.allow_merge_commit` | No | `boolean` | — | — |
88
+ | `mergeMethods.allow_auto_merge` | No | `boolean` | — | — |
89
+ | `mergeMethods.delete_branch_on_merge` | No | `boolean` | — | — |
90
+ | `notifications` | No | `object` | — | Nested configuration block. |
91
+ | `notifications.mentionOperator` | No | `boolean` | — | — |
92
+ | `notifications.commentEvents` | No | `array<enum>` | — | — |
93
+ | `notifications.webhookEvents` | No | `array<enum>` | — | — |
94
+
95
+ ### `planning` (optional)
96
+
97
+ | Key | Required | Type | Default | Description |
98
+ | --- | --- | --- | --- | --- |
99
+ | `riskHeuristics` | No | `string[]` or `{ append?, prepend? }` | — | — |
100
+ | `maxTickets` | No | `integer` | — | — |
101
+ | `context` | No | `object` | — | Nested configuration block. |
102
+ | `context.maxBytes` | No | `integer` | — | — |
103
+ | `context.summaryMode` | No | `"auto"` \| `"always"` \| `"never"` | — | — |
104
+ | `codebaseSnapshot` | No | `object` | — | Nested configuration block. |
105
+ | `codebaseSnapshot.tier` | No | `"skinny"` \| `"medium"` | — | — |
106
+ | `codebaseSnapshot.include` | No | `array<string>` | — | — |
107
+ | `codebaseSnapshot.exclude` | No | `array<string>` | — | — |
108
+ | `codebaseSnapshot.recentCommitWindow` | No | `integer` | — | — |
109
+ | `taskSizing` | No | `object` | — | Story-sizing thresholds consumed by ticket-validator-sizing.js. Operator overrides shallow-merge with DEFAULT_TASK_SIZING defaults. Story #3760 collapsed the per-profile matrix and the parallel testSurface axis into a flat set of knobs; the sizingProfile enum was replaced by an optional body-level `wide` declaration that lifts the hardFiles rejection. Story #3874 cut over to one uniform relaxed profile sized for capability slices a frontier model delivers and self-verifies in one pass. |
110
+ | `taskSizing.softFiles` | No | `integer` | — | File-count soft-warn threshold above which a typical-Story width finding fires (default 8). |
111
+ | `taskSizing.hardFiles` | No | `integer` | — | File-count hard ceiling: a Story exceeding it is rejected unless it declares `wide` with a reason (default 30). |
112
+ | `taskSizing.maxAcceptance` | No | `integer` | — | Hard ceiling on acceptance[] item count (default 14). |
113
+ | `taskSizing.softAcceptanceCount` | No | `integer` | — | Soft-warn threshold on acceptance[] item count (default 10). |
114
+ | `failOnSharedEditors` | No | `boolean` | — | — |
115
+ | `requireExplicitCrossStoryDeps` | No | `boolean` | — | — |
116
+ | `failOnRegistryConflicts` | No | `boolean` | — | — |
117
+ | `failOnLargeFanOut` | No | `boolean` | — | — |
118
+ | `largeFanOutThreshold` | No | `integer` | — | — |
119
+ | `crossCuttingRegistries` | No | `string[]` or `{ append?, prepend? }` | — | — |
120
+
121
+ ### `delivery` (optional)
122
+
123
+ | Key | Required | Type | Default | Description |
124
+ | --- | --- | --- | --- | --- |
125
+ | `execution` | No | `object` | — | Nested configuration block. |
126
+ | `execution.timeoutMs` | No | `integer` | — | — |
127
+ | `maxTokenBudget` | No | `integer` | — | — |
128
+ | `lease` | No | `object` | — | Story #3480 (Epic #3457). Assignee-as-lease primitive. ttlMs is the staleness window — a ticket claim whose owner has not emitted a story.heartbeat within this many milliseconds is reclaimable by another operator. Defaults to 900000 (15 min) in lib/config/limits.js. |
129
+ | `lease.ttlMs` | No | `integer` | — | — |
130
+ | `docsFreshness` | No | `object` | — | Nested configuration block. |
131
+ | `docsFreshness.paths` | No | `array` | — | — |
132
+ | `deliverRunner` | No | `object` | — | Nested configuration block. |
133
+ | `deliverRunner.concurrencyCap` | No | `integer` | — | Maximum Stories dispatched in parallel within one wave. Default 3. Conservative by design — keeps host-quota consumption predictable on small waves and avoids GitHub API saturation. Operators running wide-wave Epics on hosts with adequate parallel-agent quota should raise this value to reduce wall-clock time proportionally. See epic-deliver.md § Phase 2b for the dispatch model and the throughput tradeoff discussion. |
134
+ | `deliverRunner.progressReportIntervalSec` | No | `integer` | — | — |
135
+ | `deliverRunner.verifyConcurrencyCap` | No | `integer` | — | Bounded-concurrency cap for the per-wave verifyWaveResults loop (Epic #3019 Tech Spec §1.4). Separate from the wave-execution `concurrencyCap` so operators can tune ticket-verification parallelism independently of Story dispatch parallelism. Default 4. |
136
+ | `worktreeIsolation` | No | `object` | — | Nested configuration block. |
137
+ | `worktreeIsolation.enabled` | No | `boolean` | — | — |
138
+ | `worktreeIsolation.root` | No | `string` | — | — |
139
+ | `worktreeIsolation.nodeModulesStrategy` | No | `"per-worktree"` \| `"symlink"` \| `"pnpm-store"` | — | — |
140
+ | `worktreeIsolation.primeFromPath` | No | `string` \| `null` | — | — |
141
+ | `worktreeIsolation.allowSymlinkOnWindows` | No | `boolean` | — | — |
142
+ | `worktreeIsolation.reapOnSuccess` | No | `boolean` | — | — |
143
+ | `worktreeIsolation.reapOnCancel` | No | `boolean` | — | — |
144
+ | `worktreeIsolation.bootstrapFiles` | No | `array<string>` | `[".env",".mcp.json"]` | — |
145
+ | `signals` | No | `object` | — | Nested configuration block. |
146
+ | `signals.hotspot` | No | `object` | — | Nested configuration block. |
147
+ | `signals.hotspot.p95Multiplier` | No | `number` | — | — |
148
+ | `signals.rework` | No | `object` | — | Nested configuration block. |
149
+ | `signals.rework.editsPerFile` | No | `integer` | — | — |
150
+ | `signals.retry` | No | `object` | — | Nested configuration block. |
151
+ | `signals.retry.repeatCount` | No | `integer` | — | — |
152
+ | `quality` | No | `object` | — | Nested configuration block. |
153
+ | `quality.gateScoping` | No | `object` | — | Nested configuration block. |
154
+ | `quality.gateScoping.scope` | No | `"diff"` \| `"full"` | — | — |
155
+ | `quality.gateScoping.diffRef` | No | `string` | — | — |
156
+ | `quality.gates` | No | `object` | — | Nested configuration block. |
157
+ | `quality.gates.lint` | No | `object` | — | Nested configuration block. |
158
+ | `quality.gates.lint.enabled` | No | `boolean` | — | — |
159
+ | `quality.gates.lint.baselinePath` | No | `string` | — | — |
160
+ | `quality.gates.lint.tolerance` | No | `object` | — | Nested configuration block. |
161
+ | `quality.gates.lint.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
162
+ | `quality.gates.lint.tolerance.value` | Yes | `number` | — | — |
163
+ | `quality.gates.lint.floors` | No | `object<map>` | — | — |
164
+ | `quality.gates.lint.components` | No | `object<map>` | — | — |
165
+ | `quality.gates.coverage` | No | `object` | — | Nested configuration block. |
166
+ | `quality.gates.coverage.enabled` | No | `boolean` | — | — |
167
+ | `quality.gates.coverage.baselinePath` | No | `string` | — | — |
168
+ | `quality.gates.coverage.tolerance` | No | `object` | — | Nested configuration block. |
169
+ | `quality.gates.coverage.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
170
+ | `quality.gates.coverage.tolerance.value` | Yes | `number` | — | — |
171
+ | `quality.gates.coverage.floors` | No | `object<map>` | — | — |
172
+ | `quality.gates.coverage.components` | No | `object<map>` | — | — |
173
+ | `quality.gates.coverage.coveragePath` | No | `string` | — | — |
174
+ | `quality.gates.coverage.timeoutMs` | No | `integer` | — | — |
175
+ | `quality.gates.crap` | No | `object` | — | Nested configuration block. |
176
+ | `quality.gates.crap.enabled` | No | `boolean` | — | — |
177
+ | `quality.gates.crap.baselinePath` | No | `string` | — | — |
178
+ | `quality.gates.crap.tolerance` | No | `object` | — | Nested configuration block. |
179
+ | `quality.gates.crap.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
180
+ | `quality.gates.crap.tolerance.value` | Yes | `number` | — | — |
181
+ | `quality.gates.crap.floors` | No | `object<map>` | — | — |
182
+ | `quality.gates.crap.components` | No | `object<map>` | — | — |
183
+ | `quality.gates.crap.targetDirs` | No | `string[]` or `{ append?, prepend? }` | — | Directories whose JS sources the CRAP gate scores. Mandrel ships a `src/`-centric default; projects whose executable code lives elsewhere (e.g. this repo's `.agents/scripts/`) override here. The framework default is intentionally not auto-discovered, so an override is the explicit, auditable signal. |
184
+ | `quality.gates.crap.newMethodCeiling` | No | `integer` | — | — |
185
+ | `quality.gates.crap.requireCoverage` | No | `boolean` | — | — |
186
+ | `quality.gates.crap.friction` | No | `object` | — | Nested configuration block. |
187
+ | `quality.gates.crap.friction.markerKey` | No | `string` | — | — |
188
+ | `quality.gates.crap.refreshTag` | No | `string` | — | — |
189
+ | `quality.gates.crap.refreshTimeoutMs` | No | `integer` | — | Bounded timeout (ms) for `npm run crap:update` spawned by the baseline-attribution refresh path. Mirrors `coverage.timeoutMs`: a SIGKILL fired at the budget boundary maps to exit 124 so the close orchestrator can flip the Story to `agent::blocked`. Default 60000 (Story #2165). |
190
+ | `quality.gates.crap.ignoreGlobs` | No | `array<string>` | — | Minimatch glob patterns matched against the canonicalised repo-relative path of each discovered file. Files matching any pattern are excluded from CRAP discovery before scoring. Orthogonal to `components` (grouping) — a file excluded here never appears in any component bucket. Absent or empty preserves the existing IGNORED_DIRS-only behaviour (Story #3217). |
191
+ | `quality.gates.maintainability` | No | `object` | — | Nested configuration block. |
192
+ | `quality.gates.maintainability.enabled` | No | `boolean` | — | — |
193
+ | `quality.gates.maintainability.baselinePath` | No | `string` | — | — |
194
+ | `quality.gates.maintainability.tolerance` | No | `object` | — | Nested configuration block. |
195
+ | `quality.gates.maintainability.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
196
+ | `quality.gates.maintainability.tolerance.value` | Yes | `number` | — | — |
197
+ | `quality.gates.maintainability.floors` | No | `object<map>` | — | — |
198
+ | `quality.gates.maintainability.components` | No | `object<map>` | — | — |
199
+ | `quality.gates.maintainability.targetDirs` | No | `string[]` or `{ append?, prepend? }` | — | Directories whose JS sources the maintainability gate scores. Mandrel ships a `src/`-centric default; projects whose executable code lives elsewhere (e.g. this repo's `.agents/scripts/` plus `tests/`) override here. The framework default is intentionally not auto-discovered, so an override is the explicit, auditable signal. |
200
+ | `quality.gates.maintainability.refreshTimeoutMs` | No | `integer` | — | Bounded timeout (ms) for `npm run maintainability:update` spawned by the baseline-attribution refresh path. Mirrors `coverage.timeoutMs`: a SIGKILL fired at the budget boundary maps to exit 124 so the close orchestrator can flip the Story to `agent::blocked`. Default 60000 (Story #2165). |
201
+ | `quality.gates.maintainability.ignoreGlobs` | No | `array<string>` | — | Minimatch glob patterns matched against the canonicalised repo-relative path of each discovered file. Files matching any pattern are excluded from MI discovery before scoring. Orthogonal to `components` (grouping) — a file excluded here never appears in any component bucket. Absent or empty preserves the existing IGNORED_DIRS-only behaviour (Story #3217). |
202
+ | `quality.gates.mutation` | No | `object` | — | Nested configuration block. |
203
+ | `quality.gates.mutation.enabled` | No | `boolean` | — | — |
204
+ | `quality.gates.mutation.baselinePath` | No | `string` | — | — |
205
+ | `quality.gates.mutation.tolerance` | No | `object` | — | Nested configuration block. |
206
+ | `quality.gates.mutation.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
207
+ | `quality.gates.mutation.tolerance.value` | Yes | `number` | — | — |
208
+ | `quality.gates.mutation.floors` | No | `object<map>` | — | — |
209
+ | `quality.gates.mutation.components` | No | `object<map>` | — | — |
210
+ | `quality.gates.mutation.strykerConfigPath` | No | `string` \| `null` | — | — |
211
+ | `quality.gates.lighthouse` | No | `object` | — | Nested configuration block. |
212
+ | `quality.gates.lighthouse.enabled` | No | `boolean` | — | — |
213
+ | `quality.gates.lighthouse.baselinePath` | No | `string` | — | — |
214
+ | `quality.gates.lighthouse.tolerance` | No | `object` | — | Nested configuration block. |
215
+ | `quality.gates.lighthouse.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
216
+ | `quality.gates.lighthouse.tolerance.value` | Yes | `number` | — | — |
217
+ | `quality.gates.lighthouse.floors` | No | `object<map>` | — | — |
218
+ | `quality.gates.lighthouse.components` | No | `object<map>` | — | — |
219
+ | `quality.gates.lighthouse.baseUrl` | No | `string` \| `null` | — | — |
220
+ | `quality.gates.lighthouse.routes[]` | No | `array<lighthouseRoute>` | — | Each item (`lighthouseRoute`) has: path, formFactor. |
221
+ | `quality.gates.bundle-size` | No | `object` | — | Nested configuration block. |
222
+ | `quality.gates.bundle-size.enabled` | No | `boolean` | — | — |
223
+ | `quality.gates.bundle-size.baselinePath` | No | `string` | — | — |
224
+ | `quality.gates.bundle-size.tolerance` | No | `object` | — | Nested configuration block. |
225
+ | `quality.gates.bundle-size.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
226
+ | `quality.gates.bundle-size.tolerance.value` | Yes | `number` | — | — |
227
+ | `quality.gates.bundle-size.floors` | No | `object<map>` | — | — |
228
+ | `quality.gates.bundle-size.components` | No | `object<map>` | — | — |
229
+ | `quality.gates.bundle-size.bundles[]` | No | `array<bundleDeclaration>` | — | Each item (`bundleDeclaration`) has: name, path, limit. |
230
+ | `quality.gates.duplication` | No | `object` | — | Nested configuration block. |
231
+ | `quality.gates.duplication.enabled` | No | `boolean` | — | — |
232
+ | `quality.gates.duplication.baselinePath` | No | `string` | — | — |
233
+ | `quality.gates.duplication.tolerance` | No | `object` | — | Nested configuration block. |
234
+ | `quality.gates.duplication.tolerance.kind` | Yes | `"absolute"` \| `"percent"` | — | — |
235
+ | `quality.gates.duplication.tolerance.value` | Yes | `number` | — | — |
236
+ | `quality.gates.duplication.floors` | No | `object<map>` | — | — |
237
+ | `quality.gates.duplication.components` | No | `object<map>` | — | — |
238
+ | `quality.gates.duplication.targetDirs` | No | `string[]` or `{ append?, prepend? }` | — | Directories whose JS sources the duplication (DRY) gate scans for copy-paste clones. Mandrel ships a `src/`-centric default; projects whose executable code lives elsewhere (e.g. this repo's `.agents/scripts/`) override here. The framework default is intentionally not auto-discovered, so an override is the explicit, auditable signal (Story #3664). |
239
+ | `quality.gates.duplication.refreshTimeoutMs` | No | `integer` | — | Bounded timeout (ms) for `npm run duplication:update` spawned by the baseline-attribution refresh path. Mirrors `crap.refreshTimeoutMs` / `coverage.timeoutMs`: a SIGKILL fired at the budget boundary maps to exit 124. Default 60000 (Story #3664). |
240
+ | `quality.gates.duplication.ignoreGlobs` | No | `array<string>` | — | Minimatch glob patterns matched against the canonicalised repo-relative path of each discovered file. Files matching any pattern are excluded from duplication discovery before scanning. Orthogonal to `components` (grouping). Absent or empty preserves the existing behaviour (Story #3664). |
241
+ | `quality.formatAutofix` | No | `object` | — | Bounded-timeout knob for the close-time `npx biome format --write` spawn (Story #2165). A SIGKILL fired at the budget boundary maps to exit 124 so the close orchestrator can flip the Story to `agent::blocked` with a friction comment. |
242
+ | `quality.formatAutofix.timeoutMs` | No | `integer` | — | — |
243
+ | `quality.codingGuardrails` | No | `object` | — | Nested configuration block. |
244
+ | `quality.codingGuardrails.cyclomaticFlag` | No | `integer` | — | — |
245
+ | `quality.codingGuardrails.cyclomaticMustFix` | No | `integer` | — | — |
246
+ | `quality.codingGuardrails.miDropMustRefactor` | No | `number` | — | — |
247
+ | `quality.codingGuardrails.requireSiblingTest` | No | `boolean` | — | — |
248
+ | `quality.autoRefresh` | No | `object` | — | Nested configuration block. |
249
+ | `quality.autoRefresh.enabled` | No | `boolean` | — | — |
250
+ | `quality.autoRefresh.miDropCap` | No | `number` | — | — |
251
+ | `quality.autoRefresh.crapJumpCap` | No | `number` | — | — |
252
+ | `quality.autoRefresh.scope` | No | `"diff"` \| `"full"` | — | — |
253
+ | `quality.baselineEpsilon` | No | `object` | — | Per-kind epsilon for s-stability-epsilon (Story #1964). Sub-epsilon row deltas resolve to prior bytes so env variance does not rewrite the on-disk baseline. |
254
+ | `quality.baselineEpsilon.maintainability` | No | `number` | — | — |
255
+ | `quality.baselineEpsilon.crap` | No | `number` | — | — |
256
+ | `quality.baselineEpsilon.coverage` | No | `number` | — | — |
257
+ | `quality.baselineEpsilon.mutation` | No | `number` | — | — |
258
+ | `quality.baselineEpsilon.lint` | No | `number` | — | — |
259
+ | `quality.baselineEpsilon.lighthouse` | No | `number` | — | — |
260
+ | `quality.baselineEpsilon.bundle-size` | No | `number` | — | — |
261
+ | `quality.baselineEpsilon.duplication` | No | `number` | — | — |
262
+ | `lifecycle` | No | `object` | — | Knobs consumed by the lifecycle event bus (Epic #2172). `timeouts` is a per-event budget map (eventName → seconds) used by `TimeoutWatchdog`; missing entries fall back to in-listener defaults. `heartbeatWarnSeconds` is the no-progress threshold consumed by `HeartbeatMonitor`. Story #2227 lays down the keys; consumers land in later stories. |
263
+ | `lifecycle.timeouts` | No | `object<map>` | — | — |
264
+ | `lifecycle.heartbeatWarnSeconds` | No | `integer` | — | — |
265
+ | `mergeWatch` | No | `object` | — | Knobs consumed by the MergeWatcher lifecycle listener (Story #2896, Epic #2880). `intervalSeconds` is the poll cadence between `gh pr view --json mergeCommit,mergedAt` probes after epic.merge.armed; `maxBudgetSeconds` is the total wall-clock budget before the watcher surfaces `agent::blocked` with reason `budget-exceeded`. |
266
+ | `mergeWatch.intervalSeconds` | No | `integer` | `30` | Seconds between MergeWatcher polls. Default 30. |
267
+ | `mergeWatch.maxBudgetSeconds` | No | `integer` | `3600` | Total wall-clock budget (seconds) for the MergeWatcher poll loop. Default 3600 (60 minutes). |
268
+ | `epicAudit` | No | `object` | — | Nested configuration block. |
269
+ | `epicAudit.maxFixAttempts` | No | `integer` | — | Maximum auto-fix retry attempts per finding in /epic-deliver Phase 4 (epic-audit). 0 disables auto-fix. Default 3. |
270
+ | `epicAudit.maxFixScopeFiles` | No | `integer` | — | Maximum file count a single auto-fix may modify before escalating to agent::blocked. Default 5. |
271
+ | `codeReview` | No | `object` | — | Nested configuration block. |
272
+ | `codeReview.provider` | No | `"native"` \| `"codex"` \| `"security-review"` | `"native"` | Legacy single-adapter selection. ReviewProvider that produces the Finding[] consumed by runCodeReview(). Story #2833 registered `native` (in-process maintainability/lint); Story #2830 added `codex` (invokes `/codex:review` plugin); Story #2871 added `security-review` (shells out to `claude --print /security-review`). When `providers` (chain shape) is set this field is ignored with a warning. Selecting an adapter whose probe fails hard-fails at factory construction unless declared `optional: true` in the chain. |
273
+ | `codeReview.providers[]` | No | `array<object>` | — | Multi-provider chain (Story #2871). When set and non-empty, takes precedence over the legacy `provider` field. 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. Each item has: name, scopes, optional, manualPrompt, when. |
274
+ | `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. |
275
+ | `codeReview.maxFixAttempts` | No | `integer` | — | Maximum auto-fix retry attempts per finding in /epic-deliver Phase 5 (code-review). 0 disables auto-fix. Default 3. |
276
+ | `codeReview.maxFixScopeFiles` | No | `integer` | — | Maximum file count a single auto-fix may modify before escalating to agent::blocked. Default 5. |
277
+ | `retro` | No | `object` | — | Story #3042 (Epic #3019). Operator-tunable retro behaviour. Currently exposes `perfThresholds`, the gates the retro perf-signals classifier uses to decide which signals to surface in the `## Performance Signals` / `## Recommended Follow-Ons` retro sections. |
278
+ | `retro.perfThresholds` | No | `object` | — | Gates for `classifyPerfSignals` (lib/orchestration/retro-perf-heuristics.js). Defaults are 0.6 / 0.4 / 2. |
279
+ | `retro.perfThresholds.utilisation` | No | `number` | — | Per-wave utilisation threshold. Waves whose `utilisation` is strictly below this value emit a `low-utilisation` signal. Default 0.6. |
280
+ | `retro.perfThresholds.bootstrapShare` | No | `number` | — | Maximum acceptable share of cumulative Story execution time spent in the story-init phase. When exceeded the retro emits a `high-bootstrap-share` signal. Default 0.4. |
281
+ | `retro.perfThresholds.capBindingRunLength` | No | `integer` | — | Minimum run length of consecutive cap-binding waves before the retro emits a `cap-binding-run` signal. Default 2. |
282
+ | `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. |
283
+ | `refactorStage.enabled` | No | `boolean` | `false` | When true, story-deliver runs an advisory post-green refactor stage (refactorer persona + core/refactoring-discipline skill) after the suite is green. Default false — when unset the stage is skipped and close-validation gate semantics are unchanged. |
284
+ | `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 working diff 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 loop is a hard cutover (always on). |
285
+ | `acceptanceEval.maxRounds` | No | `integer` | — | Maximum number of redraft rounds before escalation. Default 2; clamped into [1, hard ceiling] by lib/config/acceptance-eval.js so the cap can never be disabled (maxRounds: 0 clamps up to 1). |
286
+ | `ci` | No | `object` | — | Nested configuration block. |
287
+ | `ci.skipForStoryPushes` | No | `boolean` | — | Story #2899 (Epic #2880, F13). When true (default), pre-push tooling appends a '[skip ci]' trailer to Story-branch commit subjects so intermediate pushes do not stampede the CI fleet. The Epic-branch merge commit produced by story-close.js never carries the marker, regardless of this flag. |
288
+ | `preflight` | No | `object` | — | Story #2899 (Epic #2880, F13). Thresholds consumed by `.agents/scripts/epic-deliver-preflight.js`. When any value is exceeded the preflight envelope flags a breach and /epic-deliver Phase 1 surfaces it via agent::blocked. |
289
+ | `preflight.maxStories` | No | `integer` | — | — |
290
+ | `preflight.maxWaves` | No | `integer` | — | — |
291
+ | `preflight.maxInstallCostSeconds` | No | `integer` | — | — |
292
+ | `preflight.maxGithubApiRequests` | No | `integer` | — | — |
293
+ | `preflight.maxClaudeQuotaTokens` | No | `integer` | — | — |
294
+ | `failOnConcurrencyHazards` | No | `boolean` | — | — |
295
+ | `feedbackLoop` | No | `object` | — | Nested configuration block. |
296
+ | `feedbackLoop.codeReviewAutoFile` | No | `boolean` | `true` | When true (default), the Epic finalize listener auto-files non-blocking code-review 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 Epic. |
297
+ | `feedbackLoop.auditResultsAutoFile` | No | `boolean` | `true` | When true (default), the Epic finalize listener 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 Epic. |
298
+
299
+ <!-- END GENERATED:agentrc -->
300
+
301
+ ## `project` (required)
302
+
303
+ Project-local execution behaviour. Only `paths` is required; everything else
304
+ falls back to documented defaults.
305
+
306
+ ### `project.paths` (required)
307
+
308
+ Filesystem roots the framework reads from. All three keys are required —
309
+ the resolver no longer applies code-level fallbacks; a missing value is a
310
+ validation error with a clear `instancePath`.
311
+
312
+ | Field | Required | Purpose |
313
+ | ----------- | -------- | ------------------------------------------------ |
314
+ | `agentRoot` | Yes | Path to the materialized framework payload (e.g. `.agents`). |
315
+ | `docsRoot` | Yes | Path to project documentation (e.g. `docs`). |
316
+ | `tempRoot` | Yes | Path for ephemeral artefacts (e.g. `temp`). |
317
+
318
+ `auditOutputDir` is derived (not configurable) — it resolves to
319
+ `${tempRoot}/audits` and is the canonical destination for every
320
+ `audit-*` workflow's result reports **and** the audit-suite's prompt
321
+ artifacts. Override `tempRoot` to relocate audit output.
322
+
323
+ ### `project.baseBranch`
324
+
325
+ | Field | Required | Default | Purpose |
326
+ | ------------ | -------- | ------- | ------------------------------------------------------------------------- |
327
+ | `baseBranch` | No | (none) | Default branch name (e.g. `main`). Read by close, push, and rebase paths. |
328
+
329
+ ### `project.commands`
330
+
331
+ Executable strings the framework spawns for validation, testing, and baseline
332
+ ratchets. Strings must be non-empty and pass the shell-injection guard
333
+ (`safeString` — disallows `;`, `&`, `|`, backtick, `$`, `<`, `>`).
334
+
335
+ `typecheck` is nullable to indicate "not applicable for this repo"; `null`
336
+ is the canonical disabled value.
337
+
338
+ | Field | Required | Default | Type | Purpose |
339
+ | -------------- | -------- | ----------------------------- | --------------- | ------------------------------------------------------ |
340
+ | `lintBaseline` | No | (none) | `string` | Structured-output linter for the lint ratchet. |
341
+ | `test` | No | (none) | `string` | Project test runner. |
342
+ | `typecheck` | No | `null` | `string \| null` | Strict type-checking. `null` = disabled. |
343
+ | `formatCheck` | No | `npx biome format .` | `string` | Read-only format check used by close-validation. |
344
+ | `formatWrite` | No | `npx biome format --write .` | `string` | Auto-format invocation used by `runFormatAutofix`. |
345
+
346
+ Read with `getCommands(config)` — see
347
+ [`config-resolver.js`](../scripts/lib/config-resolver.js).
348
+
349
+ ### `project.docsContextFiles`
350
+
351
+ | Field | Required | Default | Purpose |
352
+ | ------------------ | -------- | ------- | -------------------------------------------------------------------------------------------------- |
353
+ | `docsContextFiles` | No | `[]` | Files the context-hydration engine includes when assembling agent prompts. Resolved against `paths.docsRoot`. |
354
+
355
+ ---
356
+
357
+ ## `github`
358
+
359
+ Ticketing provider configuration. Required when any GitHub-aware workflow
360
+ runs (which is the common case).
361
+
362
+ ### `github` — top-level
363
+
364
+ | Field | Required | Purpose |
365
+ | ---------------- | -------- | ------------------------------------------------------------------ |
366
+ | `owner` | Yes | GitHub repository owner (user or org). |
367
+ | `repo` | Yes | GitHub repository name. |
368
+ | `projectNumber` | No | GitHub Projects V2 number for custom field writes. |
369
+ | `projectOwner` | No | Project board owner (defaults to `owner`). |
370
+ | `operatorHandle` | No | `@`-prefixed handle used in operator @mentions. |
371
+
372
+ ### `github.branchProtection`
373
+
374
+ Drives the `node .agents/scripts/bootstrap.js` flow that creates or merges
375
+ branch protection on the base branch.
376
+
377
+ | Field | Required | Default | Purpose |
378
+ | ---------------- | -------- | ------- | ----------------------------------------------------------------------- |
379
+ | `enforce` | No | `true` | When `true`, `node .agents/scripts/bootstrap.js` calls `ensureMainBranchProtection(...)`. |
380
+ | `requiredChecks` | No | `[]` | Array of `{ name, cmd[] }` entries used both as required-status-check expectations on the PR and as local close-validation gate invocations. |
381
+
382
+ Each `requiredChecks` entry takes the shape:
383
+
384
+ ```jsonc
385
+ { "name": "lint", "cmd": ["npm", "run", "lint"] }
386
+ ```
387
+
388
+ ### `github.mergeMethods`
389
+
390
+ Repository-level merge-method allowlist applied by bootstrap.
391
+
392
+ | Field | Required | Default | Purpose |
393
+ | ------------------------ | -------- | ------- | ------------------------------------------------ |
394
+ | `allow_squash_merge` | No | `true` | Permit squash merges through the UI / `gh`. |
395
+ | `allow_rebase_merge` | No | `false` | Permit rebase merges. |
396
+ | `allow_merge_commit` | No | `false` | Permit merge commits. |
397
+ | `allow_auto_merge` | No | `true` | Enable auto-merge for the repository. |
398
+ | `delete_branch_on_merge` | No | `true` | Delete the source branch after merge. |
399
+
400
+ ### `github.notifications`
401
+
402
+ | Field | Required | Default | Purpose |
403
+ | ----------------- | -------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
404
+ | `mentionOperator` | No | `false` | When `true`, friction comments @-mention `operatorHandle` for `medium`-severity dispatches (high always @mentions). |
405
+ | `commentEvents` | No | `["state-transition", "story-merged", "operator-message"]` | Allowlist of event names that reach the GitHub ticket comment channel. |
406
+ | `webhookEvents` | No | `["epic-started", "epic-progress", "epic-blocked", "epic-unblocked", "epic-complete"]` | Allowlist of event names that reach `NOTIFICATION_WEBHOOK_URL`. The webhook channel is curated for the epic narrative; story-level events are excluded. |
407
+
408
+ Both fields' enums are pinned in the schema and rejected if extended. To
409
+ suppress a channel entirely, set its array to `[]`.
410
+
411
+ > **Severity assignment.** Task transitions and `story-run-progress` upserts
412
+ > fire `low` (frequency-driven). Story state transitions, `wave-run-progress`,
413
+ > `epic-run-progress`, and epic-completion fire `medium`. Epic blockers and
414
+ > HITL gates fire `high` (webhook prefix `[Action Required]` when an
415
+ > allowlisted blocker event reaches the webhook).
416
+
417
+ ---
418
+
419
+ ## `planning`
420
+
421
+ `/epic-plan` tuning. All fields optional.
422
+
423
+ | Field | Required | Default | Purpose |
424
+ | ------------------------------ | -------- | ---------- | ------------------------------------------------------------------------------------------------ |
425
+ | `riskHeuristics` | No | `[]` | Free-form rubric for `risk::high` decisions (informational only — `risk::high` does not gate runtime). Accepts a plain array or the `{ append/prepend }` extender form. |
426
+ | `maxTickets` | No | (none) | Soft cap on tickets a single Epic may decompose. |
427
+ | `failOnSharedEditors` | No | (none) | Hard-fail Phase 7 when two Stories declare the same editor. |
428
+ | `requireExplicitCrossStoryDeps`| No | (none) | Require explicit cross-Story `blocked by` declarations rather than inferring from shared paths. |
429
+
430
+ ### `planning.context`
431
+
432
+ Caps the size of `--emit-context` JSON payloads emitted during `/epic-plan`
433
+ so a runaway PRD / Tech Spec can't blow the planning agent's context budget.
434
+
435
+ | Field | Required | Default | Purpose |
436
+ | ------------- | -------- | -------- | --------------------------------------------------------------------------------------------- |
437
+ | `maxBytes` | No | `50000` | Hard ceiling on the JSON payload size (bytes). Truncation is summary-mode-aware. |
438
+ | `summaryMode` | No | `'auto'` | `'auto'` truncates intelligently; `'never'` errors over the cap; `'always'` always summarizes. |
439
+
440
+ ### `planning.codebaseSnapshot`
441
+
442
+ Controls the Phase 7 codebase-snapshot fetcher that grounds story decomposition.
443
+
444
+ | Field | Required | Default | Purpose |
445
+ | -------------------- | -------- | ----------- | ------------------------------------------------------------------------ |
446
+ | `tier` | No | `'skinny'` | One of `'skinny'` or `'medium'`. `medium` opts into a richer snapshot. |
447
+ | `include` | No | (see below) | Glob patterns whose matches are included in the snapshot. |
448
+ | `exclude` | No | (see below) | Glob patterns whose matches are excluded from the snapshot. |
449
+ | `recentCommitWindow` | No | (none) | Number of recent commits to summarise in the snapshot header. |
450
+
451
+ The shipped `include` default scans `.agents/scripts/**`, `src/**`,
452
+ `lib/**`, `app/**`, and `packages/**`; the shipped `exclude` default drops
453
+ `node_modules`, `dist`, `build`, and `coverage`. Override only when the
454
+ project's source layout differs.
455
+
456
+ The `skinny` tier caps its file list at 250 paths. When the include set
457
+ matches more than that, the cap is applied with **per-top-level-directory
458
+ proportional budgeting** (round-robin across the matched top-level trees)
459
+ rather than a flat lexicographic slice — so a large, dot-prefixed tree like
460
+ `.agents/scripts/**` can no longer monopolise the budget and truncate away
461
+ the consumer's own `src/` / `lib/` source. When `.agents/scripts/**` is the
462
+ only matching tree (the Mandrel-repo dogfood case), the round-robin
463
+ degenerates to taking the first 250 sorted paths, so that snapshot stays
464
+ useful. When truncation occurs, `/epic-plan` Phase 7 emits an
465
+ operator-visible warning naming the dropped file count and suggesting
466
+ `tier: "medium"` and/or a narrowed `include`. Opt into the richer `medium`
467
+ tier or narrow `include` if the partial skinny view is insufficient.
468
+
469
+ ---
470
+
471
+ ## `delivery`
472
+
473
+ `/epic-deliver` and `/story-deliver` tuning. All sub-blocks are optional and
474
+ fall back to documented defaults (or are no-ops when omitted).
475
+
476
+ ### `delivery.execution`
477
+
478
+ | Field | Required | Default | Purpose |
479
+ | ----------- | -------- | ------- | ------------------------------------------------------------------ |
480
+ | `timeoutMs` | No | (none) | Per-spawn timeout (ms) for child processes the framework launches. |
481
+
482
+ ### `delivery.maxTokenBudget`
483
+
484
+ | Field | Required | Default | Purpose |
485
+ | ----------------- | -------- | ------- | ------------------------------------------------------------------ |
486
+ | `maxTokenBudget` | No | (none) | Hydrated prompt cap for `hydrate-context` (character-based estimate + section elision). |
487
+
488
+ ### `delivery.docsFreshness`
489
+
490
+ | Field | Required | Default | Purpose |
491
+ | ------- | -------- | ------- | ------------------------------------------------------------- |
492
+ | `paths` | No | `[]` | Files refreshed during the post-PR-merge release tagging step. |
493
+
494
+ ### `delivery.deliverRunner`
495
+
496
+ | Field | Required | Default | Purpose |
497
+ | --------------------------- | -------- | ------- | ------------------------------------------------ |
498
+ | `concurrencyCap` | No | `3` | Max parallel Story sub-agents per wave. |
499
+ | `progressReportIntervalSec` | No | `120` | Progress-report cadence (seconds). |
500
+
501
+ ### `delivery.worktreeIsolation`
502
+
503
+ Story-level worktree isolation. When `enabled: true`, `/story-deliver` runs
504
+ each Story inside `.worktrees/story-<id>/` instead of moving the main
505
+ checkout's HEAD.
506
+
507
+ | Field | Required | Default | Purpose |
508
+ | ----------------------- | --------------- | ---------------- | ----------------------------------------------------------- |
509
+ | `enabled` | No | `false` | Master switch. |
510
+ | `root` | Conditional | `.worktrees` | Required when `enabled: true`. Worktree parent directory. |
511
+ | `nodeModulesStrategy` | No | `per-worktree` | One of `per-worktree`, `symlink`, `pnpm-store`. |
512
+ | `primeFromPath` | No | `null` | Optional source path used to prime `node_modules`. |
513
+ | `allowSymlinkOnWindows` | No | `false` | Permit symlink strategy on Windows (requires admin/dev mode). |
514
+ | `reapOnSuccess` | No | `true` | Reap the worktree after a successful Story close. |
515
+ | `reapOnCancel` | No | `true` | Reap the worktree if the Story is cancelled. |
516
+ | `bootstrapFiles` | No | `[".env", ".mcp.json"]` | Untracked files copied into each new worktree. |
517
+
518
+ ### `delivery.signals`
519
+
520
+ Friction-detector thresholds consumed by progress-signal listeners.
521
+
522
+ | Field | Required | Default | Purpose |
523
+ | ---------------------- | -------- | ------- | ------------------------------------------------------------------------ |
524
+ | `hotspot.p95Multiplier`| No | (none) | Hot-file threshold expressed as a multiplier of the p95 edit frequency. |
525
+ | `rework.editsPerFile` | No | (none) | Edits to the same file before a rework signal fires. |
526
+ | `retry.repeatCount` | No | (none) | Identical retried commands before a retry signal fires. |
527
+
528
+ ### `delivery.quality`
529
+
530
+ Quality-gate configuration. Lives under `delivery.quality` and uses the
531
+ uniform `gates.<tier>` shape (seven gates: `lint`, `coverage`, `crap`,
532
+ `maintainability`, `mutation`, `lighthouse`, `bundle-size`) introduced by
533
+ Epic #1720 Story #1737.
534
+
535
+ #### `delivery.quality.gateScoping`
536
+
537
+ | Field | Required | Default | Purpose |
538
+ | --------- | -------- | -------- | ------------------------------------------------------------------------------ |
539
+ | `scope` | No | `'full'` | One of `'diff'` (only files changed vs `diffRef`) or `'full'` (all targetDirs). |
540
+ | `diffRef` | No | (none) | Ref used to compute the diff when `scope: 'diff'` (e.g. `main`). |
541
+
542
+ #### `delivery.quality.gates.<tier>` — common shape
543
+
544
+ Every gate shares the same envelope:
545
+
546
+ | Field | Required | Purpose |
547
+ | -------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
548
+ | `enabled` | No | Master switch. `false` makes all three gate sites self-skip for this tier. |
549
+ | `baselinePath` | No | Path to the per-tier ratchet baseline file (e.g. `baselines/crap.json`). |
550
+ | `tolerance` | No | `{ kind: 'absolute' \| 'percent', value: <number> }` — slack permitted when comparing scores against baseline. |
551
+ | `floors` | No | `{ <workspace>: { <metric>: <number> } }` — absolute floors below which the gate fails regardless of baseline. |
552
+ | `components` | No | `{ <component>: [<glob>, ...] }` — optional component-level grouping for breakdown reporting. |
553
+
554
+ Tier-specific knobs:
555
+
556
+ ##### `gates.lint`
557
+
558
+ No tier-specific knobs beyond the common shape.
559
+
560
+ ##### `gates.coverage`
561
+
562
+ | Field | Required | Default | Purpose |
563
+ | -------------- | -------- | -------------------------------- | -------------------------------------------------------- |
564
+ | `coveragePath` | No | `coverage/coverage-final.json` | Per-method coverage artifact consumed by the gate. |
565
+ | `timeoutMs` | No | `600000` | Wall clock (ms) for `npm run test:coverage` spawned by `coverage-capture.js`. SIGKILL → exit 124 (GNU `timeout` convention) so close-validation can branch on hang-vs-failure. |
566
+
567
+ > **Canonical accessor.** Internal callers MUST read this block via
568
+ > `getQuality(config)` where `config` is the full envelope returned by
569
+ > `resolveConfig()` (or any object that exposes `delivery.quality.*`).
570
+ > Passing a sub-pick such as `getQuality({ agentSettings })` silently
571
+ > resolves to framework defaults — `agentSettings` is not part of the
572
+ > post-Epic-#2880 resolver output and `getQuality` reads only
573
+ > `config?.delivery?.quality`. The same applies to `getBaselines(config)`.
574
+
575
+ ##### `gates.crap`
576
+
577
+ | Field | Required | Default | Purpose |
578
+ | ------------------- | ----------- | --------------------------- | ---------------------------------------------------------------- |
579
+ | `targetDirs` | No | `["src"]` | Source dirs to score. Accepts list or `{ append/prepend }` form. |
580
+ | `newMethodCeiling` | No | `30` | Max CRAP score allowed for methods absent from the baseline. |
581
+ | `requireCoverage` | No | `true` | When `true`, methods without coverage are skipped (not failed). |
582
+ | `friction.markerKey`| No | `crap-baseline-regression` | Friction-log marker for regressions. |
583
+ | `refreshTag` | No | `baseline-refresh:` | Subject prefix the refresh-guardrail expects on baseline-only commits. |
584
+ | `refreshTimeoutMs` | No | `60000` | Bounded timeout (ms) for `npm run crap:update` in the baseline-attribution refresh path. SIGKILL → exit 124 → Story `agent::blocked`. |
585
+
586
+ ##### `gates.maintainability`
587
+
588
+ | Field | Required | Default | Purpose |
589
+ | ------------------ | -------- | ----------- | ---------------------------------------------------------------- |
590
+ | `targetDirs` | No | `["src"]` | Source dirs to score. Accepts list or `{ append/prepend }` form. |
591
+ | `refreshTimeoutMs` | No | `60000` | Bounded timeout (ms) for `npm run maintainability:update` in the baseline-attribution refresh path. |
592
+
593
+ ##### `gates.mutation`
594
+
595
+ | Field | Required | Default | Purpose |
596
+ | -------------------- | -------- | ------- | -------------------------------------------------------- |
597
+ | `strykerConfigPath` | No | `null` | Path to the Stryker config the mutation gate consumes. |
598
+
599
+ ##### `gates.lighthouse`
600
+
601
+ | Field | Required | Default | Purpose |
602
+ | --------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
603
+ | `baseUrl` | No | `null` | Base URL Lighthouse audits. |
604
+ | `routes` | No | `[]` | Array of `{ path, formFactor? }` entries, where `formFactor` is `'mobile'` or `'desktop'`. |
605
+
606
+ ##### `gates.bundle-size`
607
+
608
+ | Field | Required | Default | Purpose |
609
+ | --------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
610
+ | `bundles` | No | `[]` | Array of `{ name, path, limit }` entries (e.g. `{ "name": "app", "path": "dist/app.js", "limit": "100kB" }`). |
611
+
612
+ #### `delivery.quality.formatAutofix`
613
+
614
+ | Field | Required | Default | Purpose |
615
+ | ----------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
616
+ | `timeoutMs` | No | (none) | Bounded timeout (ms) for the close-time `npx biome format --write` spawn. SIGKILL maps to exit 124 → Story `agent::blocked`. |
617
+
618
+ #### `delivery.quality.codingGuardrails`
619
+
620
+ | Field | Required | Default | Purpose |
621
+ | ---------------------- | -------- | ------- | ------------------------------------------------------------------ |
622
+ | `cyclomaticFlag` | No | (none) | Cyclomatic-complexity value at which the engineer should refactor. |
623
+ | `cyclomaticMustFix` | No | (none) | Cyclomatic-complexity value that hard-fails the gate. |
624
+ | `miDropMustRefactor` | No | (none) | MI drop that mandates a refactor. |
625
+ | `requireSiblingTest` | No | (none) | When `true`, a new function requires a sibling test file. |
626
+
627
+ #### `delivery.quality.autoRefresh`
628
+
629
+ Controls Story-close auto-baseline-refresh for gated metrics.
630
+
631
+ | Field | Required | Default | Purpose |
632
+ | ------------- | -------- | ------- | -------------------------------------------------------- |
633
+ | `enabled` | No | (none) | Master switch. |
634
+ | `miDropCap` | No | (none) | Max MI drop the auto-refresher will absorb before failing. |
635
+ | `crapJumpCap` | No | (none) | Max CRAP jump the auto-refresher will absorb before failing. |
636
+ | `scope` | No | (none) | One of `'diff'` or `'full'`. |
637
+
638
+ #### `delivery.quality.baselineEpsilon`
639
+
640
+ Per-kind epsilon (introduced by Story #1964). Sub-epsilon row deltas resolve
641
+ to prior bytes so cross-environment variance does not rewrite the on-disk
642
+ baseline.
643
+
644
+ | Field | Required | Default | Purpose |
645
+ | ----------------- | -------- | ------- | -------------------------------------- |
646
+ | `maintainability` | No | (none) | Epsilon for maintainability rows. |
647
+ | `crap` | No | (none) | Epsilon for CRAP rows. |
648
+ | `coverage` | No | (none) | Epsilon for coverage rows. |
649
+ | `mutation` | No | (none) | Epsilon for mutation rows. |
650
+ | `lint` | No | (none) | Epsilon for lint rows. |
651
+ | `lighthouse` | No | (none) | Epsilon for Lighthouse rows. |
652
+ | `bundle-size` | No | (none) | Epsilon for bundle-size rows. |
653
+
654
+ ### `delivery.lifecycle`
655
+
656
+ Knobs consumed by the lifecycle event bus (Epic #2172). `timeouts` is a
657
+ per-event budget map (eventName → seconds) used by `TimeoutWatchdog`;
658
+ missing entries fall back to in-listener defaults.
659
+
660
+ | Field | Required | Default | Purpose |
661
+ | ---------------------- | -------- | ------- | ------------------------------------------------------ |
662
+ | `timeouts` | No | `{}` | `{ <eventName>: <seconds> }` watchdog budgets. |
663
+ | `heartbeatWarnSeconds` | No | (none) | No-progress threshold consumed by `HeartbeatMonitor`. |
664
+
665
+ ### `delivery.epicAudit`
666
+
667
+ `/epic-deliver` Phase 4 (epic-audit) auto-fix budget.
668
+
669
+ | Field | Required | Default | Purpose |
670
+ | ------------------ | -------- | ------- | -------------------------------------------------------------------- |
671
+ | `maxFixAttempts` | No | `3` | Max auto-fix retry attempts per finding. `0` disables auto-fix. |
672
+ | `maxFixScopeFiles` | No | `5` | Max file count a single auto-fix may modify before escalating to `agent::blocked`. |
673
+
674
+ ### `delivery.codeReview`
675
+
676
+ Configuration block for the code-review pipeline that runs at **both**
677
+ Story-close (`story-close.js`) and Epic-close (`/epic-deliver` Phase 5).
678
+ Selects the review backend, exposes an escape-hatch for adapter-specific
679
+ configuration, and sets the auto-fix budget enforced at each close scope.
680
+
681
+ | Field | Required | Default | Purpose |
682
+ | ------------------ | -------- | ---------- | -------------------------------------------------------------------- |
683
+ | `provider` | No | `"native"` | ReviewProvider adapter that produces the `Finding[]` consumed by `runCodeReview()`. See enum values below. |
684
+ | `providerConfig` | No | `{}` | Optional escape hatch for adapter-specific configuration. Reserved so future adapters can be configured without another schema migration; no documented keys in Epic #2815. |
685
+ | `maxFixAttempts` | No | `3` | Max auto-fix retry attempts per finding. `0` disables auto-fix. Applied at **both** Story-close and Epic-close. |
686
+ | `maxFixScopeFiles` | No | `5` | Max file count a single auto-fix may modify before escalating to `agent::blocked`. Applied at **both** Story-close and Epic-close. |
687
+
688
+ #### `provider` enum
689
+
690
+ | Value | Behaviour |
691
+ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
692
+ | `native` | Default. In-process maintainability/lint pass that runs without any external plugin. Always available. |
693
+ | `codex` | Invokes the `/codex:review` Claude Code plugin via the [`codex-plugin-cc`](https://github.com/openai/codex-plugin-cc) backend. Selecting `codex` when the plugin is not installed hard-fails at factory construction with remediation guidance — there is no silent fallback to `native`. |
694
+
695
+ #### Dual-scope fix budget
696
+
697
+ `maxFixAttempts` and `maxFixScopeFiles` are enforced at two distinct
698
+ points in the SDLC, using the **same configured values** for both scopes:
699
+
700
+ - **Story-close** — `story-close.js` runs `runCodeReview()` against the
701
+ Story branch's diff and applies the budget per finding before merging
702
+ into `epic/<epicId>`.
703
+ - **Epic-close** — `/epic-deliver` Phase 5 runs `runCodeReview()` against
704
+ the integrated Epic branch and applies the same per-finding budget
705
+ before opening the PR to `main`.
706
+
707
+ Setting `maxFixAttempts: 0` disables auto-fix at both scopes; there is no
708
+ per-scope override.
709
+
710
+ ### `delivery.failOnConcurrencyHazards`
711
+
712
+ | Field | Required | Default | Purpose |
713
+ | --------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------- |
714
+ | `failOnConcurrencyHazards` | No | (none) | When `true`, hard-fail the plan if Phase 7 detects shared-editor or unsequenced cross-Story deps. |
715
+
716
+ ### `delivery.feedbackLoop`
717
+
718
+ | Field | Required | Default | Purpose |
719
+ | ----------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
720
+ | `codeReviewAutoFile` | No | `true` | When `true`, the Epic finalize listener auto-files non-blocking code-review findings as follow-up issues routed by source classification. |
721
+ | `auditResultsAutoFile` | No | `true` | When `true`, the Epic finalize listener auto-files non-blocking audit-results findings as follow-up issues routed by source classification. |
722
+
723
+ ---
724
+
725
+ ## Root dogfood vs distributed templates
726
+
727
+ Three `.agentrc`-shaped files live in this repository and serve different
728
+ audiences. They share the same schema but legitimately disagree on a small
729
+ number of keys.
730
+
731
+ | File | Audience | Role |
732
+ | --------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
733
+ | `.agentrc.json` (repo root) | The framework dogfooding itself | Live config used when running `/epic-*` and `/story-deliver` workflows against this repo. Exercises the framework end-to-end on its own source tree. |
734
+ | `.agents/starter-agentrc.json` | Downstream consumer repos | Bootstrap delta-seed a consumer copies via `cp .agents/starter-agentrc.json .agentrc.json`. Minimum schema-required keys only. |
735
+ | `.agents/docs/agentrc-reference.json` | Operators and reviewers | Exhaustive editor reference enumerating every schema key with its framework default. Not a copy target. |
736
+
737
+ | Key | Root dogfood | Distributed template (`agentrc-reference.json`) | Why they differ |
738
+ | ---------------------------------------------------- | ------------------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
739
+ | `project.commands.lintBaseline` | `npm run lint` | `npx eslint . --format json` | Root piggybacks on the repo's existing lint script; consumer template assumes a generic ESLint setup with structured output. |
740
+ | `delivery.quality.gates.maintainability.targetDirs` | `[".agents/scripts", "tests"]` | `["src"]` | Root scans the framework's own source tree; consumer template scans the conventional `src/`. |
741
+ | `delivery.quality.gates.crap.targetDirs` | `[".agents/scripts"]` | `["src"]` | Same reason as maintainability above. |
742
+ | `github.owner` / `.repo` / `.projectNumber` | Populated for `dsj1984/mandrel` | `[OWNER]` / `[REPO]` / `null` | Shared repo identifiers; placeholders in the template are replaced by `node .agents/scripts/bootstrap.js` (or by hand). |
743
+ | `github.operatorHandle` | Committed as the `@[USERNAME]` placeholder; each contributor overrides it in gitignored `.agentrc.local.json` | `@[USERNAME]` | Schema-required, but per-contributor: the committed placeholder resolves to null and the lease guards fail closed until you set your own handle locally (see [Per-machine local overrides](#per-machine-local-overrides)). |
744
+ | `delivery.worktreeIsolation.nodeModulesStrategy` | `per-worktree` | `per-worktree` | npm-only repo (`package-lock.json`); worktree init runs `npm ci` per tree. |
745
+
746
+ When a consumer runs `/agents-update`, the
747
+ [`agents-sync-config`](../workflows/helpers/agents-sync-config.md)
748
+ helper validates the project config against the schema, then adds any
749
+ template-introduced keys the project does not already define. Project-side
750
+ values that validate are preserved unconditionally — including optional keys
751
+ the template does not declare.
752
+
753
+ > **Editing rule of thumb:** edit `.agents/docs/agentrc-reference.json` when a
754
+ > framework default changes; edit `.agents/starter-agentrc.json` only when
755
+ > the bootstrap seed itself needs new schema-required keys; edit
756
+ > `.agentrc.json` for changes that only affect this repo's own dogfood
757
+ > runs.
758
+
759
+ ---
760
+
761
+ ## Baseline conventions
762
+
763
+ The framework writes two distinct kinds of baseline file. They are intentionally
764
+ separated so a repo-wide grep never confuses one with the other.
765
+
766
+ ### Canonical ratchet baselines — `/baselines/`
767
+
768
+ Committed, schema-pointed baselines that gate every PR via close-validation,
769
+ the lint ratchet, and the CRAP/MI gates.
770
+
771
+ | File | Owner | Refresh |
772
+ | --------------------------------- | ------------------------------------ | ---------------------------------------------------------------------- |
773
+ | `baselines/lint.json` | `lint-baseline.js` | `node .agents/scripts/lint-baseline.js --refresh` |
774
+ | `baselines/crap.json` | `update-crap-baseline.js` | `npm run crap:update` |
775
+ | `baselines/maintainability.json` | `update-maintainability-baseline.js` | `npm run maintainability:update` |
776
+
777
+ These files are the contract. They are read by every gate (Story close, push
778
+ hook, CI) and are regenerated only via tagged `baseline-refresh:` commits
779
+ with a non-empty body. The convention is operator-enforced; see the CRAP
780
+ section of [`docs/quality-gates.md`](../../docs/quality-gates.md) for the policy.
781
+
782
+ Paths are configured in `delivery.quality.gates.<tier>.baselinePath`. The
783
+ default values match the canonical layout above; override only when a
784
+ project genuinely stores baselines elsewhere.
785
+
786
+ ### Per-wave drift snapshots — `.agents/state/`
787
+
788
+ The Epic runner's progress reporter writes wave-start snapshots so that a
789
+ resumed run can detect intra-wave drift without re-reading the canonical
790
+ baseline (which may have been refreshed mid-Epic).
791
+
792
+ | File | Owner | Lifecycle |
793
+ | --------------------------------------- | ---------------------------------------------------- | ----------------------------------------------- |
794
+ | `.agents/state/wave-mi-snapshot.json` | `progress-signals/maintainability-drift.js` | Captured at wave-start; overwritten next wave. |
795
+ | `.agents/state/wave-crap-snapshot.json` | `progress-signals/crap-drift.js` | Captured at wave-start; overwritten next wave. |
796
+
797
+ These are **not** ratchet baselines and must not be committed as such. The
798
+ filenames intentionally differ from the canonical files so a repo-wide grep
799
+ for `baselines/maintainability.json` or `baselines/crap.json` only ever hits
800
+ the canonical paths.
801
+
802
+ The `.agents/state/` directory itself is created on demand by the progress
803
+ reporter; the framework does not require it to exist ahead of time and does
804
+ not commit its contents.
805
+
806
+ ---
807
+
808
+ ## How to extend
809
+
810
+ ### Adding a project-specific optional key
811
+
812
+ The schema-driven sync helper preserves every project-side key that validates,
813
+ including optional keys absent from the distributed template. To add a
814
+ project-specific knob:
815
+
816
+ 1. Confirm the key is **already declared in the schema** at
817
+ [`.agents/schemas/agentrc.schema.json`](../schemas/agentrc.schema.json)
818
+ — if it isn't, the AJV validators will reject it on the next
819
+ `/agents-update`.
820
+ 2. Set the key in `.agentrc.json`. Don't add it to the template unless it
821
+ should ship to all consumers.
822
+ 3. Run `/agents-update` to confirm the helper preserves the key on round-trip.
823
+
824
+ ### Extending list-valued keys without losing template defaults
825
+
826
+ `delivery.quality.gates.maintainability.targetDirs`,
827
+ `delivery.quality.gates.crap.targetDirs`, and `planning.riskHeuristics`
828
+ accept the deep-merge extender form:
829
+
830
+ ```jsonc
831
+ {
832
+ "delivery": {
833
+ "quality": {
834
+ "gates": {
835
+ "crap": {
836
+ "targetDirs": { "append": ["packages/foo/src", "packages/bar/src"] }
837
+ }
838
+ }
839
+ }
840
+ }
841
+ }
842
+ ```
843
+
844
+ `{ "append": [...] }` and `{ "prepend": [...] }` extend the resolver's
845
+ fallback default. A plain array (`["packages/foo/src"]`) replaces the default
846
+ entirely — useful when the consumer wants exactly its own dirs.
847
+
848
+ ### Per-machine local overrides
849
+
850
+ `.agentrc.local.json` (gitignored) is layered on top of `.agentrc.json` by the
851
+ resolver. Precedence (highest wins): local → committed `.agentrc.json` →
852
+ built-in defaults. Object keys **deep-merge** so a local file can override one
853
+ nested field without restating sibling keys; absent local file is a no-op. Use
854
+ it for machine-specific tuning (e.g. lower
855
+ `delivery.deliverRunner.concurrencyCap` on a laptop) that should never reach
856
+ git.
857
+
858
+ **Per-contributor identity (required).** `github.operatorHandle` is a personal,
859
+ per-contributor value with two jobs: the `@`-handle the framework @mentions on
860
+ friction comments, **and** the lease owner the workflow guards
861
+ ([`ticket-lease.js`](../scripts/lib/orchestration/ticket-lease.js))
862
+ assign to a ticket so two contributors cannot drive the same Epic/Story
863
+ concurrently. Because the lease must distinguish *your* run from *another
864
+ person's*, a shared committed handle would defeat it — everyone would coordinate
865
+ under one identity. So each contributor sets their own in `.agentrc.local.json`:
866
+
867
+ ```json
868
+ {
869
+ "github": { "operatorHandle": "@your-handle" }
870
+ }
871
+ ```
872
+
873
+ `operatorHandle` is **required** by the schema, but the committed `.agentrc.json`
874
+ carries only the non-personal placeholder `@[USERNAME]` (so CI and fresh clones
875
+ validate without naming a real person). The placeholder is **not** a usable
876
+ identity: [`normalizeOperatorHandle`](../scripts/lib/orchestration/ticket-lease.js)
877
+ resolves `@[USERNAME]` to `null`, and the lease guards (`/epic-plan`,
878
+ `/epic-deliver`, `/story-deliver`) **fail closed** — they throw with a
879
+ "set your own handle in `.agentrc.local.json`" message rather than running an
880
+ ownerless, unguarded workflow. Your local overlay replaces the placeholder with
881
+ your real handle, and the guards proceed. By contrast, `github.owner` / `repo`
882
+ are **shared** repo identifiers (everyone targets the same `dsj1984/mandrel`)
883
+ and stay committed with real values.
884
+
885
+ ### Adding a new top-level key (framework change)
886
+
887
+ This is a framework-level change, not a project-level one. The path is:
888
+
889
+ 1. Add the AJV schema in the relevant module under
890
+ `.agents/scripts/lib/`.
891
+ 2. Mirror it manually in `.agents/schemas/agentrc.schema.json`.
892
+ 3. Add a resolver getter in
893
+ [`config-resolver.js`](../scripts/lib/config-resolver.js).
894
+ 4. Add tests under `tests/lib/config-*.test.js` and confirm
895
+ `tests/config-schema-mirror-drift.test.js` passes.
896
+ 5. Document the key in this file and update `agents-sync-config.md` only if
897
+ the merge semantics differ from the default (project-wins) rule.
898
+
899
+ ---
900
+
901
+ ## Secrets now live in `.env`
902
+
903
+ As of Epic #702 the framework no longer ships an MCP server, so
904
+ `.mcp.json` is **not** a valid home for framework secrets. Every
905
+ environment variable the orchestration engine reads is sourced from the
906
+ process environment only — loaded from `.env` locally, or set in the
907
+ Claude Code web environment-variables UI for web sessions.
908
+
909
+ ### Keys the framework reads
910
+
911
+ | Variable | Required? | Purpose |
912
+ | -------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
913
+ | `GITHUB_TOKEN` | Yes\* | GitHub API auth for all ticketing operations. `GH_TOKEN` is accepted as a synonym. `gh auth token` is a fallback for local sessions. |
914
+ | `NOTIFICATION_WEBHOOK_URL` | No | POST target for in-band Notifier events (Make.com / Slack / Discord). Unset disables the webhook channel; `log` and `epic-comment` channels still fire. |
915
+ | `WEBHOOK_SECRET` | No | Shared secret used to sign outbound webhook payloads as `X-Signature-256: sha256=<hmac>`. Unset ships unsigned payloads. |
916
+ | `MANDREL_ALLOW_TEST_WEBHOOKS` | No | Set to `1` to keep `NOTIFICATION_WEBHOOK_URL` live inside `npm test` / `npm run test:profile`. Default behaviour scrubs the env var from the test child so no URL resolves and the webhook never fires (see below). |
917
+
918
+ ### Test-mode webhook isolation
919
+
920
+ `npm test` / `npm run test:profile` deliberately strip
921
+ `NOTIFICATION_WEBHOOK_URL` from the spawned test child's environment (and
922
+ set `NODE_ENV=test` for the rest of the suite's environment
923
+ expectations). With the URL scrubbed, `resolveWebhookUrl()` returns
924
+ nothing and `notify()` never POSTs — that scrub is the primary defense.
925
+
926
+ `notify()` no longer carries a `NODE_ENV=test` band-aid (removed in Story
927
+ \#3342: it made the signing and error branches untestable). Tests that
928
+ need to exercise the webhook POST inject a fake fetch via `opts.fetchImpl`
929
+ instead, so the request is captured in-process and never reaches the real
930
+ network even if a URL resolves.
931
+
932
+ Operators who keep a real webhook URL in `.env` for development do not
933
+ need to change anything; the scrub is transparent. To deliberately fire
934
+ webhooks from a contract test against a sandbox endpoint, set
935
+ `MANDREL_ALLOW_TEST_WEBHOOKS=1` for that run.
936
+
937
+ \* `GITHUB_TOKEN` / `GH_TOKEN` is required for background scripts and CI;
938
+ a locally-authenticated `gh auth login` session is an acceptable
939
+ substitute in interactive developer sessions only.
940
+
941
+ ### Where to put them
942
+
943
+ | Environment | Storage location |
944
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------- |
945
+ | Local development | `.env` at the project root (auto-loaded by `config-resolver.js`). The file is `.gitignore`d; provision it per clone. |
946
+ | Web sessions | Claude Code web UI → environment-variables panel. |
947
+ | CI | Repo / org secret, surfaced into the runner via `ENV_FILE` or the workflow's `env:` block. |
948
+
949
+ `.mcp.json` is reserved for your MCP host's own discovery of third-party
950
+ servers (e.g. `@modelcontextprotocol/server-github`, `context7`) and is
951
+ ignored by the orchestration engine. Any framework-specific keys still
952
+ present in a `.mcp.json` from a pre-#702 checkout are **dead config** —
953
+ move them to `.env` (local) or your web session's env-var UI (web).
954
+
955
+ The webhook URL for external delivery is **not** configured in
956
+ `.agentrc.json`. It is sourced from the `NOTIFICATION_WEBHOOK_URL`
957
+ process env var only — set it in `.env` locally, in the Claude Code web
958
+ environment-variables UI for web sessions, or as a repo secret via
959
+ `ENV_FILE` for GitHub Actions runs.
960
+
961
+ ---
962
+
963
+ ## Permission allowlist maintenance (`/fewer-permission-prompts`)
964
+
965
+ The harness-supplied `/fewer-permission-prompts` skill scans recent
966
+ Claude Code transcripts, buckets repeated read-only `Bash(...)` and
967
+ `mcp__*` tool calls by frequency, and proposes an additive allowlist
968
+ patch for the project's `.claude/settings.json`. Running it on a
969
+ schedule is the only way to keep the allowlist tracking the framework's
970
+ actual surface area — without it, every new `.agents/scripts/<name>.js`
971
+ helper introduced by a framework bump triggers a fresh wave of
972
+ permission prompts that operators answer by hand, and those hand-tuned
973
+ allowlists drift project-to-project.
974
+
975
+ ### Cadence
976
+
977
+ Run `/fewer-permission-prompts` **once per `/agents-update`
978
+ invocation**, immediately after the package upgrade re-materializes
979
+ `.agents/` and before the bump commit lands. The cadence is codified in
980
+ [`/agents-update` Step 3.6](../workflows/agents-update.md). The
981
+ operator who just bumped `.agents/` has the freshest transcript context
982
+ in the active session, which is exactly what the skill scans, so this
983
+ is the cheapest time to surface new high-frequency calls.
984
+
985
+ A bump that introduces no new scripts produces a "no new high-frequency
986
+ calls" report from the skill — that is a valid outcome, not a reason to
987
+ skip the step on the next bump. Silence-by-omission is the failure
988
+ mode this cadence is meant to eliminate.
989
+
990
+ ### Review discipline
991
+
992
+ Treat the skill's output as a **PR-reviewable artifact**, not an
993
+ auto-applied change. The skill never edits `.claude/settings.json`
994
+ directly; it emits a proposed additive patch the operator approves
995
+ entry-by-entry.
996
+
997
+ **Accept** narrowly-scoped read-only entries:
998
+
999
+ - `Bash(node .agents/scripts/<name>.js *)` for helper scripts the
1000
+ framework just introduced.
1001
+ - `Bash(gh issue view *)`, `Bash(gh pr view *)`, and other read-only
1002
+ `gh` invocations that already appear in agent workflows.
1003
+ - `mcp__github__get_*`, `mcp__github__list_*`, `mcp__github__search_*`
1004
+ and similarly read-only MCP tool entries.
1005
+
1006
+ **Reject** anything that grants:
1007
+
1008
+ - Write permissions on the filesystem outside the worktree
1009
+ (`Bash(rm -rf *)`, `Bash(git push --force *)`,
1010
+ `mcp__github__delete_*`, `mcp__github__merge_pull_request`, etc.).
1011
+ - Network egress to non-framework endpoints.
1012
+ - Destructive shells (`Bash(gh release delete *)`,
1013
+ `mcp__github__push_files` against `main`).
1014
+
1015
+ When in doubt, leave the entry off the patch — a missed allowlist
1016
+ addition costs one permission prompt on the next run; a wrongly-added
1017
+ destructive permission costs trust. The rejected entries surface again
1018
+ on the next cadence run if they remain high-frequency, so the cost of
1019
+ deferral is bounded.
1020
+
1021
+ Stage the accepted `.claude/settings.json` diff alongside the
1022
+ `/agents-update` bump commit so the reviewer sees the framework pointer
1023
+ move and the allowlist response in the same diff.
1024
+
1025
+ ---
1026
+
1027
+ ## Cross-references
1028
+
1029
+ - JSON Schema mirror —
1030
+ [`.agents/schemas/agentrc.schema.json`](../schemas/agentrc.schema.json)
1031
+ - Resolver entry point —
1032
+ [`config-resolver.js`](../scripts/lib/config-resolver.js)
1033
+ - Sync helper —
1034
+ [`agents-sync-config.md`](../workflows/helpers/agents-sync-config.md)
1035
+ - Bootstrap script —
1036
+ [`bootstrap.js`](../scripts/bootstrap.js)
1037
+ - Quality gates runbook (CRAP onboarding, MI ratchet, lint ratchet) —
1038
+ [`docs/quality-gates.md`](../../docs/quality-gates.md)
1039
+ - Activation pointers (slash commands, personas, skills) —
1040
+ [`.agents/README.md`](../README.md)