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,70 +1,11 @@
1
- // .agents/scripts/lib/baselines/scope.js
2
- //
3
- // Story #1962 / Task #1970 — the ScopeResolution helper behind the
4
- // `check-baselines.js` dispatcher: `resolveDispatchScope` in
5
- // `lib/orchestration/check-baselines/phases/compare.js` is its one
6
- // caller. Routing the read side's scope decision through a single pure
7
- // function keeps the precedence rules from being re-implemented per gate.
8
- //
9
- // It is NOT the writers' resolver. `lib/baselines/refresh-service.js`
10
- // defines its own private `resolveScope` (Story #3658) over a different
11
- // input set, and the header here used to claim otherwise — a claim that
12
- // made the read/write pair look coupled when it is not. Corrected in
13
- // Story #4922.
14
- //
15
- // The resolver is intentionally pure — it takes already-extracted
16
- // inputs and returns a frozen ScopeResolution. Env reading and config
17
- // loading happen in the caller; that keeps this module trivially
18
- // testable.
19
- //
20
- // Precedence (highest → lowest):
21
- //
22
- // 1. Environment — `BASELINE_SCOPE` ('full' | 'diff') and
23
- // `BASELINE_REF` (any git ref). The dispatcher reads these from
24
- // `process.env` and forwards via `envScope` / `envRef` so the
25
- // resolver itself never touches process state. CI sets these.
26
- // 2. Config — `configScope` ('full' | 'diff') and `configRef` (any
27
- // git ref) from `delivery.quality.gateScoping` in `.agentrc.json`.
28
- // 3. Default — `mode='diff'` against `ref='main'`. This is the
29
- // framework-wide fallback when nothing else is configured.
30
- //
31
- // Story #4922 removed a fourth, highest-precedence layer: a
32
- // `cliFlags.fullScope` / `cliFlags.changedSinceRef` operator override,
33
- // plus the `cliFlags.changedFiles` → `files` plumbing that fed it. No
34
- // production caller ever populated any of the three — only this module's
35
- // own unit tests did — so the layer's only effect was to advertise a
36
- // `--full-scope` / `--changed-since` contract that `check-baselines.js`
37
- // does not implement, and a `files` set that no consumer read. Operators
38
- // who need full scope set `BASELINE_SCOPE=full`, which is what CI does.
39
- // (`mergeRowsByScope` below still takes a `files`-bearing scope — that
40
- // one comes from the refresh service's own resolver, not from here.)
41
- //
42
- // Missing-ref fallback: when the resolved mode is `'diff'` but no ref
43
- // is supplied at any layer, the resolver falls back to `'main'` rather
44
- // than producing a half-resolved scope with `ref=null`. The dispatcher
45
- // would have to invent a default anyway; centralising it here keeps
46
- // every gate aligned.
47
- //
48
- // `kind` (e.g. `'lint'`, `'coverage'`, `'crap'`) is currently echoed
49
- // through to the resolution unchanged. The argument exists so future
50
- // per-kind overrides (e.g. "lint always runs full") have a place to
51
- // land without breaking call signatures. Today: pass it; ignore it.
52
- //
53
- // Returned shape:
54
- //
55
- // {
56
- // kind: string, // echoed back for caller convenience
57
- // mode: 'full' | 'diff',
58
- // ref: string | null, // null in full mode; ref string in diff mode
59
- // source: string, // which layer won (debug / friction signal)
60
- // }
1
+ // Read-side scope resolution for the `check-baselines` dispatcher (the
2
+ // refresh service has its own resolver). Pure: the caller extracts
3
+ // `BASELINE_SCOPE` / `BASELINE_REF`; env wins, else diff against `main`.
61
4
 
62
5
  const VALID_MODES = new Set(['full', 'diff']);
63
6
  const DEFAULT_DIFF_REF = 'main';
64
7
 
65
8
  /**
66
- * Coerce a candidate value to a non-empty string, or `null`.
67
- *
68
9
  * @param {unknown} v
69
10
  * @returns {string | null}
70
11
  */
@@ -73,10 +14,7 @@ function asNonEmptyString(v) {
73
14
  }
74
15
 
