mandrel 2.60.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 (661) hide show
  1. package/.agents/README.md +10 -10
  2. package/.agents/agents/story-worker.md +1 -1
  3. package/.agents/docs/agentrc-reference.json +4 -82
  4. package/.agents/docs/configuration.md +20 -87
  5. package/.agents/docs/workflows.md +1 -1
  6. package/.agents/instructions.md +1 -3
  7. package/.agents/rules/gherkin-standards.md +4 -0
  8. package/.agents/schemas/agentrc.schema.json +11 -486
  9. package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
  10. package/.agents/schemas/validation-evidence.schema.json +2 -1
  11. package/.agents/scripts/README.md +14 -14
  12. package/.agents/scripts/acceptance-eval.js +32 -164
  13. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  14. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  15. package/.agents/scripts/audit-baselines.js +6 -27
  16. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  17. package/.agents/scripts/audit-to-stories.js +91 -361
  18. package/.agents/scripts/boot-sweep.js +19 -72
  19. package/.agents/scripts/bootstrap.js +74 -395
  20. package/.agents/scripts/ceremony-derive.js +9 -45
  21. package/.agents/scripts/check-arch-cycles.js +14 -64
  22. package/.agents/scripts/check-baselines.js +8 -48
  23. package/.agents/scripts/check-context-budget.js +46 -172
  24. package/.agents/scripts/check-cyclomatic.js +12 -44
  25. package/.agents/scripts/check-dead-exports.js +13 -64
  26. package/.agents/scripts/check-doc-links.js +38 -186
  27. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  28. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  29. package/.agents/scripts/coverage-capture.js +32 -99
  30. package/.agents/scripts/deliver-light.js +14 -101
  31. package/.agents/scripts/deliver-recover.js +6 -42
  32. package/.agents/scripts/deliver-run.js +36 -133
  33. package/.agents/scripts/diagnose-friction.js +24 -116
  34. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  35. package/.agents/scripts/evidence-gate.js +23 -85
  36. package/.agents/scripts/file-ci-gap.js +10 -50
  37. package/.agents/scripts/generate-config-docs.js +30 -170
  38. package/.agents/scripts/generate-lens-checklists.js +8 -52
  39. package/.agents/scripts/generate-skills-index.js +14 -112
  40. package/.agents/scripts/generate-workflows-doc.js +10 -70
  41. package/.agents/scripts/git-cleanup.js +2 -34
  42. package/.agents/scripts/lib/Graph.js +24 -81
  43. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  44. package/.agents/scripts/lib/Logger.js +14 -76
  45. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  46. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  47. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  48. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  49. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  50. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  51. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  52. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  53. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  54. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  55. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  56. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  57. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  58. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  59. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  60. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  61. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  62. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  63. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  64. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  65. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  66. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  67. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  68. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  69. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  70. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  71. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  72. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  73. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  74. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  75. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  76. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  77. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  78. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  79. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  80. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  81. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  82. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  83. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  84. package/.agents/scripts/lib/baseline-loader.js +12 -51
  85. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  86. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  87. package/.agents/scripts/lib/baselines/components.js +10 -61
  88. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  89. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
  90. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  91. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  92. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  93. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  94. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  95. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  96. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  97. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  98. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  99. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  100. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  101. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  102. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  103. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  104. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  105. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  106. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  107. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  108. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  109. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  110. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  111. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  112. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  113. package/.agents/scripts/lib/baselines/reader.js +14 -107
  114. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  115. package/.agents/scripts/lib/baselines/scope.js +11 -135
  116. package/.agents/scripts/lib/baselines/writer.js +16 -149
  117. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  118. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  119. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  120. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  121. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  122. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  123. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  124. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  125. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  126. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  127. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  128. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  129. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  130. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  131. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  132. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  133. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  134. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  135. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  136. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  137. package/.agents/scripts/lib/changed-files.js +31 -143
  138. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  139. package/.agents/scripts/lib/checks/index.js +18 -101
  140. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  141. package/.agents/scripts/lib/checks/state.js +16 -91
  142. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  143. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  144. package/.agents/scripts/lib/child-exec.js +39 -108
  145. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  146. package/.agents/scripts/lib/cli-args.js +31 -146
  147. package/.agents/scripts/lib/cli-usage.js +5 -27
  148. package/.agents/scripts/lib/cli-utils.js +2 -12
  149. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  150. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  151. package/.agents/scripts/lib/close-validation/process.js +121 -151
  152. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  153. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  154. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  155. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  156. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  157. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  158. package/.agents/scripts/lib/command-header.js +6 -28
  159. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  160. package/.agents/scripts/lib/config/baselines.js +3 -14
  161. package/.agents/scripts/lib/config/ci.js +8 -38
  162. package/.agents/scripts/lib/config/commands.js +1 -15
  163. package/.agents/scripts/lib/config/defaults.js +4 -33
  164. package/.agents/scripts/lib/config/delivery-routing.js +6 -35
  165. package/.agents/scripts/lib/config/explain.js +9 -80
  166. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  167. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
  168. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  169. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  170. package/.agents/scripts/lib/config/gates/index.js +2 -17
  171. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  172. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  173. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  174. package/.agents/scripts/lib/config/github.js +4 -22
  175. package/.agents/scripts/lib/config/limits.js +4 -57
  176. package/.agents/scripts/lib/config/paths.js +2 -21
  177. package/.agents/scripts/lib/config/qa.js +4 -38
  178. package/.agents/scripts/lib/config/quality.js +76 -432
  179. package/.agents/scripts/lib/config/runners.js +12 -56
  180. package/.agents/scripts/lib/config/runtime.js +13 -57
  181. package/.agents/scripts/lib/config/shared.js +2 -16
  182. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  183. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  184. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  185. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  186. package/.agents/scripts/lib/config-resolver.js +10 -52
  187. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  188. package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
  189. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  190. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  191. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  192. package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
  193. package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
  194. package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
  195. package/.agents/scripts/lib/coverage-capture.js +99 -224
  196. package/.agents/scripts/lib/coverage-utils.js +14 -79
  197. package/.agents/scripts/lib/cpu-pool.js +17 -123
  198. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  199. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  200. package/.agents/scripts/lib/crap-engine.js +40 -153
  201. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  202. package/.agents/scripts/lib/crap-utils.js +31 -155
  203. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  204. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  205. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  206. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  207. package/.agents/scripts/lib/degraded-mode.js +3 -26
  208. package/.agents/scripts/lib/dependency-parser.js +8 -40
  209. package/.agents/scripts/lib/dependency-version.js +13 -35
  210. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  211. package/.agents/scripts/lib/doc-tiers.js +22 -126
  212. package/.agents/scripts/lib/duplicate-search.js +8 -72
  213. package/.agents/scripts/lib/env-loader.js +5 -27
  214. package/.agents/scripts/lib/error-redactor.js +6 -31
  215. package/.agents/scripts/lib/errors/index.js +2 -22
  216. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  217. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  218. package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
  219. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  220. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
  221. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  222. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  223. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  224. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  225. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  226. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  227. package/.agents/scripts/lib/findings/severity.js +18 -104
  228. package/.agents/scripts/lib/format-generated-json.js +12 -44
  229. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  230. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  231. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  232. package/.agents/scripts/lib/gates/friction.js +1 -3
  233. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  234. package/.agents/scripts/lib/gh-exec.js +31 -259
  235. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  236. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  237. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  238. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  239. package/.agents/scripts/lib/git-utils.js +37 -161
  240. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  241. package/.agents/scripts/lib/github-url.js +2 -17
  242. package/.agents/scripts/lib/import-graph.js +11 -38
  243. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  244. package/.agents/scripts/lib/json-utils.js +3 -18
  245. package/.agents/scripts/lib/label-constants.js +16 -111
  246. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  247. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  248. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  249. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  250. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  251. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  252. package/.agents/scripts/lib/npm-scripts.js +4 -23
  253. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  254. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  255. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  256. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  257. package/.agents/scripts/lib/observability/source-classifier.js +21 -203
  258. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  259. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  260. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  261. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  262. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  263. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  264. package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
  265. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  266. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  267. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  268. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  274. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  275. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  276. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
  277. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  278. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  279. package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
  280. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  281. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  282. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  283. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  284. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  285. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  286. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  287. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  288. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  289. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  290. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  291. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  292. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  293. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  294. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  295. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  308. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  309. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  310. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  311. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  312. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  313. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  314. package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
  315. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  316. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  317. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  318. package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
  319. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  320. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  321. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  322. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  323. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  324. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  325. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
  326. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  327. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  328. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  329. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  330. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  331. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  332. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
  333. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  334. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
  335. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
  336. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
  337. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  338. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  339. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  340. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  341. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  342. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  343. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  344. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  345. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  346. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  347. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  348. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  349. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  350. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  351. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  352. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  353. package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
  354. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  355. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  356. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  357. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  358. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  359. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  360. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  361. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  362. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  363. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  364. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  365. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  366. package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
  367. package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
  368. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  369. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  370. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  371. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  372. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
  373. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  390. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
  391. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  392. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  393. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  394. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  395. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  396. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  397. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  398. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  399. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
  400. package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
  401. package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
  402. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  403. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  404. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
  405. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  406. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  407. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  408. package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
  409. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  410. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
  411. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  412. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  413. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  414. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  415. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  416. package/.agents/scripts/lib/path-security.js +3 -6
  417. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  418. package/.agents/scripts/lib/preflight-runner.js +13 -69
  419. package/.agents/scripts/lib/process-group.js +143 -0
  420. package/.agents/scripts/lib/project-root.js +2 -8
  421. package/.agents/scripts/lib/provider-factory.js +2 -25
  422. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  423. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  424. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  425. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  426. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  427. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  428. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  429. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  430. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  431. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  432. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  433. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  434. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  435. package/.agents/scripts/lib/signals/index.js +2 -19
  436. package/.agents/scripts/lib/signals/schema.js +14 -109
  437. package/.agents/scripts/lib/signals/write.js +2 -11
  438. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  439. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  440. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  441. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  442. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  443. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  444. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  445. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  446. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  447. package/.agents/scripts/lib/source-extensions.js +11 -42
  448. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  449. package/.agents/scripts/lib/stdio-flush.js +9 -36
  450. package/.agents/scripts/lib/story-adjacency.js +8 -40
  451. package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
  452. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  453. package/.agents/scripts/lib/story-body/story-body.js +83 -358
  454. package/.agents/scripts/lib/temp-retention.js +42 -143
  455. package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
  456. package/.agents/scripts/lib/test-env.js +12 -65
  457. package/.agents/scripts/lib/test-run-credit.js +10 -65
  458. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  459. package/.agents/scripts/lib/test-temp.js +38 -184
  460. package/.agents/scripts/lib/test-tiers.js +12 -96
  461. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  462. package/.agents/scripts/lib/transpile.js +15 -74
  463. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  464. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  465. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  466. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  467. package/.agents/scripts/lib/validation-evidence.js +21 -96
  468. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  469. package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
  470. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  471. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  472. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  473. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  474. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  475. package/.agents/scripts/lib/workflow-closure.js +22 -105
  476. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  477. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  478. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  479. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  480. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  481. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  482. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  483. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  484. package/.agents/scripts/lib/worktree-manager.js +15 -40
  485. package/.agents/scripts/lint-issue-body.js +12 -68
  486. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  487. package/.agents/scripts/merge-baseline.js +30 -104
  488. package/.agents/scripts/nav-registry-diff.js +22 -108
  489. package/.agents/scripts/notify.js +12 -69
  490. package/.agents/scripts/plan-context.js +27 -111
  491. package/.agents/scripts/plan-critics.js +12 -66
  492. package/.agents/scripts/plan-persist.js +31 -148
  493. package/.agents/scripts/plan-run-epilogue.js +11 -37
  494. package/.agents/scripts/pr-watch-with-update.js +76 -267
  495. package/.agents/scripts/providers/github/auth.js +3 -8
  496. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  497. package/.agents/scripts/providers/github/board-add.js +5 -21
  498. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  499. package/.agents/scripts/providers/github/cache.js +2 -14
  500. package/.agents/scripts/providers/github/comments.js +7 -40
  501. package/.agents/scripts/providers/github/compose.js +3 -19
  502. package/.agents/scripts/providers/github/errors.js +22 -125
  503. package/.agents/scripts/providers/github/issues.js +31 -123
  504. package/.agents/scripts/providers/github/labels.js +24 -124
  505. package/.agents/scripts/providers/github/mappers.js +5 -27
  506. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  507. package/.agents/scripts/providers/github/project-board.js +2 -17
  508. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  509. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  510. package/.agents/scripts/providers/github/search-budget.js +9 -39
  511. package/.agents/scripts/providers/github/search-query.js +5 -26
  512. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  513. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  514. package/.agents/scripts/providers/github/tickets.js +32 -134
  515. package/.agents/scripts/providers/github.js +18 -59
  516. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  517. package/.agents/scripts/quality-preview.js +35 -220
  518. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  519. package/.agents/scripts/resolve-stories.js +16 -67
  520. package/.agents/scripts/resync-status-column.js +6 -25
  521. package/.agents/scripts/run-tests.js +29 -104
  522. package/.agents/scripts/single-story-close.js +23 -135
  523. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  524. package/.agents/scripts/single-story-init.js +47 -209
  525. package/.agents/scripts/stories-wave-tick.js +102 -472
  526. package/.agents/scripts/sync-agentrc.js +3 -21
  527. package/.agents/scripts/sync-claude-agents.js +9 -55
  528. package/.agents/scripts/sync-claude-commands.js +20 -110
  529. package/.agents/scripts/test-wrapper.js +6 -43
  530. package/.agents/scripts/update-coverage-baseline.js +5 -22
  531. package/.agents/scripts/update-crap-baseline.js +7 -30
  532. package/.agents/scripts/update-duplication-baseline.js +16 -92
  533. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  534. package/.agents/scripts/update-ticket-state.js +1 -7
  535. package/.agents/scripts/validate-skills.js +6 -26
  536. package/.agents/templates/agent-protocol.md +2 -2
  537. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  538. package/.agents/workflows/audit-accessibility.md +4 -7
  539. package/.agents/workflows/audit-adrs.md +3 -6
  540. package/.agents/workflows/audit-architecture.md +3 -11
  541. package/.agents/workflows/audit-baselines.md +6 -9
  542. package/.agents/workflows/audit-clean-code.md +8 -12
  543. package/.agents/workflows/audit-data-model.md +3 -7
  544. package/.agents/workflows/audit-dependencies.md +4 -7
  545. package/.agents/workflows/audit-devops.md +4 -8
  546. package/.agents/workflows/audit-documentation.md +1 -4
  547. package/.agents/workflows/audit-mobile.md +4 -7
  548. package/.agents/workflows/audit-navigability.md +3 -6
  549. package/.agents/workflows/audit-performance.md +2 -4
  550. package/.agents/workflows/audit-privacy.md +4 -7
  551. package/.agents/workflows/audit-quality.md +4 -7
  552. package/.agents/workflows/audit-security.md +4 -7
  553. package/.agents/workflows/audit-seo.md +4 -7
  554. package/.agents/workflows/audit-sre.md +4 -7
  555. package/.agents/workflows/audit-to-stories.md +17 -30
  556. package/.agents/workflows/audit-ux-ui.md +4 -7
  557. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  558. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  559. package/.agents/workflows/helpers/deliver-digest.md +6 -4
  560. package/.agents/workflows/helpers/deliver-reference.md +114 -188
  561. package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
  562. package/.agents/workflows/helpers/plan-reference.md +86 -139
  563. package/.agents/workflows/helpers/qa-core.md +12 -0
  564. package/.agents/workflows/memory-consolidate.md +1 -1
  565. package/.agents/workflows/qa-assist.md +27 -71
  566. package/.agents/workflows/qa-explore.md +19 -59
  567. package/.agents/workflows/qa-run.md +11 -33
  568. package/README.md +1 -1
  569. package/bin/mandrel.js +5 -46
  570. package/bin/postinstall.js +18 -107
  571. package/docs/CHANGELOG.md +25 -0
  572. package/lib/cli/doctor.js +11 -71
  573. package/lib/cli/init.js +26 -165
  574. package/lib/cli/migrate.js +5 -64
  575. package/lib/cli/registry.js +84 -467
  576. package/lib/cli/sync-agents.js +4 -64
  577. package/lib/cli/sync-commands.js +11 -64
  578. package/lib/cli/sync.js +34 -213
  579. package/lib/cli/uninstall.js +40 -219
  580. package/lib/cli/update.js +105 -661
  581. package/lib/cli/version-check.js +8 -72
  582. package/lib/cli/version-helpers.js +14 -87
  583. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  584. package/lib/migrations/index.js +15 -92
  585. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  586. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  587. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  588. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  589. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  590. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  591. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  592. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  593. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
  594. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  595. package/package.json +16 -14
  596. package/.agents/docs/SDLC.md +0 -590
  597. package/.agents/docs/quality-gates.md +0 -1183
  598. package/.agents/rules/known-tooling-behavior.md +0 -200
  599. package/.agents/rules/orchestration-error-handling.md +0 -61
  600. package/.agents/rules/test-seams.md +0 -59
  601. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  602. package/.agents/schemas/baselines/lint.schema.json +0 -47
  603. package/.agents/scripts/check-action-pinning.js +0 -260
  604. package/.agents/scripts/check-audit-attribution.js +0 -302
  605. package/.agents/scripts/check-baseline-drift.js +0 -211
  606. package/.agents/scripts/check-baseline-scope.js +0 -362
  607. package/.agents/scripts/check-generated-validator.js +0 -202
  608. package/.agents/scripts/check-knip-entries.js +0 -159
  609. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  610. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  611. package/.agents/scripts/check-schema-references.js +0 -368
  612. package/.agents/scripts/check-test-portability.js +0 -512
  613. package/.agents/scripts/check-workflow-citations.js +0 -218
  614. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  615. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  616. package/.agents/scripts/install-matrix-assert.js +0 -326
  617. package/.agents/scripts/lib/audit-advisories.js +0 -195
  618. package/.agents/scripts/lib/audit-attribution.js +0 -134
  619. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  620. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  621. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  622. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  623. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  624. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  625. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  626. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  627. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  628. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  629. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  630. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  631. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  632. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  633. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  634. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  635. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  636. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  637. package/.agents/scripts/lib/fs-walk.js +0 -52
  638. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  639. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  640. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  641. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  642. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  643. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  644. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  645. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  646. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  647. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  648. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  649. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  650. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  651. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  652. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  653. package/.agents/scripts/post-structured-comment.js +0 -127
  654. package/.agents/scripts/provision-git-hooks.js +0 -85
  655. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  656. package/.agents/scripts/run-coverage.js +0 -197
  657. package/.agents/scripts/run-lint.js +0 -133
  658. package/.agents/scripts/run-test-profile.js +0 -129
  659. package/.agents/scripts/run-verify.js +0 -125
  660. package/.agents/scripts/test-isolate.js +0 -55
  661. 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
+ }