mandrel 2.59.0 → 2.61.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 (678) hide show
  1. package/.agents/README.md +21 -19
  2. package/.agents/agents/acceptance-critic.md +24 -43
  3. package/.agents/agents/story-worker.md +20 -21
  4. package/.agents/docs/agentrc-reference.json +5 -84
  5. package/.agents/docs/configuration.md +48 -132
  6. package/.agents/docs/workflows.md +2 -2
  7. package/.agents/instructions.md +5 -8
  8. package/.agents/rules/ci-remediation.md +41 -8
  9. package/.agents/rules/gherkin-standards.md +4 -0
  10. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  11. package/.agents/schemas/agentrc.schema.json +16 -496
  12. package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
  13. package/.agents/schemas/validation-evidence.schema.json +2 -1
  14. package/.agents/scripts/README.md +23 -13
  15. package/.agents/scripts/acceptance-eval.js +35 -169
  16. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  17. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  18. package/.agents/scripts/audit-baselines.js +6 -27
  19. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  20. package/.agents/scripts/audit-to-stories.js +91 -361
  21. package/.agents/scripts/boot-sweep.js +19 -72
  22. package/.agents/scripts/bootstrap.js +74 -395
  23. package/.agents/scripts/ceremony-derive.js +10 -41
  24. package/.agents/scripts/check-arch-cycles.js +14 -64
  25. package/.agents/scripts/check-baselines.js +8 -48
  26. package/.agents/scripts/check-context-budget.js +105 -311
  27. package/.agents/scripts/check-cyclomatic.js +12 -44
  28. package/.agents/scripts/check-dead-exports.js +13 -64
  29. package/.agents/scripts/check-doc-links.js +38 -186
  30. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  31. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  32. package/.agents/scripts/coverage-capture.js +34 -98
  33. package/.agents/scripts/deliver-light.js +25 -171
  34. package/.agents/scripts/deliver-recover.js +6 -42
  35. package/.agents/scripts/deliver-run.js +534 -0
  36. package/.agents/scripts/diagnose-friction.js +24 -116
  37. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  38. package/.agents/scripts/evidence-gate.js +23 -85
  39. package/.agents/scripts/file-ci-gap.js +57 -49
  40. package/.agents/scripts/generate-config-docs.js +30 -170
  41. package/.agents/scripts/generate-lens-checklists.js +8 -52
  42. package/.agents/scripts/generate-skills-index.js +14 -112
  43. package/.agents/scripts/generate-workflows-doc.js +10 -70
  44. package/.agents/scripts/git-cleanup.js +2 -34
  45. package/.agents/scripts/lib/Graph.js +24 -81
  46. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  47. package/.agents/scripts/lib/Logger.js +14 -76
  48. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  49. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  50. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  51. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  52. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  53. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  54. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  55. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  56. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  57. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  58. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  59. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  60. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  61. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  62. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  63. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  64. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  65. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  66. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  67. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  68. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  69. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  70. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  71. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  72. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  73. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  74. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  75. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  76. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  77. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  78. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  79. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  80. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  81. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  82. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  83. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  84. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  85. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  86. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  87. package/.agents/scripts/lib/baseline-loader.js +12 -51
  88. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  89. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  90. package/.agents/scripts/lib/baselines/components.js +10 -61
  91. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  92. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
  93. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  94. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  95. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  96. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  97. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  98. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  99. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  100. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  101. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  102. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  103. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  104. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  105. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  106. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  107. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  108. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  109. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  110. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  111. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  112. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  113. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  114. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  115. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  116. package/.agents/scripts/lib/baselines/reader.js +14 -107
  117. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  118. package/.agents/scripts/lib/baselines/scope.js +11 -135
  119. package/.agents/scripts/lib/baselines/writer.js +16 -149
  120. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  121. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  122. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  123. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  124. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  125. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  126. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  127. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  128. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  129. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  130. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  131. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  132. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  133. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  134. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  135. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  136. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  137. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  138. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  139. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  140. package/.agents/scripts/lib/changed-files.js +39 -121
  141. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  142. package/.agents/scripts/lib/checks/index.js +18 -101
  143. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  144. package/.agents/scripts/lib/checks/state.js +16 -91
  145. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  146. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  147. package/.agents/scripts/lib/child-exec.js +39 -108
  148. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  149. package/.agents/scripts/lib/cli-args.js +31 -146
  150. package/.agents/scripts/lib/cli-usage.js +5 -27
  151. package/.agents/scripts/lib/cli-utils.js +2 -12
  152. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  153. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  154. package/.agents/scripts/lib/close-validation/process.js +121 -151
  155. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  156. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  157. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  158. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  159. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  160. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  161. package/.agents/scripts/lib/command-header.js +6 -28
  162. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  163. package/.agents/scripts/lib/config/baselines.js +3 -14
  164. package/.agents/scripts/lib/config/ci.js +8 -38
  165. package/.agents/scripts/lib/config/commands.js +1 -15
  166. package/.agents/scripts/lib/config/defaults.js +4 -33
  167. package/.agents/scripts/lib/config/delivery-routing.js +6 -34
  168. package/.agents/scripts/lib/config/explain.js +10 -83
  169. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  170. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
  171. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  172. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  173. package/.agents/scripts/lib/config/gates/index.js +2 -17
  174. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  175. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  176. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  177. package/.agents/scripts/lib/config/github.js +4 -22
  178. package/.agents/scripts/lib/config/limits.js +4 -57
  179. package/.agents/scripts/lib/config/paths.js +2 -21
  180. package/.agents/scripts/lib/config/qa.js +4 -38
  181. package/.agents/scripts/lib/config/quality.js +76 -432
  182. package/.agents/scripts/lib/config/runners.js +12 -56
  183. package/.agents/scripts/lib/config/runtime.js +13 -57
  184. package/.agents/scripts/lib/config/shared.js +2 -16
  185. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  186. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  187. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  188. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  189. package/.agents/scripts/lib/config-resolver.js +11 -52
  190. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  191. package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
  192. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  193. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  194. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  195. package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
  196. package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
  197. package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
  198. package/.agents/scripts/lib/coverage-capture.js +99 -224
  199. package/.agents/scripts/lib/coverage-utils.js +14 -79
  200. package/.agents/scripts/lib/cpu-pool.js +17 -123
  201. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  202. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  203. package/.agents/scripts/lib/crap-engine.js +40 -153
  204. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  205. package/.agents/scripts/lib/crap-utils.js +31 -155
  206. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  207. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  208. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  209. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  210. package/.agents/scripts/lib/degraded-mode.js +3 -26
  211. package/.agents/scripts/lib/dependency-parser.js +8 -40
  212. package/.agents/scripts/lib/dependency-version.js +13 -35
  213. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  214. package/.agents/scripts/lib/doc-tiers.js +22 -124
  215. package/.agents/scripts/lib/duplicate-search.js +8 -72
  216. package/.agents/scripts/lib/env-loader.js +5 -27
  217. package/.agents/scripts/lib/error-redactor.js +6 -31
  218. package/.agents/scripts/lib/errors/index.js +2 -22
  219. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  220. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  221. package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
  222. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  223. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
  224. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  225. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  226. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  227. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  228. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  229. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  230. package/.agents/scripts/lib/findings/severity.js +18 -104
  231. package/.agents/scripts/lib/format-generated-json.js +12 -44
  232. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  233. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  234. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  235. package/.agents/scripts/lib/gates/friction.js +1 -3
  236. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  237. package/.agents/scripts/lib/gh-exec.js +123 -191
  238. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  239. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  240. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  241. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  242. package/.agents/scripts/lib/git-utils.js +37 -161
  243. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  244. package/.agents/scripts/lib/github-url.js +2 -17
  245. package/.agents/scripts/lib/import-graph.js +11 -38
  246. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  247. package/.agents/scripts/lib/json-utils.js +3 -18
  248. package/.agents/scripts/lib/label-constants.js +16 -111
  249. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  250. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  251. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  252. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  253. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  254. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  255. package/.agents/scripts/lib/npm-scripts.js +4 -23
  256. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  257. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  258. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  259. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  260. package/.agents/scripts/lib/observability/source-classifier.js +22 -203
  261. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  262. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  263. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  264. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  265. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  266. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  267. package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
  268. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  274. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  275. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  276. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  277. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  278. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  279. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
  280. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  281. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  282. package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
  283. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  284. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  285. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  286. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  287. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  288. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  289. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  290. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  291. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  292. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  293. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  294. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  295. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  308. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  309. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  310. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  311. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  313. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  314. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  315. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  316. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  317. package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
  318. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  319. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  320. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  321. package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
  322. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  323. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  324. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  325. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  326. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  327. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  328. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
  329. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  330. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  331. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  332. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  333. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  334. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  335. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
  336. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  337. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
  338. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
  339. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
  340. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  341. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  342. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  343. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  344. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  345. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  346. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  347. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  348. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  349. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  350. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  351. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  352. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  353. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  354. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  355. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  356. package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
  357. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  358. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  359. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  360. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  361. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  362. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  363. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  364. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  365. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  366. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  367. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  368. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  369. package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
  370. package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
  371. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  372. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  373. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  391. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  392. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  393. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
  394. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  395. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  396. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  397. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  398. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  399. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  400. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  401. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  402. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
  403. package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
  404. package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
  405. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  406. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  407. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
  408. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  409. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  410. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  411. package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
  412. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  413. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
  414. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  415. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  416. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  417. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  418. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  419. package/.agents/scripts/lib/path-security.js +3 -6
  420. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  421. package/.agents/scripts/lib/preflight-runner.js +13 -69
  422. package/.agents/scripts/lib/process-group.js +143 -0
  423. package/.agents/scripts/lib/project-root.js +2 -8
  424. package/.agents/scripts/lib/provider-factory.js +2 -25
  425. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  426. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  427. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  428. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  429. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  430. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  431. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  432. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  433. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  434. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  435. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  436. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  437. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  438. package/.agents/scripts/lib/signals/index.js +2 -19
  439. package/.agents/scripts/lib/signals/schema.js +14 -109
  440. package/.agents/scripts/lib/signals/write.js +2 -11
  441. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  442. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  443. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  444. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  445. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  446. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  447. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  448. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  449. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  450. package/.agents/scripts/lib/source-extensions.js +11 -42
  451. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  452. package/.agents/scripts/lib/stdio-flush.js +9 -36
  453. package/.agents/scripts/lib/story-adjacency.js +8 -40
  454. package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
  455. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  456. package/.agents/scripts/lib/story-body/story-body.js +123 -344
  457. package/.agents/scripts/lib/temp-retention.js +42 -143
  458. package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
  459. package/.agents/scripts/lib/test-env.js +12 -65
  460. package/.agents/scripts/lib/test-run-credit.js +10 -65
  461. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  462. package/.agents/scripts/lib/test-temp.js +38 -184
  463. package/.agents/scripts/lib/test-tiers.js +12 -96
  464. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  465. package/.agents/scripts/lib/transpile.js +15 -74
  466. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  467. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  468. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  469. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  470. package/.agents/scripts/lib/validation-evidence.js +21 -96
  471. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  472. package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
  473. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  474. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  475. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  476. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  477. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  478. package/.agents/scripts/lib/workflow-closure.js +22 -105
  479. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  480. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  481. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  482. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  483. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  484. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  485. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  486. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  487. package/.agents/scripts/lib/worktree-manager.js +15 -40
  488. package/.agents/scripts/lint-issue-body.js +12 -68
  489. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  490. package/.agents/scripts/merge-baseline.js +30 -105
  491. package/.agents/scripts/nav-registry-diff.js +22 -108
  492. package/.agents/scripts/notify.js +12 -69
  493. package/.agents/scripts/plan-context.js +97 -92
  494. package/.agents/scripts/plan-critics.js +12 -66
  495. package/.agents/scripts/plan-persist.js +71 -137
  496. package/.agents/scripts/plan-run-epilogue.js +20 -43
  497. package/.agents/scripts/pr-watch-with-update.js +79 -263
  498. package/.agents/scripts/providers/github/auth.js +3 -8
  499. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  500. package/.agents/scripts/providers/github/board-add.js +5 -21
  501. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  502. package/.agents/scripts/providers/github/cache.js +2 -14
  503. package/.agents/scripts/providers/github/comments.js +7 -40
  504. package/.agents/scripts/providers/github/compose.js +3 -19
  505. package/.agents/scripts/providers/github/errors.js +22 -125
  506. package/.agents/scripts/providers/github/issues.js +31 -123
  507. package/.agents/scripts/providers/github/labels.js +24 -124
  508. package/.agents/scripts/providers/github/mappers.js +5 -27
  509. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  510. package/.agents/scripts/providers/github/project-board.js +2 -17
  511. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  512. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  513. package/.agents/scripts/providers/github/search-budget.js +9 -39
  514. package/.agents/scripts/providers/github/search-query.js +5 -26
  515. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  516. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  517. package/.agents/scripts/providers/github/tickets.js +32 -134
  518. package/.agents/scripts/providers/github.js +18 -59
  519. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  520. package/.agents/scripts/quality-preview.js +35 -220
  521. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  522. package/.agents/scripts/resolve-stories.js +16 -67
  523. package/.agents/scripts/resync-status-column.js +6 -25
  524. package/.agents/scripts/run-tests.js +29 -104
  525. package/.agents/scripts/single-story-close.js +23 -135
  526. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  527. package/.agents/scripts/single-story-init.js +47 -259
  528. package/.agents/scripts/stories-wave-tick.js +179 -415
  529. package/.agents/scripts/sync-agentrc.js +3 -21
  530. package/.agents/scripts/sync-claude-agents.js +9 -55
  531. package/.agents/scripts/sync-claude-commands.js +20 -110
  532. package/.agents/scripts/test-wrapper.js +6 -43
  533. package/.agents/scripts/update-coverage-baseline.js +5 -22
  534. package/.agents/scripts/update-crap-baseline.js +7 -30
  535. package/.agents/scripts/update-duplication-baseline.js +16 -92
  536. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  537. package/.agents/scripts/update-ticket-state.js +1 -7
  538. package/.agents/scripts/validate-skills.js +6 -26
  539. package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
  540. package/.agents/skills/skills.index.json +2 -2
  541. package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
  542. package/.agents/templates/agent-protocol.md +2 -2
  543. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  544. package/.agents/workflows/audit-accessibility.md +4 -7
  545. package/.agents/workflows/audit-adrs.md +3 -6
  546. package/.agents/workflows/audit-architecture.md +3 -11
  547. package/.agents/workflows/audit-baselines.md +6 -9
  548. package/.agents/workflows/audit-clean-code.md +8 -12
  549. package/.agents/workflows/audit-data-model.md +3 -7
  550. package/.agents/workflows/audit-dependencies.md +4 -7
  551. package/.agents/workflows/audit-devops.md +4 -8
  552. package/.agents/workflows/audit-documentation.md +1 -4
  553. package/.agents/workflows/audit-mobile.md +4 -7
  554. package/.agents/workflows/audit-navigability.md +3 -6
  555. package/.agents/workflows/audit-performance.md +2 -4
  556. package/.agents/workflows/audit-privacy.md +4 -7
  557. package/.agents/workflows/audit-quality.md +4 -7
  558. package/.agents/workflows/audit-security.md +4 -7
  559. package/.agents/workflows/audit-seo.md +4 -7
  560. package/.agents/workflows/audit-sre.md +4 -7
  561. package/.agents/workflows/audit-to-stories.md +17 -30
  562. package/.agents/workflows/audit-ux-ui.md +4 -7
  563. package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
  564. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  565. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  566. package/.agents/workflows/helpers/code-review.md +4 -2
  567. package/.agents/workflows/helpers/deliver-digest.md +37 -28
  568. package/.agents/workflows/helpers/deliver-light.md +92 -101
  569. package/.agents/workflows/helpers/deliver-reference.md +162 -220
  570. package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
  571. package/.agents/workflows/helpers/deliver-story.md +17 -18
  572. package/.agents/workflows/helpers/plan-reference.md +125 -167
  573. package/.agents/workflows/helpers/qa-core.md +12 -0
  574. package/.agents/workflows/mandrel-deliver.md +47 -31
  575. package/.agents/workflows/mandrel-plan.md +22 -21
  576. package/.agents/workflows/mandrel-update.md +36 -21
  577. package/.agents/workflows/memory-consolidate.md +1 -1
  578. package/.agents/workflows/qa-assist.md +27 -71
  579. package/.agents/workflows/qa-explore.md +19 -59
  580. package/.agents/workflows/qa-run.md +11 -33
  581. package/README.md +1 -1
  582. package/bin/mandrel.js +5 -46
  583. package/bin/postinstall.js +18 -107
  584. package/docs/CHANGELOG.md +60 -0
  585. package/lib/cli/doctor.js +11 -71
  586. package/lib/cli/init.js +26 -165
  587. package/lib/cli/migrate.js +5 -64
  588. package/lib/cli/registry.js +84 -467
  589. package/lib/cli/sync-agents.js +4 -64
  590. package/lib/cli/sync-commands.js +11 -64
  591. package/lib/cli/sync.js +34 -213
  592. package/lib/cli/uninstall.js +40 -219
  593. package/lib/cli/update.js +326 -523
  594. package/lib/cli/version-check.js +8 -72
  595. package/lib/cli/version-helpers.js +14 -87
  596. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  597. package/lib/migrations/index.js +17 -92
  598. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  599. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  600. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  601. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  602. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  603. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  604. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  605. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  606. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
  607. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  608. package/package.json +17 -14
  609. package/.agents/docs/SDLC.md +0 -590
  610. package/.agents/docs/quality-gates.md +0 -1179
  611. package/.agents/rules/known-tooling-behavior.md +0 -150
  612. package/.agents/rules/orchestration-error-handling.md +0 -61
  613. package/.agents/rules/test-seams.md +0 -59
  614. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  615. package/.agents/schemas/baselines/lint.schema.json +0 -47
  616. package/.agents/schemas/model-attribution.schema.json +0 -53
  617. package/.agents/scripts/check-action-pinning.js +0 -260
  618. package/.agents/scripts/check-audit-attribution.js +0 -302
  619. package/.agents/scripts/check-baseline-drift.js +0 -211
  620. package/.agents/scripts/check-baseline-scope.js +0 -362
  621. package/.agents/scripts/check-generated-validator.js +0 -202
  622. package/.agents/scripts/check-knip-entries.js +0 -159
  623. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  624. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  625. package/.agents/scripts/check-schema-references.js +0 -366
  626. package/.agents/scripts/check-test-portability.js +0 -512
  627. package/.agents/scripts/check-workflow-citations.js +0 -332
  628. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  629. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  630. package/.agents/scripts/install-matrix-assert.js +0 -326
  631. package/.agents/scripts/lib/audit-advisories.js +0 -195
  632. package/.agents/scripts/lib/audit-attribution.js +0 -134
  633. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  634. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  635. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  636. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  637. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  638. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  639. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  640. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  641. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  642. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  643. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  644. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  645. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  646. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  647. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  648. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  649. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  650. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  651. package/.agents/scripts/lib/fs-walk.js +0 -52
  652. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  653. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  654. package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
  655. package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
  656. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
  657. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  658. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  659. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  660. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  661. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  662. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  663. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  664. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  665. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  666. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  667. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  668. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  669. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  670. package/.agents/scripts/post-structured-comment.js +0 -127
  671. package/.agents/scripts/provision-git-hooks.js +0 -85
  672. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  673. package/.agents/scripts/run-coverage.js +0 -197
  674. package/.agents/scripts/run-lint.js +0 -133
  675. package/.agents/scripts/run-test-profile.js +0 -129
  676. package/.agents/scripts/run-verify.js +0 -118
  677. package/.agents/scripts/test-isolate.js +0 -55
  678. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -1,24 +1,8 @@
