mandrel 2.60.0 → 2.62.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 (662) 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/merge-queue.js +158 -0
  318. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  319. package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
  320. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  321. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  322. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  323. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  324. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  325. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  326. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
  327. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  328. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  329. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  330. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  331. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  332. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  333. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
  334. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  335. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
  336. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
  337. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
  338. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  339. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  340. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  341. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  342. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  343. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  344. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  345. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  346. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  347. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  348. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  349. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  350. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  351. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  352. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  353. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  354. package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
  355. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  356. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  357. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  358. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  359. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  360. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  361. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  362. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  363. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  364. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  365. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  366. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  367. package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
  368. package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
  369. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  370. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  371. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  372. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
  373. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  391. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
  392. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  393. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  394. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  395. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  396. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  397. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  398. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  399. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  400. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
  401. package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
  402. package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
  403. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  404. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  405. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
  406. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  407. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  408. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  409. package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
  410. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  411. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
  412. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  413. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  414. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  415. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  416. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  417. package/.agents/scripts/lib/path-security.js +3 -6
  418. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  419. package/.agents/scripts/lib/preflight-runner.js +13 -69
  420. package/.agents/scripts/lib/process-group.js +143 -0
  421. package/.agents/scripts/lib/project-root.js +2 -8
  422. package/.agents/scripts/lib/provider-factory.js +2 -25
  423. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  424. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  425. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  426. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  427. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  428. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  429. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  430. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  431. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  432. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  433. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  434. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  435. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  436. package/.agents/scripts/lib/signals/index.js +2 -19
  437. package/.agents/scripts/lib/signals/schema.js +14 -109
  438. package/.agents/scripts/lib/signals/write.js +2 -11
  439. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  440. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  441. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  442. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  443. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  444. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  445. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  446. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  447. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  448. package/.agents/scripts/lib/source-extensions.js +11 -42
  449. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  450. package/.agents/scripts/lib/stdio-flush.js +9 -36
  451. package/.agents/scripts/lib/story-adjacency.js +8 -40
  452. package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
  453. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  454. package/.agents/scripts/lib/story-body/story-body.js +83 -358
  455. package/.agents/scripts/lib/temp-retention.js +42 -143
  456. package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
  457. package/.agents/scripts/lib/test-env.js +12 -65
  458. package/.agents/scripts/lib/test-run-credit.js +10 -65
  459. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  460. package/.agents/scripts/lib/test-temp.js +38 -184
  461. package/.agents/scripts/lib/test-tiers.js +12 -96
  462. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  463. package/.agents/scripts/lib/transpile.js +15 -74
  464. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  465. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  466. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  467. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  468. package/.agents/scripts/lib/validation-evidence.js +21 -96
  469. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  470. package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
  471. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  472. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  473. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  474. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  475. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  476. package/.agents/scripts/lib/workflow-closure.js +22 -105
  477. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  478. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  479. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  480. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  481. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  482. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  483. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  484. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  485. package/.agents/scripts/lib/worktree-manager.js +15 -40
  486. package/.agents/scripts/lint-issue-body.js +12 -68
  487. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  488. package/.agents/scripts/merge-baseline.js +30 -104
  489. package/.agents/scripts/nav-registry-diff.js +22 -108
  490. package/.agents/scripts/notify.js +12 -69
  491. package/.agents/scripts/plan-context.js +27 -111
  492. package/.agents/scripts/plan-critics.js +12 -66
  493. package/.agents/scripts/plan-persist.js +31 -148
  494. package/.agents/scripts/plan-run-epilogue.js +11 -37
  495. package/.agents/scripts/pr-watch-with-update.js +76 -267
  496. package/.agents/scripts/providers/github/auth.js +3 -8
  497. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  498. package/.agents/scripts/providers/github/board-add.js +5 -21
  499. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  500. package/.agents/scripts/providers/github/cache.js +2 -14
  501. package/.agents/scripts/providers/github/comments.js +7 -40
  502. package/.agents/scripts/providers/github/compose.js +3 -19
  503. package/.agents/scripts/providers/github/errors.js +22 -125
  504. package/.agents/scripts/providers/github/issues.js +31 -123
  505. package/.agents/scripts/providers/github/labels.js +24 -124
  506. package/.agents/scripts/providers/github/mappers.js +5 -27
  507. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  508. package/.agents/scripts/providers/github/project-board.js +2 -17
  509. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  510. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  511. package/.agents/scripts/providers/github/search-budget.js +9 -39
  512. package/.agents/scripts/providers/github/search-query.js +5 -26
  513. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  514. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  515. package/.agents/scripts/providers/github/tickets.js +32 -134
  516. package/.agents/scripts/providers/github.js +18 -59
  517. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  518. package/.agents/scripts/quality-preview.js +35 -220
  519. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  520. package/.agents/scripts/resolve-stories.js +16 -67
  521. package/.agents/scripts/resync-status-column.js +6 -25
  522. package/.agents/scripts/run-tests.js +29 -104
  523. package/.agents/scripts/single-story-close.js +23 -135
  524. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  525. package/.agents/scripts/single-story-init.js +47 -209
  526. package/.agents/scripts/stories-wave-tick.js +102 -472
  527. package/.agents/scripts/sync-agentrc.js +3 -21
  528. package/.agents/scripts/sync-claude-agents.js +9 -55
  529. package/.agents/scripts/sync-claude-commands.js +20 -110
  530. package/.agents/scripts/test-wrapper.js +6 -43
  531. package/.agents/scripts/update-coverage-baseline.js +5 -22
  532. package/.agents/scripts/update-crap-baseline.js +7 -30
  533. package/.agents/scripts/update-duplication-baseline.js +16 -92
  534. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  535. package/.agents/scripts/update-ticket-state.js +1 -7
  536. package/.agents/scripts/validate-skills.js +6 -26
  537. package/.agents/templates/agent-protocol.md +2 -2
  538. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  539. package/.agents/workflows/audit-accessibility.md +4 -7
  540. package/.agents/workflows/audit-adrs.md +3 -6
  541. package/.agents/workflows/audit-architecture.md +3 -11
  542. package/.agents/workflows/audit-baselines.md +6 -9
  543. package/.agents/workflows/audit-clean-code.md +8 -12
  544. package/.agents/workflows/audit-data-model.md +3 -7
  545. package/.agents/workflows/audit-dependencies.md +4 -7
  546. package/.agents/workflows/audit-devops.md +4 -8
  547. package/.agents/workflows/audit-documentation.md +1 -4
  548. package/.agents/workflows/audit-mobile.md +4 -7
  549. package/.agents/workflows/audit-navigability.md +3 -6
  550. package/.agents/workflows/audit-performance.md +2 -4
  551. package/.agents/workflows/audit-privacy.md +4 -7
  552. package/.agents/workflows/audit-quality.md +4 -7
  553. package/.agents/workflows/audit-security.md +4 -7
  554. package/.agents/workflows/audit-seo.md +4 -7
  555. package/.agents/workflows/audit-sre.md +4 -7
  556. package/.agents/workflows/audit-to-stories.md +17 -30
  557. package/.agents/workflows/audit-ux-ui.md +4 -7
  558. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  559. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  560. package/.agents/workflows/helpers/deliver-digest.md +6 -4
  561. package/.agents/workflows/helpers/deliver-reference.md +114 -188
  562. package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
  563. package/.agents/workflows/helpers/plan-reference.md +86 -139
  564. package/.agents/workflows/helpers/qa-core.md +12 -0
  565. package/.agents/workflows/memory-consolidate.md +1 -1
  566. package/.agents/workflows/qa-assist.md +27 -71
  567. package/.agents/workflows/qa-explore.md +19 -59
  568. package/.agents/workflows/qa-run.md +11 -33
  569. package/README.md +1 -1
  570. package/bin/mandrel.js +5 -46
  571. package/bin/postinstall.js +18 -107
  572. package/docs/CHANGELOG.md +32 -0
  573. package/lib/cli/doctor.js +11 -71
  574. package/lib/cli/init.js +26 -165
  575. package/lib/cli/migrate.js +5 -64
  576. package/lib/cli/registry.js +84 -467
  577. package/lib/cli/sync-agents.js +4 -64
  578. package/lib/cli/sync-commands.js +11 -64
  579. package/lib/cli/sync.js +34 -213
  580. package/lib/cli/uninstall.js +40 -219
  581. package/lib/cli/update.js +105 -661
  582. package/lib/cli/version-check.js +8 -72
  583. package/lib/cli/version-helpers.js +14 -87
  584. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  585. package/lib/migrations/index.js +15 -92
  586. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  587. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  588. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  589. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  590. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  591. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  592. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  593. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  594. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
  595. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  596. package/package.json +16 -14
  597. package/.agents/docs/SDLC.md +0 -590
  598. package/.agents/docs/quality-gates.md +0 -1183
  599. package/.agents/rules/known-tooling-behavior.md +0 -200
  600. package/.agents/rules/orchestration-error-handling.md +0 -61
  601. package/.agents/rules/test-seams.md +0 -59
  602. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  603. package/.agents/schemas/baselines/lint.schema.json +0 -47
  604. package/.agents/scripts/check-action-pinning.js +0 -260
  605. package/.agents/scripts/check-audit-attribution.js +0 -302
  606. package/.agents/scripts/check-baseline-drift.js +0 -211
  607. package/.agents/scripts/check-baseline-scope.js +0 -362
  608. package/.agents/scripts/check-generated-validator.js +0 -202
  609. package/.agents/scripts/check-knip-entries.js +0 -159
  610. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  611. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  612. package/.agents/scripts/check-schema-references.js +0 -368
  613. package/.agents/scripts/check-test-portability.js +0 -512
  614. package/.agents/scripts/check-workflow-citations.js +0 -218
  615. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  616. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  617. package/.agents/scripts/install-matrix-assert.js +0 -326
  618. package/.agents/scripts/lib/audit-advisories.js +0 -195
  619. package/.agents/scripts/lib/audit-attribution.js +0 -134
  620. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  621. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  622. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  623. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  624. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  625. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  626. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  627. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  628. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  629. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  630. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  631. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  632. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  633. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  634. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  635. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  636. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  637. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  638. package/.agents/scripts/lib/fs-walk.js +0 -52
  639. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  640. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  641. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  642. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  643. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  644. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  645. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  646. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  647. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  648. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  649. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  650. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  651. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  652. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  653. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  654. package/.agents/scripts/post-structured-comment.js +0 -127
  655. package/.agents/scripts/provision-git-hooks.js +0 -85
  656. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  657. package/.agents/scripts/run-coverage.js +0 -197
  658. package/.agents/scripts/run-lint.js +0 -133
  659. package/.agents/scripts/run-test-profile.js +0 -129
  660. package/.agents/scripts/run-verify.js +0 -125
  661. package/.agents/scripts/test-isolate.js +0 -55
  662. 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
  );