75
16
  /**
76
- * Coerce a candidate scope value to one of the canonical modes, or
77
- * `null` if it is not a recognised mode. Unknown strings are dropped
78
- * rather than coerced — the layer "did not specify" rather than
79
- * "specified an invalid value".
17
+ * An unknown string means "unspecified", not invalid.
80
18
  *
81
19
  * @param {unknown} v
82
20
  * @returns {'full' | 'diff' | null}
@@ -86,13 +24,10 @@ function asMode(v) {
86
24
  }
87
25
 
88
26
  /**
89
- * Resolve a scope against the layered precedence (env > config >
90
- * default). Pure; no I/O.
27
+ * `source` names the winning layer; `ref` is null in full mode.
91
28
  *
92
29
  * @param {object} input
93
- * @param {string} input.kind - Baseline kind (e.g. `'lint'`).
94
- * @param {string} [input.configScope] - `'full'` | `'diff'` from agentrc.
95
- * @param {string} [input.configRef] - Diff ref from agentrc.
30
+ * @param {string} input.kind - Echoed back.
96
31
  * @param {string} [input.envScope] - From `BASELINE_SCOPE`.
97
32
  * @param {string} [input.envRef] - From `BASELINE_REF`.
98
33
  * @returns {{
@@ -108,7 +43,6 @@ export function resolveScope(input = {}) {
108
43
  ? input.kind
109
44
  : 'unknown';
110
45
 
111
- // ---- Layer 1: Environment (extracted by the caller) ------------------
112
46
  const envMode = asMode(input.envScope);
113
47
  if (envMode === 'full') {
114
48
  return Object.freeze({
@@ -128,29 +62,6 @@ export function resolveScope(input = {}) {
128
62
  });
129
63
  }
130
64
 
131
- // ---- Layer 2: Config (delivery.quality.gateScoping) ------------------
132
- const cfgMode = asMode(input.configScope);
133
- if (cfgMode === 'full') {
134
- return Object.freeze({
135
- kind,
136
- mode: 'full',
137
- ref: null,
138
- source: 'config:gateScoping.scope=full',
139
- });
140
- }
141
- const cfgRef = asNonEmptyString(input.configRef);
142
- if (cfgMode === 'diff' || cfgRef) {
143
- return Object.freeze({
144
- kind,
145
- mode: 'diff',
146
- ref: cfgRef ?? DEFAULT_DIFF_REF,
147
- source: cfgRef
148
- ? 'config:gateScoping.diffRef'
149
- : 'config:gateScoping.scope=diff',
150
- });
151
- }
152
-
153
- // ---- Layer 3: Default ------------------------------------------------
154
65
  return Object.freeze({
155
66
  kind,
156
67
  mode: 'diff',
@@ -160,44 +71,17 @@ export function resolveScope(input = {}) {
160
71
  }
161
72
 
162
73
  /**
163
- * Generic scope-aware row merge for s-diff-scoped-writes (Story #1974).
164
- *
165
- * Each per-kind module re-exports a thin wrapper that pins `scopeKey` to
166
- * the field used to identify the file the row belongs to (path / route /
167
- * bundle). This helper does the actual merge:
168
- *
169
- * - `scope.mode === 'full'` (or `scope` is null/undefined / `scope.files`
170
- * is empty): regenerated wins everywhere — returned as-is. This keeps
171
- * the legacy "always rewrite" behaviour intact when no scope filter is
172
- * applied.
173
- * - `scope.mode === 'diff'`: rows whose `scopeKey` value is OUTSIDE
174
- * `scope.files` are preserved from `prior` verbatim. Rows whose
175
- * `scopeKey` value is INSIDE `scope.files` are taken from
176
- * `regenerated` (the regenerated values for in-scope files). Prior
177
- * rows for in-scope files are dropped (regen replaces them); regen
178
- * rows for out-of-scope files are dropped (the writer should not have
179
- * computed them, but we filter defensively).
180
- * - Missing `prior` (null / undefined / empty) — regenerated wins
181
- * everywhere; behaves like full mode.
182
- *
183
- * Identity matching uses the per-kind `identity(row)` function — for
184
- * coverage / lint / maintainability / mutation / lighthouse / bundle-size
185
- * the identity is the keyField value; for crap it's a composite
186
- * `path::method@startLine`. The merge preserves row ordering by
187
- * concatenating in-scope regen rows then out-of-scope prior rows; the
188
- * downstream `sortRows` from the per-kind module re-sorts before write.
189
- *
190
- * Pure. No I/O.
74
+ * Scope-aware row merge. Full mode, no scope, or no prior: regenerated wins.
75
+ * Diff mode: in-scope rows come from `regenerated`, out-of-scope rows from
76
+ * `prior` verbatim (regen rows outside scope are dropped). Output is unsorted.
191
77
  *
192
78
  * @template TRow
193
79
  * @param {object} args
194
80
  * @param {Array<TRow>|null|undefined} args.prior
195
81
  * @param {Array<TRow>|null|undefined} args.regenerated
196
82
  * @param {{mode?: 'full'|'diff', files?: Set<string>|Iterable<string>}|null|undefined} args.scope
197
- * @param {(row: TRow) => string} args.scopeKey Per-kind scope-key extractor — returns the
198
- * file path / route / bundle name used to match against `scope.files`.
199
- * @param {(row: TRow) => string} [args.identity] Per-kind identity extractor — defaults to
200
- * the same as `scopeKey`. CRAP overrides this with `path::method@startLine`.
83
+ * @param {(row: TRow) => string} args.scopeKey The file key matched against `scope.files`.
84
+ * @param {(row: TRow) => string} [args.identity] Defaults to `scopeKey`.
201
85
  * @returns {Array<TRow>}
202
86
  */