1
1
  /**
2
- * verify-credit.js — decide whether a Story `verify[]` entry has already been
3
- * paid for by the delivery's single credited full-suite run (Story #5174).
4
- *
5
- * A Story's `verify[]` is meant to be *scoped* entries plus the one credited
6
- * full-suite run the worker makes just before the hand-off push
7
- * (`helpers/deliver-digest.md` § 5). When a `verify[]` entry is itself a
8
- * full-suite command, running it spends a second whole-suite spawn for a
9
- * result the credited run already established — and the close gate chain then
10
- * makes a third. This module is the read side of that credit: given the
11
- * entry's command it consults **the same stamp close consults** and reports
12
- * the entry as credited instead of telling the caller to spawn it.
13
- *
14
- * It only ever *reads*. Nothing here writes a capture stamp or an evidence
15
- * record — an entry that is not covered by a fresh stamp or a credited
16
- * `test` evidence record (Story #5313: a green bare `npm test` deposits one)
17
- * is reported `spawn: true` and runs for real, so the credit can never
18
- * manufacture a pass.
19
- *
20
- * @see .agents/scripts/lib/coverage-capture.js (`isCoverageFresh`)
21
- * @see .agents/scripts/lib/validation-evidence.js (`shouldSkip`)
2
+ * Report a full-suite `verify[]` entry as credited when the stamp or `test`
3
+ * evidence close consults already covers it, instead of respawning the suite.
4
+ * Read-only: an uncovered entry is `spawn: true`, so credit never
5
+ * manufactures a pass.
22
6
  */
23
7
 
24
8
  import { getQuality, resolveConfig } from '../config-resolver.js';
@@ -31,34 +15,17 @@ import {
31
15
  treeFingerprint,
32
16
  } from '../validation-evidence.js';
33
17
 
34
- /**
35
- * The shape a `verify[]` array is supposed to have, stated once so the
36
- * warning a caller surfaces and the prose in `deliver-digest.md` § 5 say the
37
- * same thing.
38
- * @type {string}
39
- */
18
+ /** @type {string} */
40
19
  export const FULL_SUITE_SHAPE_WARNING =
41
20
  'verify[] should be scoped entries plus the single credited full-suite run ' +
42
21
  '(deliver-digest.md § 5) — a full-suite command listed in verify[] is ' +
43
22
  'reported credited against that run, never respawned.';
44
23
 
45
- /** Package managers whose `test` script means "the whole suite". */
46
24
  const PACKAGE_MANAGERS = new Set(['npm', 'pnpm', 'yarn', 'bun']);
47
25
 
48
- /** Script names that mean "the whole suite" rather than a scoped subset. */
49
26
  const FULL_SUITE_SCRIPTS = new Set(['test', 'test:coverage']);
50
27
 
51
- /**
52
- * Flags that narrow a runner's work to a subset of the suite (Story #5278).
53
- *
54
- * A positional path is not the only way to scope a run: Node's test runner
55
- * takes filter flags that select a fraction of the tests while the argv still
56
- * reads as a bare `node --test`. Crediting one of those against the full-suite
57
- * stamp reports a filtered run as the whole suite — the exact false positive
58
- * {@link isFullSuiteCommand} exists to refuse. Matched by prefix so both
59
- * spellings (`--test-only`, `--test-name-pattern=x`, `--test-name-pattern x`)
60
- * are caught.
61
- */
28
+ /** Filter flags that scope a bare-looking `node --test`; `=value` form too. */
62
29
  const NARROWING_FLAGS = Object.freeze([
63
30
  '--test-name-pattern',
64
31
  '--test-skip-pattern',
@@ -66,10 +33,6 @@ const NARROWING_FLAGS = Object.freeze([
66
33
  ]);
67
34
 
68
35
  /**
69
- * Does any token narrow the run to a subset of the suite? Pure helper for
70
- * {@link isFullSuiteCommand}, split out so that function's own branching stays
71
- * inside its committed cyclomatic budget.
72
- *
73
36
  * @param {string[]} tokens
74
37
  * @returns {boolean}
75
38
  */
@@ -82,11 +45,8 @@ function hasNarrowingFlag(tokens) {
82
45
  }
83
46
 
84
47
  /**
85
- * Split a Story `verify[]` line into its command and its tier tag.
86
- *
87
- * Story bodies write entries as `` `<command>` (<tier>) `` — the tier is
88
- * planning metadata, not part of the command, and leaving it attached would
89
- * make every entry look scoped.
48
+ * Strip a trailing `(<tier>)` tag, which would otherwise make every entry
49
+ * look scoped.
90
50
  *
91
51
  * @param {string} entry
92
52
  * @returns {{ command: string, tier: string|null }}
@@ -99,12 +59,8 @@ export function parseVerifyEntry(entry) {
99
59
  }
100
60
 
101
61
  /**
102
- * Is this command a whole-suite run?
103
- *
104
- * Deliberately narrow. A false positive here would report a *scoped* command
105
- * as credited without ever running it, which is how a gate stops gating — so
106
- * anything carrying its own positional argument (`npm test -- tests/x.js`,
107
- * `node --test tests/x.js`) is scoped by construction.
62
+ * Deliberately narrow: a false positive credits a scoped command without
63
+ * running it. Any positional argument or narrowing flag means scoped.
108
64
  *
109
65
  * @param {string} command
110
66
  * @returns {boolean}
@@ -115,13 +71,9 @@ export function isFullSuiteCommand(command) {
115
71
  .split(/\s+/)
116
72
  .filter(Boolean);
117
73
  if (tokens.length === 0) return false;
118
- // A narrowing flag scopes the run wherever it appears — before the package
119
- // manager's `--` as much as after it — so the probe runs over the whole
120
- // token list rather than per-branch below.
121
74
  if (hasNarrowingFlag(tokens)) return false;
122
75
 
123
76
  if (tokens[0] === 'node') {
124
- // `node --test` with no path argument walks the default test globs.
125
77
  const rest = tokens.slice(1);
126
78
  return rest.length > 0 && rest.every((t) => t.startsWith('-'));
127
79
  }
@@ -129,14 +81,10 @@ export function isFullSuiteCommand(command) {
129
81
  if (!PACKAGE_MANAGERS.has(tokens[0])) return false;
130
82
  const rest = tokens[1] === 'run' ? tokens.slice(2) : tokens.slice(1);
131
83
  if (rest.length === 0 || !FULL_SUITE_SCRIPTS.has(rest[0])) return false;
132
- // `npm test -- <path>` narrows the run; only a bare invocation is the suite.
133
84
  return rest.length === 1;
134
85
  }
135
86
 
136
87
  /**
137
- * Read HEAD from a worktree. `null` when the tree cannot be read — which
138
- * routes to `spawn`, never to a credit.
139
- *
140
88
  * @param {string} cwd
141
89
  * @param {Function} gitSpawnFn
142
90
  * @returns {string|null}
@@ -149,15 +97,12 @@ function readHeadSha(cwd, gitSpawnFn) {
149
97
  }
150
98
 
151
99
  /**
152
- * Decide how a single `verify[]` entry should be executed.
153
- *
154
100
  * @param {object} input
155
- * @param {string} input.command — the entry's command (tier tag already off).
101
+ * @param {string} input.command — tier tag already off.
156
102
  * @param {number|string} input.storyId
157
- * @param {string} input.worktree — ABSOLUTE path to the Story worktree.
158
- * @param {string} [input.cwd] — main checkout (evidence keyspace root).
159
- * Defaults to `worktree`.
160
- * @param {object} [deps] — test seams; every one defaults to the real impl.
103
+ * @param {string} input.worktree — ABSOLUTE path.
104
+ * @param {string} [input.cwd] — evidence keyspace root; defaults to `worktree`.
105
+ * @param {object} [deps] — test seams.
161
106
  * @returns {{
162
107
  * command: string, fullSuite: boolean, credited: boolean, spawn: boolean,
163
108
  * mode: 'capture'|'evidence'|null, reason: string, warning: string|null
@@ -215,10 +160,8 @@ export function resolveVerifyCredit(
215
160
  stampReason = freshness?.reason ?? 'unknown';
216
161
  }
217
162
 
218
- // Story #5313 — a green bare `npm test` deposits the `test` evidence record
219
- // close reads, so a stale (or absent) capture stamp is not the last word:
220
- // the evidence keyspace is consulted in both modes before spawning. When it
221
- // credits nothing either, capture mode reports the stamp's own reason.
163
+ // A stale stamp is not the last word: a green `npm test` deposits `test`
164
+ // evidence, consulted in both modes before spawning.
222
165
  const verdict = readTestEvidence({
223
166
  storyId,
224
167
  worktree,
@@ -239,9 +182,7 @@ export function resolveVerifyCredit(
239
182
  }
240
183
 
241
184
  /**
242
- * Consult the `test` evidence record for the worktree's HEAD — the record a
243
- * green bare `npm test` deposits (Story #5313) and `evidence-gate.js` wrote
244
- * before it. Total: an unreadable HEAD is `no-head`, never a credit.
185
+ * An unreadable HEAD is `no-head`, never a credit.
245
186
  *
246
187
  * @param {{ storyId: number|string, worktree: string, cwd: string, gitSpawnFn: Function, shouldSkipImpl: Function, hashCommandConfigImpl: Function, treeFingerprintImpl: Function }} args
247
188
  * @returns {{ skip: boolean, reason: string }}
@@ -274,9 +215,7 @@ function readTestEvidence({
274
215
  }
275
216
 
276
217
  /**
277
- * Classify a whole `verify[]` array in one pass.
278
- *
279
- * @param {string[]} entries — raw `verify[]` lines, tier tags included.
218
+ * @param {string[]} entries — raw lines, tier tags included.
280
219
  * @param {{ storyId: number|string, worktree: string, cwd?: string }} context
281
220
  * @param {object} [deps]
282
221
  * @returns {Array<ReturnType<typeof resolveVerifyCredit> & { tier: string|null }>}
@@ -1,13 +1,5 @@
1
1
  /**
2
- * lib/orchestration/worktree-dirty.js — "does this branch's checkout carry
3
- * uncommitted changes?" (Story #5238).
4
- *
5
- * Its own module because the light path's diff backstop is otherwise a pure
6
- * join over two committed-state git reads, and this is the one question there
7
- * that needs a third read of a *working tree*. Keeping it here leaves
8
- * {@link module:lib/orchestration/light-backstop} the thin join it claims to
9
- * be, and gives the probe its own place to be tested against every way a git
10
- * read can fail.
2
+ * Does a branch's checkout carry uncommitted changes?
11
3
  *
12
4
  * @module lib/orchestration/worktree-dirty
13
5
  */
@@ -16,8 +8,6 @@ import { gitSpawn } from '../git-utils.js';
16
8
  import { parseWorktreePorcelain } from '../worktree/inspector.js';
17
9
 
18
10
  /**
19
- * The stdout of a successful git read, or `null` when it cannot be trusted.
20
- *
21
11
  * @param {{ status?: number, stdout?: unknown }|null|undefined} result
22
12
  * @returns {string|null}
23
13
  */
@@ -27,12 +17,7 @@ function readableStdout(result) {
27
17
  }
28
18
 
29
19
  /**
30
- * Locate the checkout that has `branch` checked out, or `null` when no
31
- * checkout does.
32
- *
33
- * `git worktree list --porcelain` enumerates **every** checkout including the
34
- * main one, so a repository working on the branch directly (no separate
35
- * worktree) is found by this same lookup rather than by a second fallback path.
20
+ * `worktree list` includes the main checkout, so no second fallback is needed.
36
21
  *
37
22
  * @param {{ branch: string, cwd: string, gitFn: typeof gitSpawn }} args
38
23
  * @returns {string|null}
@@ -47,19 +32,9 @@ function resolveBranchCheckout({ branch, cwd, gitFn }) {
47
32
  }
48
33
 
49
34
  /**
50
- * Does the checkout holding `branch` have uncommitted changes?
51
- *
52
- * **Why the light path asks.** Its diff backstop measures `base...head`, which
53
- * is committed state, so a run that implemented and did not commit measures an
54
- * empty change set — and the refusal then told the agent its scope was
55
- * unverifiable and to escalate, when the actual fix was `git commit`. Measured
56
- * in the consumer: the refusal signal is stamped 12:14:06Z and the branch's
57
- * only commit 12:15:19Z (issue #5237).
58
- *
59
- * Total, and deliberately asymmetric: every unreadable surface — a failed
60
- * `worktree list`, a branch no checkout holds, a failed `status`, a throwing
61
- * git — answers `false`. A probe that cannot see the tree must not be able to
62
- * talk a refusal into friendlier guidance than the evidence supports.
35
+ * The light backstop diffs committed state, so uncommitted work reads as an
36
+ * empty change set; this lets the refusal say "commit" instead. Every
37
+ * unreadable surface answers `false` — a blind probe must not soften a refusal.
63
38
  *
64
39
  * @param {{ branch: string, cwd?: string, gitFn?: typeof gitSpawn }} args
65
40
  * @returns {boolean}
@@ -1,15 +1,12 @@
1
1
  import path from 'node:path';
2
2
 
3
3
  /**
4
- * Assert that `target` resolves inside `root`. Prevents "../" traversal and
5
- * absolute-path escapes in configuration-supplied paths.
4
+ * Reject `..` traversal and absolute escapes in config-supplied paths.
6
5
  *
7
6
  * @param {string} root absolute path of the containing directory
8
7
  * @param {string} target absolute path to validate
9
- * @param {string} label human-readable identifier for the error message
10
- * @param {{ allowEmpty?: boolean }} [opts]
11
- * - `allowEmpty`: when false, `path.relative(root, target) === ''` is also
12
- * rejected (target equals root). Default: true.
8
+ * @param {string} label identifier for the error message
9
+ * @param {{ allowEmpty?: boolean }} [opts] false also rejects target === root.
13
10
  * @returns {string} the path relative to `root`
14
11
  * @throws {Error} when target escapes root
15
12
  */
@@ -1,28 +1,8 @@
1
1
  /**
2
- * plan-phase-cleanup.js — Post-phase temp-file cleanup for `/mandrel-plan`.
3
- *
4
- * The spec and decompose phases write several run-scoped temp files under
5
- * the per-run tree (`temp/run-<id>/planner-context.json`,
6
- * `temp/run-<id>/techspec.md`, etc. — see `lib/config/temp-paths.js`). The
7
- * workflow .md previously told the operator to `Remove-Item` those files by
8
- * name at the end of each phase, which rots: adding a new temp file in the
9
- * script required a synchronized markdown edit, and missed edits left
10
- * orphaned files accumulating in `temp/`.
11
- *
12
- * The wrapper scripts now call `cleanupPhaseTempFiles()` directly. The set
13
- * of artifact basenames a phase creates is the contract of this module —
14
- * when a new temp file is introduced, extend `PHASE_TEMP_BASENAMES` here
15
- * and both the spec and decompose wrappers delete it automatically.
16
- *
17
- * Cleanup is best-effort: missing files are fine (`ENOENT` is ignored),
18
- * unexpected errors are swallowed with a console warning so a failed rm
19
- * never sinks a successful phase.
20
- *
21
- * Migration note (Epic #1030 Story #1040): the legacy flat layout
22
- * (`temp/planner-context-for-<id>.json` etc.) has been retired. The
23
- * resolver now delegates to `runArtifactPath` from
24
- * `lib/config/temp-paths.js`, which yields `temp/run-<id>/<basename>`
25
- * under the configured `tempRoot`.
2
+ * plan-phase-cleanup.js — delete a `/mandrel-plan` phase's run-scoped temp
3
+ * files. `PHASE_TEMP_BASENAMES` is the contract: extend it when a phase adds
4
+ * a temp file. Best-effort — ENOENT is ignored and other errors only warn,
5
+ * so a failed rm never sinks a successful phase.
26
6
  */
27
7
 
28
8
  import fs from 'node:fs/promises';
@@ -30,10 +10,7 @@ import path from 'node:path';
30
10
  import { runArtifactPath } from './config/temp-paths.js';
31
11
  import { PROJECT_ROOT, resolveConfig } from './config-resolver.js';
32
12
 
33
- /**
34
- * Map of phase → artifact basenames (no path components). The per-run
35
- * directory prefix is supplied by `runArtifactPath` at resolution time.
36
- */
13
+ /** Phase → artifact basenames; `runArtifactPath` supplies the run dir. */
37
14
  export const PHASE_TEMP_BASENAMES = Object.freeze({
38
15
  spec: Object.freeze([
39
16
  'planner-context.json',
@@ -41,13 +18,9 @@ export const PHASE_TEMP_BASENAMES = Object.freeze({
41
18
  'acceptance-spec.md',
42
19
  ]),
43
20
  decompose: Object.freeze(['decomposer-context.json', 'tickets.json']),
44
- // Epic #4474 (PR3) — the collapsed `plan-persist.js` surface owns every
45
- // plan-phase artifact and deletes them ONLY at terminal success (after
46
- // the `agent::ready` flip), fixing the mid-pipeline deletion defect where
47
- // per-phase cleanup removed artifacts a `--force`/`--resume` re-persist
48
- // was still entitled to reuse.
49
- // `plan-metrics.json` stays deliberately excluded (PR1) — the ledger
50
- // must survive cleanup so the whole plan run is visible in one stream.
21
+ // Deleted only at terminal persist success, so a `--force`/`--resume`
22
+ // re-persist can still reuse them. `plan-metrics.json` is deliberately
23
+ // excluded: the ledger must survive to show the whole run.
51
24
  persist: Object.freeze([
52
25
  'planner-context.json',
53
26
  'techspec.md',
@@ -58,8 +31,6 @@ export const PHASE_TEMP_BASENAMES = Object.freeze({
58
31
  });
59
32
 
60
33
  /**
61
- * Resolve the concrete paths a phase owns for a given Epic.
62
- *
63
34
  * @param {'spec'|'decompose'} phase
64
35
  * @param {number} epicId
65
36
  * @param {string} [repoRoot]
@@ -72,9 +43,7 @@ export function resolvePhaseTempPaths(phase, epicId, repoRoot = PROJECT_ROOT) {
72
43
  `[plan-phase-cleanup] Unknown phase "${phase}". Expected one of: ${Object.keys(PHASE_TEMP_BASENAMES).join(', ')}.`,
73
44
  );
74
45
  }
75
- // Thread the resolved config so we honour `project.paths.tempRoot`
76
- // overrides; fall back to the helper's default when the resolver itself
77
- // throws (zero-config callers — unit tests).
46
+ // Honour `tempRoot` overrides; zero-config callers fall back to defaults.
78
47
  let config;
79
48
  try {
80
49
  config = resolveConfig({ cwd: repoRoot });
@@ -83,20 +52,11 @@ export function resolvePhaseTempPaths(phase, epicId, repoRoot = PROJECT_ROOT) {
83
52
  }
84
53
  return basenames.map((basename) => {
85
54
  const rel = runArtifactPath(epicId, basename, config);
86
- // `runArtifactPath` yields a path under `tempRoot` (relative when
87
- // tempRoot is itself relative — the framework default). Rebase
88
- // relative paths against `repoRoot` so callers always receive an
89
- // absolute path — matches the pre-migration contract that
90
- // downstream `fs.unlink` relies on. Already-absolute results pass
91
- // through untouched.
92
55
  return path.isAbsolute(rel) ? rel : path.join(repoRoot, rel);
93
56
  });
94
57
  }
95
58
 
96
59
  /**
97
- * Delete the temp files a phase owns for the given Epic. Idempotent:
98
- * missing files are ignored; other errors are logged but do not throw.
99
- *
100
60
  * @param {{
101
61
  * phase: 'spec'|'decompose',
102
62
  * epicId: number,
@@ -1,23 +1,7 @@
1
1
  /**
2
- * preflight-runner.js — Shared preflight wrapper around the checks registry.
3
- *
4
- * This module is the single implementation of the "run the registry, fail
5
- * fast on blockers, log auto-fixes" pattern. The consumer entry points
6
- * (`single-story-close.js`, `mandrel-update-preflight.js`, the npm test wrapper, and
7
- * the bootstrap scripts) call `runPreflight({ scope })` instead of
8
- * re-implementing the same assemble+run+format+exit-2 dance.
9
- *
10
- * Exit-code contract (shared by every consumer):
11
- * - 0 → no blocker findings (warnings/info may have been printed).
12
- * - 2 → at least one `severity: 'blocker'` finding survived after
13
- * auto-fixes. The wrapper prints a human-readable blocker table
14
- * (`id · summary · fixCommand`) before returning. Code 2 is the
15
- * project-wide "preflight refused" reservation — see
16
- * `.agents/workflows/helpers/deliver-story.md` for the rationale.
17
- *
18
- * Auto-fixes are logged via `logFixes` before the blocker check so the
19
- * operator sees the "we corrected X" line even when a separate blocker
20
- * later trips the exit. Auto-fixes never themselves block.
2
+ * preflight-runner.js — run the checks registry, log auto-fixes (which never
3
+ * block) before the blocker table, and report `blocked` so the consumer
4
+ * exits {@link PREFLIGHT_REFUSED_EXIT_CODE}.
21
5
  */
22
6
 
23
7
  import { runChecks } from './checks/index.js';
@@ -29,15 +13,9 @@ import { Logger } from './Logger.js';
29
13
  * @property {Array<object>} findings Unfixed findings (any severity).
30
14
  * @property {Array<object>} fixed Findings that were auto-corrected.
31
15
  * @property {boolean} blocked True iff `findings` contains a
32
- * `severity: 'blocker'`. When `true`, the consumer must exit with code 2.
16
+ * `severity: 'blocker'`; the consumer must then exit 2.
33
17
  */
34
18
 
35
- /**
36
- * Default logger adapter — routes info/warn/error through the project
37
- * Logger. Kept as a module-local constant so the runner has a single seam
38
- * tests can swap with a spy that captures lines without going through
39
- * Logger's stdout/stderr.
40
- */
41
19
  const DEFAULT_LOGGER = {
42
20
  info: (msg) => Logger.info(msg),
43
21
  warn: (msg) => Logger.warn(msg),
@@ -45,26 +23,14 @@ const DEFAULT_LOGGER = {
45
23
  };
46
24
 
47
25
  /**
48
- * Run preflight checks for `scope` against an assembled state probe.
49
- *
50
- * The consumer surface is intentionally tiny: pass a `scope` string and
51
- * (optionally) a `cwd`. The runner handles state assembly, the autoFix
52
- * flag, finding/fix routing, and pretty-print of the blocker table.
53
- *
54
26
  * @param {object} opts
55
- * @param {string} opts.scope Consumer surface — `'story-close'`,
56
- * `'npm-test'`, `'diagnose'`, etc.
57
- * @param {boolean} [opts.autoFix=true] Forwarded to `runChecks`. Defaults
58
- * to `true` because every wiring call site at this Story's level wants
59
- * auto-correction (the `retro` consumer that needs `autoFix:false` does
60
- * NOT use this helper — it calls `runChecks` directly).
27
+ * @param {string} opts.scope e.g. `'story-close'`, `'npm-test'`.
28
+ * @param {boolean} [opts.autoFix=true]
61
29
  * @param {string} [opts.cwd=process.cwd()]
62
- * @param {object} [opts.probes] Test-only probe injection forwarded
63
- * to `assembleState`. Production callers omit this.
64
- * @param {object} [opts.registry] Test-only — bypass `loadRegistry()`.
65
- * @param {string} [opts.dir] Test-only fixture directory.
30
+ * @param {object} [opts.probes] Test-only.
31
+ * @param {object} [opts.registry] Test-only.
32
+ * @param {string} [opts.dir] Test-only.
66
33
  * @param {{ info?: Function, warn?: Function, error?: Function }} [opts.logger]
67
- * Defaults to the project Logger. Tests pass a spy that captures lines.
68
34
  * @returns {Promise<PreflightResult>}
69
35
  */
70
36
  export async function runPreflight({
@@ -79,9 +45,7 @@ export async function runPreflight({
79
45
  if (!scope || typeof scope !== 'string') {
80
46
  throw new Error('runPreflight: scope is required');
81
47
  }
82
- // `retro` is reserved by the runner and is never a preflight scope.
83
- // Catch it here so the failure mode is obvious instead of routing into
84
- // the runner's autoFix throw.
48
+ // `retro` is read-only; fail here rather than in runChecks' autoFix throw.
85
49
  if (scope === 'retro') {
86
50
  throw new Error(
87
51
  'runPreflight: retro scope is read-only — call runChecks directly',
@@ -99,18 +63,12 @@ export async function runPreflight({
99
63
  const blockers = findings.filter((f) => f.severity === 'blocker');
100
64
  const blocked = blockers.length > 0;
101
65
  if (blocked) logBlockers(scope, blockers, logger);
102
- // Surface non-blocker findings as well so operators see warnings/info.
103
66
  const nonBlockerFindings = findings.filter((f) => f.severity !== 'blocker');
104
67
  if (nonBlockerFindings.length > 0) logNonBlockers(nonBlockerFindings, logger);
105
68
  return { findings, fixed, blocked };
106
69
  }
107
70
 
108
- /**
109
- * Pick the logger method for `level` — falls back through the project
110
- * Logger if the supplied logger is missing the level. Keeps the
111
- * console-allowlist test happy (no direct console.* fallback here) and
112
- * still lets tests swap the entire logger out.
113
- */
71
+ /** Falls back to the project Logger — never to `console.*` directly. */
114
72
  function pick(logger, level) {
115
73
  if (logger && typeof logger[level] === 'function') {
116
74
  return (msg) => logger[level](msg);
@@ -119,8 +77,6 @@ function pick(logger, level) {
119
77
  }
120
78
 
121
79
  /**
122
- * Print the auto-fixed findings as a one-line-per-fix summary.
123
- *
124
80
  * @param {Array<object>} fixed
125
81
  * @param {object} [logger]
126
82
  */
@@ -134,9 +90,6 @@ function logFixes(fixed, logger = DEFAULT_LOGGER) {
134
90
  }
135
91
 
136
92
  /**
137
- * Print the blocker table the operator sees on `exit 2`. Each row carries
138
- * `id · summary · fixCommand`; details (if present) wrap underneath.
139
- *
140
93
  * @param {string} scope
141
94
  * @param {Array<object>} blockers
142
95
  * @param {object} [logger]
@@ -152,10 +105,7 @@ function logBlockers(scope, blockers, logger = DEFAULT_LOGGER) {
152
105
  ' -------------------------- -------- ----------------------------------------',
153
106
  );
154
107
  for (const b of blockers) {
155
- // Pad short IDs to align the column; never TRUNCATE — the operator
156
- // needs the full id to find the check module on disk and to grep the
157
- // codebase for the failure mode. Long ids just push the severity
158
- // column right, which is fine for terminal output.
108
+ // Pad, never truncate — the operator needs the full id to find the check.
159
109
  const id = String(b.id).padEnd(26);
160
110
  const sev = String(b.severity).padEnd(8);
161
111
  error(` ${id} ${sev} ${b.summary ?? ''}`);
@@ -175,8 +125,6 @@ function logBlockers(scope, blockers, logger = DEFAULT_LOGGER) {
175
125
  }
176
126
 
177
127
  /**
178
- * Print warning/info findings as one line each. These never block.
179
- *
180
128
  * @param {Array<object>} findings
181
129
  * @param {object} [logger]
182
130
  */
@@ -188,9 +136,5 @@ function logNonBlockers(findings, logger = DEFAULT_LOGGER) {
188
136
  }
189
137
  }
190
138
 
191
- /**
192
- * The reserved exit code for "preflight refused". Re-exported so consumer
193
- * scripts can `process.exit(PREFLIGHT_REFUSED_EXIT_CODE)` instead of
194
- * hard-coding the magic number.
195
- */
139
+ /** Project-wide "preflight refused" exit code. */
196
140
  export const PREFLIGHT_REFUSED_EXIT_CODE = 2;
@@ -0,0 +1,143 @@
1
+ /**
2
+ * process-group.js — kill spawned children as whole process groups:
3
+ * `child.kill()` on `npm` misses the `node --test` workers it forks.
4
+ * Parent SIGINT/SIGTERM is forwarded by a prepended handler, so the suite
5
+ * dies before the lock's release handler runs (a `setsid` leader never gets
6
+ * the terminal's Ctrl-C). win32 has no groups and degrades to the child.
7
+ * The kill path never throws.
8
+ */
9
+
10
+ export const TIMEOUT_EXIT_CODE = 124;
11
+
12
+ const FORWARDED_SIGNALS = Object.freeze(['SIGINT', 'SIGTERM']);
13
+
14
+ /**
15
+ * `detached` on win32 opens a new console instead.
16
+ *
17
+ * @param {string} [platform]
18
+ * @returns {{ detached?: boolean }}
19
+ */
20
+ export function groupSpawnOptions(platform = process.platform) {
21
+ return platform === 'win32' ? {} : { detached: true };
22
+ }
23
+
24
+ /**
25
+ * @param {{ pid?: number, kill?: (signal?: string) => void }} child
26
+ * @param {string} [signal]
27
+ * @param {{ platform?: string, killFn?: (pid: number, signal: string) => void }} [opts]
28
+ * @returns {boolean}
29
+ */
30
+ function killProcessGroup(
31
+ child,
32
+ signal = 'SIGKILL',
33
+ { platform = process.platform, killFn = process.kill.bind(process) } = {},
34
+ ) {
35
+ const pid = child?.pid;
36
+ if (platform !== 'win32' && Number.isInteger(pid) && pid > 0) {
37
+ try {
38
+ killFn(-pid, signal);
39
+ return true;
40
+ } catch {
41
+ // The group is gone (or was never ours) — try the child itself.
42
+ }
43
+ }
44
+ try {
45
+ child?.kill?.(signal);
46
+ return true;
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ /** child → the signal its group receives when this process is signalled. */
53
+ const supervised = new Map();
54
+ let detachForwarding = null;
55
+
56
+ /**
57
+ * A remaining listener (the lock's release handler) re-raises; with none,
58
+ * re-raise here so the process still dies as asked.
59
+ *
60
+ * @param {NodeJS.Process} processImpl
61
+ * @param {string} signal
62
+ */
63
+ function forwardSignal(processImpl, signal) {
64
+ for (const [child, childSignal] of supervised) {
65
+ killProcessGroup(child, childSignal);
66
+ }
67
+ supervised.clear();
68
+ stopForwarding();
69
+ if (processImpl.listenerCount(signal) > 0) return;
70
+ try {
71
+ processImpl.kill(processImpl.pid, signal);
72
+ } catch {
73
+ // A process that cannot signal itself is already on its way out.
74
+ }
75
+ }
76
+
77
+ function startForwarding(processImpl) {
78
+ if (detachForwarding) return;
79
+ const handlers = FORWARDED_SIGNALS.map((signal) => {
80
+ const handler = () => forwardSignal(processImpl, signal);
81
+ processImpl.prependListener(signal, handler);
82
+ return [signal, handler];
83
+ });
84
+ detachForwarding = () => {
85
+ for (const [signal, handler] of handlers) processImpl.off(signal, handler);
86
+ };
87
+ }
88
+
89
+ function stopForwarding() {
90
+ const detach = detachForwarding;
91
+ detachForwarding = null;
92
+ detach?.();
93
+ }
94
+
95
+ /**
96
+ * Kill the group on timeout, abort or parent signal; `release()` on exit.
97
+ *
98
+ * @param {{ pid?: number, kill?: (signal?: string) => void }} child
99
+ * @param {{
100
+ * timeoutMs?: number,
101
+ * abortSignal?: AbortSignal,
102
+ * signalOnParentSignal?: string,
103
+ * processImpl?: NodeJS.Process,
104
+ * killOptions?: { platform?: string, killFn?: Function },
105
+ * }} [opts] `signalOnParentSignal`: SIGKILL for a bare suite, SIGTERM for a
106
+ * child with its own cleanup (a capture holding the lock).
107
+ * @returns {{ readonly timedOut: boolean, release: () => void }}
108
+ */
109
+ export function superviseGroup(
110
+ child,
111
+ {
112
+ timeoutMs,
113
+ abortSignal,
114
+ signalOnParentSignal = 'SIGKILL',
115
+ processImpl = process,
116
+ killOptions,
117
+ } = {},
118
+ ) {
119
+ let timedOut = false;
120
+ supervised.set(child, signalOnParentSignal);
121
+ startForwarding(processImpl);
122
+ const timer =
123
+ Number.isFinite(timeoutMs) && timeoutMs > 0
124
+ ? setTimeout(() => {
125
+ timedOut = true;
126
+ killProcessGroup(child, 'SIGKILL', killOptions);
127
+ }, timeoutMs)
128
+ : null;
129
+ const onAbort = () => killProcessGroup(child, 'SIGTERM', killOptions);
130
+ abortSignal?.addEventListener('abort', onAbort, { once: true });
131
+ if (abortSignal?.aborted) onAbort();
132
+ return {
133
+ get timedOut() {
134
+ return timedOut;
135
+ },
136
+ release() {
137
+ if (timer) clearTimeout(timer);
138
+ abortSignal?.removeEventListener('abort', onAbort);
139
+ supervised.delete(child);
140
+ if (supervised.size === 0) stopForwarding();
141
+ },
142
+ };
143
+ }