203
87
  export function mergeRowsByScope({
@@ -214,23 +98,15 @@ export function mergeRowsByScope({
214
98
  }
215
99
  const idFn = typeof identity === 'function' ? identity : scopeKey;
216
100
 
217
- // No scope filter / full mode / no prior → regen wins everywhere.
218
101
  const mode = scope?.mode;
219
102
  if (!scope || mode === 'full' || priorRows.length === 0) {
220
103
  return regenRows.slice();
221
104
  }
222
105
 
223
- // Coerce scope.files to a Set for O(1) membership tests. An empty Set in
224
- // diff mode means "no files in scope" — every prior row is preserved
225
- // and every regen row is dropped (defensive: writer feeds in-scope rows).
226
106
  const filesSet =
227
107
  scope.files instanceof Set ? scope.files : new Set(scope.files ?? []);
228
108
 
229
- // In-scope regen rows: keep regen.
230
109
  const regenInScope = regenRows.filter((row) => filesSet.has(scopeKey(row)));
231
- // Out-of-scope prior rows: keep prior, but drop any whose identity
232
- // collides with an in-scope regen row (defensive — should not happen
233
- // since identity within a kind is keyField-derived).
234
110
  const inScopeIds = new Set(regenInScope.map((row) => idFn(row)));
235
111
  const priorOutOfScope = priorRows.filter(
236
112
  (row) => !filesSet.has(scopeKey(row)) && !inScopeIds.has(idFn(row)),
@@ -1,41 +1,7 @@
1
1
  /**
2
- * writer.js — shared baseline writer (Story #1891, Epic #1786).
3
- *
4
- * Every legacy baseline-refresh script (`update-crap-baseline.js`,
5
- * `update-maintainability-baseline.js`, `lib/coverage-baseline.js`,
6
- * the auto-refresh evaluator, now inside `auto-refresh-runner.js`) used to assemble its own envelope and
7
- * call `fs.writeFileSync`. That meant the path canonicalisation, rollup
8
- * math, kernel-version stamping, and JSON-serialisation conventions were
9
- * duplicated five-ish times, each with subtly different rules. The
10
- * worktree-prefix bug that prompted Story #1891 is the proof: each
11
- * refresh path had to remember to strip `.worktrees/<workspace>/` on its
12
- * own, and the maintainability path forgot.
13
- *
14
- * `write({ kind, rows, components, kernelVersion?, generatedAt? })` is
15
- * the single funnel:
16
- *
17
- * 1. Look up the per-kind module via the kernel registry. The module
18
- * declares the `keyField`, `projectRow`, `sortRows`, `rollup`, and
19
- * `kernelVersion()` functions.
20
- * 2. Run every row through `projectRow` — that's where the path is
21
- * canonicalised via `path-canon.canonicalise()`. After projection,
22
- * the writer asserts every key field is already canonical
23
- * (`path-canon.assertCanonical()`), refusing to silently rewrite
24
- * identity.
25
- * 3. Sort the rows for deterministic on-disk diffs.
26
- * 4. Compute the per-component rollup (always including `*`).
27
- * 5. Stamp the envelope via `buildEnvelope` — `$schema`, `kernelVersion`,
28
- * `generatedAt`.
29
- * 6. Validate the envelope via `assertEnvelope` (AJV against the per-kind
30
- * schema).
31
- * 7. Return the envelope object. Callers serialise via `writeFile()`
32
- * (separate seam so tests can round-trip without touching disk).
33
- *
34
- * `writeFile(absPath, envelope)` is the serialise + flush seam. It
35
- * stringifies the envelope with two-space indent, appends a trailing
36
- * newline, creates the parent directory, and writes atomically (write to
37
- * `<path>.tmp` then `rename` — `rename` is atomic on every platform we
38
- * support).
2
+ * Shared baseline writer, the single funnel for envelope assembly
3
+ * (`write`: project, canonical-assert, merge, stabilise, sort, rollup, stamp,
4
+ * validate) and serialisation (`writeFile`: atomic tmp + rename).
39
5
  *
40
6
  * @module lib/baselines/writer
41
7
  */
@@ -48,42 +14,11 @@ import { currentKernelVersion, getKindModule } from './kernel.js';
48
14
  import { assertCanonical } from './path-canon.js';
49
15
 
50
16
  /**
51
- * Assemble + validate a baseline envelope. Returns the envelope object
52
- * (no disk I/O). Callers feed the result into `writeFile()` when they're
53
- * ready to persist.
54
- *
55
- * Story #1964 (s-stability-epsilon) added the optional `prior` and
56
- * `epsilon` parameters. When both are present, the writer calls the
57
- * per-kind `applyEpsilon(prior, regenerated, epsilon)` stabilizer
58
- * **after** projection but **before** sort/rollup/serialise. Sub-epsilon
59
- * row deltas resolve to the prior bytes, so env variance never rewrites
60
- * the on-disk envelope. When either is absent (`undefined`), behaviour is
61
- * unchanged from the pre-#1964 contract — this is regression-fail-safe by
62
- * design so existing call sites stay untouched.
63
- *
64
- * Story #1974 (s-diff-scoped-writes) added the optional `scope` parameter.
65
- * When `scope` is present *and* `prior` is supplied, the writer calls the
66
- * per-kind `mergeRows(prior, projected, scope)` filter **after** projection
67
- * but **before** `applyEpsilon`. The composition is intentional: scope-
68
- * filter first (preserve out-of-scope prior rows verbatim), then stabilise
69
- * the in-scope rows against the same prior under epsilon. The merged result
70
- * is sorted, rolled up, and serialised exactly as before. When `scope` is
71
- * absent (or `prior` is absent), behaviour is unchanged from the pre-#1974
72
- * contract — also regression-fail-safe.
73
- *
74
- * `prior` MUST be an array of rows already in canonical (per-kind
75
- * `projectRow`) shape — the on-disk baseline format is canonical
76
- * end-to-end, and the writer no longer re-projects prior rows on entry.
77
- *
78
- * Story #2135 (Task #2146) added the structural-equality short-circuit on
79
- * top of `prior`. When a `prior` envelope (or `priorEnvelope`) is supplied
80
- * and the projected `rows + rollup` deep-equal the prior's `rows + rollup`,
81
- * the writer returns the prior envelope unchanged — same `generatedAt`,
82
- * same kernelVersion, same byte payload. Without this guard every
83
- * auto-refresh that ran on a no-op Story would stamp a fresh
84
- * `generatedAt` and surface a spurious one-line diff. The short-circuit
85
- * is the semantic replacement for the legacy byte-equality compare that
86
- * lived in `baseline-snapshot.js`.
17
+ * Assemble and validate an envelope (no I/O). With `scope`, out-of-scope
18
+ * `prior` rows are preserved first; with `epsilon`, sub-epsilon deltas then
19
+ * resolve to prior bytes. `prior` rows must already be canonical. When rows
20
+ * and rollup deep-equal the prior envelope, the prior is returned unchanged
21
+ * so a no-op refresh leaves no `generatedAt` diff.
87
22
  *
88
23
  * @param {{
89
24
  * kind: string,
@@ -127,11 +62,7 @@ export function write({
127
62
  }
128
63
  });
129
64
 
130
- // Defensive: assert every key field on the projected rows is canonical.
131
- // The per-kind `projectRow` already funnels paths through `canonicalise`,
132
- // but the assertion catches a future per-kind module that forgets — and
133
- // catches absolute paths in inputs that the canonicaliser would also
134
- // throw on (we surface a writer-scoped error pointing at the row).
65
+ // Catches a kind module whose `projectRow` forgets to canonicalise.
135
66
  if (mod.keyField === 'path') {
136
67
  projected.forEach((row, idx) => {
137
68
  try {
@@ -150,30 +81,19 @@ export function write({
150
81
  const sortedRows = mod.sortRows(stabilised);
151
82
  const rollup = mod.rollup(sortedRows, components ?? []);
152
83
 
153
- // The rollup() implementations always seed `*` from `aggregate()`, but
154
- // the AC pins this explicitly: the envelope ALWAYS carries `*` even
155
- // when `components` is undefined or empty. Belt-and-braces.
156
84
  if (!Object.hasOwn(rollup, '*')) {
157
85
  throw new Error(
158
86
  `writer.write: ${kind} rollup is missing the required "*" key`,
159
87
  );
160
88
  }
161
89
 
162
- // Story #2135 / Task #2146 — structural-equality short-circuit. When the
163
- // caller supplies a `priorEnvelope` (or, for backwards-compatibility, the
164
- // bare `prior` array is itself a full envelope object), and the projected
165
- // rows + rollup deep-equal what's on the prior, return the prior envelope
166
- // unchanged. This is the semantic replacement for the byte-equality
167
- // compare in `baseline-snapshot.js` and is what makes a no-op auto-refresh
168
- // produce a zero-byte baseline diff.
169
90
  const priorEnv = resolvePriorEnvelope(priorEnvelope, prior);
170
91
  if (
171
92
  priorEnv &&
172
93
  deepEqual(sortedRows, priorEnv.rows) &&
173
94
  deepEqual(rollup, priorEnv.rollup)
174
95
  ) {
175
- // Re-validate defensively before returning so a caller cannot smuggle
176
- // an invalid envelope through the short-circuit.
96
+ // No smuggling an invalid envelope through the short-circuit.
177
97
  assertEnvelope(priorEnv);
178
98
  return priorEnv;
179
99
  }
@@ -191,14 +111,7 @@ export function write({
191
111
  return envelope;
192
112
  }
193
113
 
194
- /**
195
- * Resolve the prior envelope used by the structural-equality short-circuit.
196
- * Accepts either an explicit `priorEnvelope` (preferred) or, for backwards
197
- * compatibility, recognises when `prior` is itself a full envelope object
198
- * carrying `rows` + `rollup` rather than a bare rows array. Returns null
199
- * when neither yields a usable envelope — the short-circuit is opt-in by
200
- * design.
201
- */
114
+ /** `priorEnvelope`, else `prior` when it is a whole envelope, else null. */
202
115
  function resolvePriorEnvelope(priorEnvelope, prior) {
203
116
  if (
204
117
  priorEnvelope &&
@@ -224,21 +137,8 @@ function resolvePriorEnvelope(priorEnvelope, prior) {
224
137
  }
225
138
 
226
139
  /**
227
- * Serialise an envelope to `absPath`. Deterministic: two-space indent,
228
- * trailing newline, sorted keys for the top-level envelope keys (rows are
229
- * already sorted by the per-kind module's `sortRows`). Atomic: writes to
230
- * `<absPath>.tmp` then `rename`s onto the destination so a crash mid-write
231
- * never leaves a half-flushed envelope on disk.
232
- *
233
- * Story #2135 / Task #2146 — the optional `fsImpl` seam lets tests inject
234
- * a virtual filesystem (or an in-memory recorder) the way the legacy
235
- * saver helpers allowed. Production callers omit it and fall through to
236
- * `node:fs`. The seam covers `mkdirSync`, `writeFileSync`, and
237
- * `renameSync` — the three calls this function actually makes — so a mock
238
- * that exposes a subset of `fs` works without leaking real disk I/O.
239
- *
240
- * Backwards-compatible: two-argument callers (`writeFile(abs, env)`)
241
- * continue to work unchanged.
140
+ * Serialise deterministically (fixed top-level key order, two-space indent,
141
+ * trailing newline) and atomically (tmp + rename).
242
142
  *
243
143
  * @param {string} absPath
244
144
  * @param {object} envelope
@@ -251,29 +151,13 @@ export function writeFile(absPath, envelope, opts = {}) {
251
151
  `writer.writeFile: absPath must be an absolute path (got ${JSON.stringify(absPath)})`,
252
152
  );
253
153
  }
254
- // Re-validate at the seam — a caller might mutate the envelope between
255
- // `write()` and `writeFile()`.
154
+ // The caller may have mutated the envelope since `write()`.
256
155
  assertEnvelope(envelope);
257
156
 
258
157
  const fsImpl = opts?.fsImpl ? opts.fsImpl : fs;
259
158
 
260
- // Canonical key order on the top-level envelope keeps diffs stable
261
- // across runs and platforms. Per-kind row keys retain their natural
262
- // declaration order; the row sort is done by `sortRows()`.
263
- //
264
- // The projection is deliberately explicit (Story #4775): a per-kind envelope
265
- // stamp reaches disk only if it is named here, so an unlisted one is present
266
- // in memory, passes validation, and is absent from the file it exists to
267
- // protect. That is not hypothetical — Story #4901 added `provenanceStamped`
268
- // to `envelopeExtras()` and not to this list, and every baseline written
269
- // between then and Story #4969 lost it at this boundary, leaving the
270
- // `provenance-unstamped` axis reading an absence its own writer had
271
- // manufactured.
272
- //
273
- // A stamp a kind does not set is simply `undefined`, and `JSON.stringify`
274
- // omits an undefined-valued key — so naming all three unconditionally emits
275
- // exactly what the per-key `undefined` guards used to, with nothing to
276
- // half-apply when the next stamp is added.
159
+ // A kind's envelope stamp reaches disk only if named here — add every new
160
+ // `envelopeExtras()` key. Unset stamps are undefined and JSON omits them.
277
161
  const canonical = {
278
162
  $schema: envelope.$schema,
279
163
  kernelVersion: envelope.kernelVersion,
@@ -292,29 +176,12 @@ export function writeFile(absPath, envelope, opts = {}) {
292
176
  return absPath;
293
177
  }
294
178
 
295
- /**
296
- * Story #1974 — s-diff-scoped-writes scope-merge dispatch. When `scope` is
297
- * present, defer to the per-kind `mergeRows(prior, projected, scope)` to
298
- * preserve out-of-scope prior rows verbatim. Returns `projected` unchanged
299
- * when `scope` is omitted, when the kind doesn't ship the merger
300
- * (forward-compatible), or when `prior` is absent (nothing to preserve).
301
- */
302
179
  function scopeMergeRows(mod, projected, prior, scope) {
303
180
  if (scope === undefined || scope === null) return projected;
304
181
  if (typeof mod.mergeRows !== 'function') return projected;
305
- // mergeRows treats null/undefined/empty prior as "no preservation needed"
306
- // and returns projected verbatim — that branch is covered upstream and
307
- // here for symmetry.
308
182
  return mod.mergeRows(prior ?? [], projected, scope);
309
183
  }
310
184
 
311
- /**
312
- * Story #1964 — s-stability-epsilon stabilizer dispatch. When both
313
- * `prior` and `epsilon` are present, fold sub-epsilon row deltas back to
314
- * the prior bytes via the per-kind `applyEpsilon`. Returns `projected`
315
- * unchanged when either is omitted, or when the kind doesn't ship the
316
- * stabilizer (forward-compatible).
317
- */
318
185
  function stabiliseRows(mod, projected, prior, epsilon) {
319
186
  if (prior === undefined || epsilon === undefined) return projected;
320
187
  if (!Array.isArray(prior)) {
@@ -1,40 +1,10 @@
1
1
  /**
2
- * BDD runner detection + pending-tag verification (Epic #2001 Story #2094
3
- * Task #2103; workspace-aware extension from Story #2956).
4
- *
5
- * Used by `buildAuthoringContext` (the `plan-context.js` envelope) to decide whether the
6
- * acceptance-table section should plan **features-first** Story ordering (a real
7
- * pending-tag is available, so the features-first Story can ship `.feature`
8
- * files marked `@pending` / `@skip` ahead of the implementation Stories) or
9
- * fall back to **dependencies-first** ordering (no pending tag → cannot
10
- * suspend an unimplemented scenario without a permanent red, so Stories run
11
- * in dependency order and the AC reconciler defers).
12
- *
13
- * The verification is **static**: we inspect `package.json` for a known BDD
14
- * runner dependency, and consult a small lookup table of which runners
15
- * support which pending/skip tag. We do not boot the runner. This keeps
16
- * `/mandrel-plan` Phase 7 hermetic and offline.
17
- *
18
- * **Workspace awareness (Story #2956).** In a pnpm / npm / yarn monorepo the
19
- * BDD runner is rarely a root devDependency — it lives in the workspace
20
- * package that owns the e2e suite (e.g. `apps/web/package.json`). The
21
- * detector reads the root `package.json` first and then unions in
22
- * dependencies from every declared workspace package, so an `apps/*` shaped
23
- * monorepo no longer falls back to "no runner detected" when the runner
24
- * sits one level down. Workspace declarations are read from
25
- * `pnpm-workspace.yaml` (`packages:` field) or the root `package.json`
26
- * `workspaces` field (array or `{ packages: [] }` object form).
27
- * Preferred-first ordering is preserved by iterating
28
- * `BDD_RUNNER_TAG_TABLE` against the union of all collected deps — the
29
- * first runner present in *any* package wins.
30
- *
31
- * Output shape (returned to the planner-context envelope):
32
- *
33
- * { runner: 'cucumber-js', pendingTag: '@skip', supported: true, fallback: false }
34
- * { runner: 'playwright-bdd', pendingTag: '@skip', supported: true, fallback: false }
35
- * { runner: '@cucumber/cucumber', pendingTag: '@skip', supported: true, fallback: false }
36
- * { runner: null, pendingTag: null, supported: false, fallback: true,
37
- * reason: 'no-bdd-runner-detected' }
2
+ * Static BDD runner detection: does the project ship a runner with a
3
+ * pending/skip tag? If so the planner can order features-first (scenarios
4
+ * land `@skip` ahead of the implementation); if not, dependencies-first,
5
+ * since an unimplemented scenario would be a permanent red. Reads the root
6
+ * `package.json` plus every workspace package (runners usually live in one),
7
+ * never boots the runner.
38
8
  */
39
9
 
40
10
  import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
@@ -45,13 +15,7 @@ import picomatch from 'picomatch';
45
15
 
46
16
  import { Logger } from './Logger.js';
47
17
 
48
- /**
49
- * Known BDD runner package names → pending-tag string the runner honours.
50
- *
51
- * Keys MUST match the literal npm package name as it appears in
52
- * `dependencies` or `devDependencies`. Order is preferred-first: if multiple
53
- * runners are present (rare), the first match wins.
54
- */
18
+ /** npm package name → pending tag. Preferred-first: the first match wins. */
55
19
  export const BDD_RUNNER_TAG_TABLE = Object.freeze({
56
20
  'playwright-bdd': '@skip',
57
21
  '@cucumber/cucumber': '@skip',
@@ -60,21 +24,8 @@ export const BDD_RUNNER_TAG_TABLE = Object.freeze({
60
24
  });
61
25
 
62
26
  /**
63
- * Shared set of tag tokens that mean "this scenario does not yet satisfy
64
- * its AC — treat coverage as pending, not satisfied." Sourced from every
65
- * pending-tag value in `BDD_RUNNER_TAG_TABLE` (today `@skip` / `skip`).
66
- *
67
- * Both the prefixed (`@skip`) and the unprefixed (`skip`) form of each
68
- * tag are included so consumers can look up either the raw tag string
69
- * (as it appears in a `.feature` file) or the normalized token form
70
- * produced by tag-block parsers that strip the leading `@`.
71
- *
72
- * Consumers:
73
- * - `acceptance-spec-reconciler.classifyCoverage` — membership check
74
- * against parsed scenario tag sets.
75
- * - Contract tests that walk `BDD_RUNNER_TAG_TABLE` and assert each
76
- * pending tag is registered here, guarding against drift when a
77
- * new runner is added.
27
+ * Tags meaning "coverage pending, not satisfied", in both `@skip` and
28
+ * `skip` forms (parsers may strip the `@`).
78
29
  */
79
30
  export const PENDING_TAGS = Object.freeze(
80
31
  new Set(
@@ -85,11 +36,6 @@ export const PENDING_TAGS = Object.freeze(
85
36
  ),
86
37
  );
87
38
 
88
- /**
89
- * Result returned when no supported BDD runner is detected. The acceptance
90
- * spec body will print "Fallback: dependencies-first ordering" and Phase 8
91
- * decomposer ordering reverts to topological dependency order.
92
- */
93
39
  const FALLBACK = Object.freeze({
94
40
  runner: null,
95
41
  pendingTag: null,
@@ -99,19 +45,11 @@ const FALLBACK = Object.freeze({
99
45
  });
100
46
 
101
47
  /**
102
- * Verify which BDD runner (if any) the project ships and whether it
103
- * supports a pending/skip tag. Reads the root `package.json` and (when
104
- * declared) every workspace `package.json` so monorepos that house the
105
- * runner in `apps/<name>` or `packages/<name>` resolve correctly.
106
- *
107
48
  * @param {object} [opts]
108
- * @param {string} [opts.cwd] - Project root holding `package.json`.
109
- * @param {(p: string) => Promise<string>} [opts.readPkg] - Override for
110
- * tests; receives the resolved absolute path to a `package.json`.
49
+ * @param {string} [opts.cwd]
50
+ * @param {(p: string) => Promise<string>} [opts.readPkg] Test seam.
111
51
  * @param {(ctx: { cwd: string, rootPkg: object, readPkg: Function }) => Promise<string[]>} [opts.listWorkspacePkgPaths]
112
- * Override for tests; returns absolute paths to workspace `package.json`
113
- * files. Defaults to scanning `pnpm-workspace.yaml` then the root
114
- * `package.json` `workspaces` field and expanding their glob patterns.
52
+ * Test seam.
115
53
  * @returns {Promise<{ runner: string|null, pendingTag: string|null, supported: boolean, fallback: boolean, reason?: string }>}
116
54
  */
117
55
  export async function verifyBddRunnerPendingTag(opts = {}) {
@@ -153,7 +91,6 @@ export async function verifyBddRunnerPendingTag(opts = {}) {
153
91
  logger,
154
92
  });
155
93
  } catch (err) {
156
- // Workspace discovery failure is non-fatal: degrade to root-only scan.
157
94
  logger.debug(
158
95
  `[bdd-runner-detect] workspace discovery failed for ${cwd}: ${err?.message ?? err}`,
159
96
  );
@@ -201,18 +138,8 @@ export async function verifyBddRunnerPendingTag(opts = {}) {
201
138
  }
202
139
 
203
140
  /**
204
- * Default workspace discovery: read `pnpm-workspace.yaml` (`packages:`
205
- * field) then the root `package.json` `workspaces` field, expand the
206
- * glob patterns against `cwd`, and return the resulting workspace
207
- * `package.json` absolute paths.
208
- *
209
- * Returns `[]` (silent) on any of:
210
- * - no `pnpm-workspace.yaml` and no `workspaces` field
211
- * - YAML parse failure
212
- * - patterns matching no on-disk directories
213
- *
214
- * Failures here are non-fatal so a malformed workspace file can never
215
- * block planner-context emission.
141
+ * Workspace `package.json` paths from `pnpm-workspace.yaml`, else the root
142
+ * `workspaces` field. Non-fatal: `[]` on any failure.
216
143
  *
217
144
  * @returns {Promise<string[]>}
218
145
  */
@@ -233,7 +160,6 @@ function readWorkspacePatterns(cwd, rootPkg, logger) {
233
160
  return parsed.packages.filter((p) => typeof p === 'string');
234
161
  }
235
162
  } catch (err) {
236
- // unparseable yaml → fall through to package.json workspaces
237
163
  logger.debug(
238
164
  `[bdd-runner-detect] pnpm-workspace.yaml parse failed for ${yamlPath}: ${err?.message ?? err}`,
239
165
  );
@@ -253,14 +179,7 @@ function readWorkspacePatterns(cwd, rootPkg, logger) {
253
179
  return [];
254
180
  }
255
181
 
256
- /**
257
- * Expand a list of workspace glob patterns into absolute paths to each
258
- * matching `package.json`. Handles:
259
- * - literal directory entries (no glob chars): `apps/web`
260
- * - single-segment globs: `apps/*`, `packages/*`
261
- * - recursive globs: `packages/**`
262
- * - exclusion patterns prefixed with `!` (pnpm/npm convention)
263
- */
182
+ /** Handles literal dirs, `*` and `**` globs, and `!` exclusions. */
264
183
  function expandWorkspacePatterns(cwd, patterns, logger) {
265
184
  const includes = patterns.filter((p) => !p.startsWith('!'));
266
185
  const excludes = patterns
@@ -366,13 +285,7 @@ function existsSyncDir(p, logger) {
366
285
  }
367
286
  }
368
287
 
369
- /**
370
- * Canonical directories a project might use to house `.feature` files.
371
- * Probed in order; the first existing directory wins. The list is
372
- * deliberately short — projects that house features elsewhere will need
373
- * to land an explicit config surface for it, which Story #2637 leaves
374
- * out of scope.
375
- */
288
+ /** Canonical `.feature` directories; there is no config key for others. */
376
289
  const CANONICAL_FEATURE_ROOTS = Object.freeze([
377
290
  'tests/features',
378
291
  'features',
@@ -380,17 +293,10 @@ const CANONICAL_FEATURE_ROOTS = Object.freeze([
380
293
  ]);
381
294
 
382
295
  /**
383
- * Resolve the project's BDD feature roots — absolute paths to every
384
- * canonical directory that exists under `cwd`. Returns an empty array
385
- * when no feature directory is present (the project has not adopted
386
- * BDD), so downstream scanners can degrade silently to "no scenarios".
387
- *
388
- * Story #2637 — the Phase 7 BDD-scenario scanner consumes this so the
389
- * planner can cross-reference acceptance criteria against existing
390
- * scenarios without introducing a new config key.
296
+ * Existing canonical feature roots; `[]` when the project has not adopted BDD.
391
297
  *
392
298
  * @param {{ cwd?: string }} [opts]
393
- * @returns {string[]} Absolute paths to existing feature roots.
299
+ * @returns {string[]}
394
300
  */
395
301
  export function resolveFeatureRoots(opts = {}) {
396
302
  const cwd = opts.cwd ?? process.cwd();
@@ -403,7 +309,6 @@ export function resolveFeatureRoots(opts = {}) {
403
309
  roots.push(abs);
404
310
  }
405
311
  } catch (err) {
406
- // Unreadable path → treat as absent. Non-blocking by design.
407
312
  logger.debug(
408
313
  `[bdd-runner-detect] feature-root probe failed for ${abs}: ${err?.message ?? err}`,
409
314
  );