mandrel 2.60.0 → 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (661) hide show
  1. package/.agents/README.md +10 -10
  2. package/.agents/agents/story-worker.md +1 -1
  3. package/.agents/docs/agentrc-reference.json +4 -82
  4. package/.agents/docs/configuration.md +20 -87
  5. package/.agents/docs/workflows.md +1 -1
  6. package/.agents/instructions.md +1 -3
  7. package/.agents/rules/gherkin-standards.md +4 -0
  8. package/.agents/schemas/agentrc.schema.json +11 -486
  9. package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
  10. package/.agents/schemas/validation-evidence.schema.json +2 -1
  11. package/.agents/scripts/README.md +14 -14
  12. package/.agents/scripts/acceptance-eval.js +32 -164
  13. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  14. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  15. package/.agents/scripts/audit-baselines.js +6 -27
  16. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  17. package/.agents/scripts/audit-to-stories.js +91 -361
  18. package/.agents/scripts/boot-sweep.js +19 -72
  19. package/.agents/scripts/bootstrap.js +74 -395
  20. package/.agents/scripts/ceremony-derive.js +9 -45
  21. package/.agents/scripts/check-arch-cycles.js +14 -64
  22. package/.agents/scripts/check-baselines.js +8 -48
  23. package/.agents/scripts/check-context-budget.js +46 -172
  24. package/.agents/scripts/check-cyclomatic.js +12 -44
  25. package/.agents/scripts/check-dead-exports.js +13 -64
  26. package/.agents/scripts/check-doc-links.js +38 -186
  27. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  28. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  29. package/.agents/scripts/coverage-capture.js +32 -99
  30. package/.agents/scripts/deliver-light.js +14 -101
  31. package/.agents/scripts/deliver-recover.js +6 -42
  32. package/.agents/scripts/deliver-run.js +36 -133
  33. package/.agents/scripts/diagnose-friction.js +24 -116
  34. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  35. package/.agents/scripts/evidence-gate.js +23 -85
  36. package/.agents/scripts/file-ci-gap.js +10 -50
  37. package/.agents/scripts/generate-config-docs.js +30 -170
  38. package/.agents/scripts/generate-lens-checklists.js +8 -52
  39. package/.agents/scripts/generate-skills-index.js +14 -112
  40. package/.agents/scripts/generate-workflows-doc.js +10 -70
  41. package/.agents/scripts/git-cleanup.js +2 -34
  42. package/.agents/scripts/lib/Graph.js +24 -81
  43. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  44. package/.agents/scripts/lib/Logger.js +14 -76
  45. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  46. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  47. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  48. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  49. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  50. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  51. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  52. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  53. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  54. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  55. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  56. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  57. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  58. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  59. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  60. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  61. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  62. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  63. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  64. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  65. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  66. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  67. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  68. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  69. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  70. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  71. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  72. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  73. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  74. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  75. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  76. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  77. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  78. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  79. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  80. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  81. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  82. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  83. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  84. package/.agents/scripts/lib/baseline-loader.js +12 -51
  85. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  86. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  87. package/.agents/scripts/lib/baselines/components.js +10 -61
  88. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  89. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
  90. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  91. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  92. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  93. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  94. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  95. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  96. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  97. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  98. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  99. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  100. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  101. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  102. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  103. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  104. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  105. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  106. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  107. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  108. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  109. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  110. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  111. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  112. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  113. package/.agents/scripts/lib/baselines/reader.js +14 -107
  114. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  115. package/.agents/scripts/lib/baselines/scope.js +11 -135
  116. package/.agents/scripts/lib/baselines/writer.js +16 -149
  117. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  118. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  119. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  120. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  121. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  122. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  123. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  124. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  125. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  126. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  127. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  128. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  129. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  130. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  131. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  132. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  133. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  134. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  135. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  136. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  137. package/.agents/scripts/lib/changed-files.js +31 -143
  138. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  139. package/.agents/scripts/lib/checks/index.js +18 -101
  140. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  141. package/.agents/scripts/lib/checks/state.js +16 -91
  142. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  143. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  144. package/.agents/scripts/lib/child-exec.js +39 -108
  145. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  146. package/.agents/scripts/lib/cli-args.js +31 -146
  147. package/.agents/scripts/lib/cli-usage.js +5 -27
  148. package/.agents/scripts/lib/cli-utils.js +2 -12
  149. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  150. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  151. package/.agents/scripts/lib/close-validation/process.js +121 -151
  152. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  153. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  154. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  155. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  156. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  157. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  158. package/.agents/scripts/lib/command-header.js +6 -28
  159. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  160. package/.agents/scripts/lib/config/baselines.js +3 -14
  161. package/.agents/scripts/lib/config/ci.js +8 -38
  162. package/.agents/scripts/lib/config/commands.js +1 -15
  163. package/.agents/scripts/lib/config/defaults.js +4 -33
  164. package/.agents/scripts/lib/config/delivery-routing.js +6 -35
  165. package/.agents/scripts/lib/config/explain.js +9 -80
  166. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  167. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
  168. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  169. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  170. package/.agents/scripts/lib/config/gates/index.js +2 -17
  171. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  172. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  173. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  174. package/.agents/scripts/lib/config/github.js +4 -22
  175. package/.agents/scripts/lib/config/limits.js +4 -57
  176. package/.agents/scripts/lib/config/paths.js +2 -21
  177. package/.agents/scripts/lib/config/qa.js +4 -38
  178. package/.agents/scripts/lib/config/quality.js +76 -432
  179. package/.agents/scripts/lib/config/runners.js +12 -56
  180. package/.agents/scripts/lib/config/runtime.js +13 -57
  181. package/.agents/scripts/lib/config/shared.js +2 -16
  182. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  183. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  184. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  185. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  186. package/.agents/scripts/lib/config-resolver.js +10 -52
  187. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  188. package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
  189. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  190. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  191. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  192. package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
  193. package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
  194. package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
  195. package/.agents/scripts/lib/coverage-capture.js +99 -224
  196. package/.agents/scripts/lib/coverage-utils.js +14 -79
  197. package/.agents/scripts/lib/cpu-pool.js +17 -123
  198. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  199. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  200. package/.agents/scripts/lib/crap-engine.js +40 -153
  201. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  202. package/.agents/scripts/lib/crap-utils.js +31 -155
  203. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  204. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  205. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  206. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  207. package/.agents/scripts/lib/degraded-mode.js +3 -26
  208. package/.agents/scripts/lib/dependency-parser.js +8 -40
  209. package/.agents/scripts/lib/dependency-version.js +13 -35
  210. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  211. package/.agents/scripts/lib/doc-tiers.js +22 -126
  212. package/.agents/scripts/lib/duplicate-search.js +8 -72
  213. package/.agents/scripts/lib/env-loader.js +5 -27
  214. package/.agents/scripts/lib/error-redactor.js +6 -31
  215. package/.agents/scripts/lib/errors/index.js +2 -22
  216. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  217. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  218. package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
  219. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  220. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
  221. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  222. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  223. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  224. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  225. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  226. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  227. package/.agents/scripts/lib/findings/severity.js +18 -104
  228. package/.agents/scripts/lib/format-generated-json.js +12 -44
  229. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  230. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  231. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  232. package/.agents/scripts/lib/gates/friction.js +1 -3
  233. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  234. package/.agents/scripts/lib/gh-exec.js +31 -259
  235. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  236. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  237. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  238. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  239. package/.agents/scripts/lib/git-utils.js +37 -161
  240. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  241. package/.agents/scripts/lib/github-url.js +2 -17
  242. package/.agents/scripts/lib/import-graph.js +11 -38
  243. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  244. package/.agents/scripts/lib/json-utils.js +3 -18
  245. package/.agents/scripts/lib/label-constants.js +16 -111
  246. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  247. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  248. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  249. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  250. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  251. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  252. package/.agents/scripts/lib/npm-scripts.js +4 -23
  253. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  254. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  255. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  256. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  257. package/.agents/scripts/lib/observability/source-classifier.js +21 -203
  258. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  259. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  260. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  261. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  262. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  263. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  264. package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
  265. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  266. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  267. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  268. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  274. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  275. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  276. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
  277. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  278. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  279. package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
  280. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  281. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  282. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  283. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  284. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  285. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  286. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  287. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  288. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  289. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  290. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  291. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  292. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  293. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  294. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  295. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  308. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  309. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  310. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  311. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  312. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  313. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  314. package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
  315. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  316. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  317. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  318. package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
  319. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  320. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  321. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  322. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  323. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  324. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  325. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
  326. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  327. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  328. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  329. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  330. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  331. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  332. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
  333. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  334. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
  335. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
  336. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
  337. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  338. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  339. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  340. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  341. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  342. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  343. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  344. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  345. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  346. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  347. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  348. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  349. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  350. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  351. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  352. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  353. package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
  354. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  355. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  356. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  357. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  358. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  359. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  360. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  361. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  362. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  363. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  364. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  365. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  366. package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
  367. package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
  368. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  369. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  370. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  371. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  372. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
  373. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  390. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
  391. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  392. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  393. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  394. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  395. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  396. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  397. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  398. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  399. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
  400. package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
  401. package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
  402. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  403. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  404. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
  405. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  406. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  407. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  408. package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
  409. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  410. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
  411. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  412. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  413. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  414. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  415. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  416. package/.agents/scripts/lib/path-security.js +3 -6
  417. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  418. package/.agents/scripts/lib/preflight-runner.js +13 -69
  419. package/.agents/scripts/lib/process-group.js +143 -0
  420. package/.agents/scripts/lib/project-root.js +2 -8
  421. package/.agents/scripts/lib/provider-factory.js +2 -25
  422. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  423. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  424. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  425. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  426. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  427. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  428. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  429. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  430. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  431. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  432. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  433. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  434. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  435. package/.agents/scripts/lib/signals/index.js +2 -19
  436. package/.agents/scripts/lib/signals/schema.js +14 -109
  437. package/.agents/scripts/lib/signals/write.js +2 -11
  438. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  439. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  440. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  441. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  442. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  443. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  444. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  445. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  446. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  447. package/.agents/scripts/lib/source-extensions.js +11 -42
  448. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  449. package/.agents/scripts/lib/stdio-flush.js +9 -36
  450. package/.agents/scripts/lib/story-adjacency.js +8 -40
  451. package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
  452. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  453. package/.agents/scripts/lib/story-body/story-body.js +83 -358
  454. package/.agents/scripts/lib/temp-retention.js +42 -143
  455. package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
  456. package/.agents/scripts/lib/test-env.js +12 -65
  457. package/.agents/scripts/lib/test-run-credit.js +10 -65
  458. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  459. package/.agents/scripts/lib/test-temp.js +38 -184
  460. package/.agents/scripts/lib/test-tiers.js +12 -96
  461. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  462. package/.agents/scripts/lib/transpile.js +15 -74
  463. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  464. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  465. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  466. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  467. package/.agents/scripts/lib/validation-evidence.js +21 -96
  468. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  469. package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
  470. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  471. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  472. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  473. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  474. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  475. package/.agents/scripts/lib/workflow-closure.js +22 -105
  476. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  477. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  478. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  479. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  480. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  481. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  482. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  483. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  484. package/.agents/scripts/lib/worktree-manager.js +15 -40
  485. package/.agents/scripts/lint-issue-body.js +12 -68
  486. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  487. package/.agents/scripts/merge-baseline.js +30 -104
  488. package/.agents/scripts/nav-registry-diff.js +22 -108
  489. package/.agents/scripts/notify.js +12 -69
  490. package/.agents/scripts/plan-context.js +27 -111
  491. package/.agents/scripts/plan-critics.js +12 -66
  492. package/.agents/scripts/plan-persist.js +31 -148
  493. package/.agents/scripts/plan-run-epilogue.js +11 -37
  494. package/.agents/scripts/pr-watch-with-update.js +76 -267
  495. package/.agents/scripts/providers/github/auth.js +3 -8
  496. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  497. package/.agents/scripts/providers/github/board-add.js +5 -21
  498. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  499. package/.agents/scripts/providers/github/cache.js +2 -14
  500. package/.agents/scripts/providers/github/comments.js +7 -40
  501. package/.agents/scripts/providers/github/compose.js +3 -19
  502. package/.agents/scripts/providers/github/errors.js +22 -125
  503. package/.agents/scripts/providers/github/issues.js +31 -123
  504. package/.agents/scripts/providers/github/labels.js +24 -124
  505. package/.agents/scripts/providers/github/mappers.js +5 -27
  506. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  507. package/.agents/scripts/providers/github/project-board.js +2 -17
  508. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  509. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  510. package/.agents/scripts/providers/github/search-budget.js +9 -39
  511. package/.agents/scripts/providers/github/search-query.js +5 -26
  512. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  513. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  514. package/.agents/scripts/providers/github/tickets.js +32 -134
  515. package/.agents/scripts/providers/github.js +18 -59
  516. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  517. package/.agents/scripts/quality-preview.js +35 -220
  518. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  519. package/.agents/scripts/resolve-stories.js +16 -67
  520. package/.agents/scripts/resync-status-column.js +6 -25
  521. package/.agents/scripts/run-tests.js +29 -104
  522. package/.agents/scripts/single-story-close.js +23 -135
  523. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  524. package/.agents/scripts/single-story-init.js +47 -209
  525. package/.agents/scripts/stories-wave-tick.js +102 -472
  526. package/.agents/scripts/sync-agentrc.js +3 -21
  527. package/.agents/scripts/sync-claude-agents.js +9 -55
  528. package/.agents/scripts/sync-claude-commands.js +20 -110
  529. package/.agents/scripts/test-wrapper.js +6 -43
  530. package/.agents/scripts/update-coverage-baseline.js +5 -22
  531. package/.agents/scripts/update-crap-baseline.js +7 -30
  532. package/.agents/scripts/update-duplication-baseline.js +16 -92
  533. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  534. package/.agents/scripts/update-ticket-state.js +1 -7
  535. package/.agents/scripts/validate-skills.js +6 -26
  536. package/.agents/templates/agent-protocol.md +2 -2
  537. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  538. package/.agents/workflows/audit-accessibility.md +4 -7
  539. package/.agents/workflows/audit-adrs.md +3 -6
  540. package/.agents/workflows/audit-architecture.md +3 -11
  541. package/.agents/workflows/audit-baselines.md +6 -9
  542. package/.agents/workflows/audit-clean-code.md +8 -12
  543. package/.agents/workflows/audit-data-model.md +3 -7
  544. package/.agents/workflows/audit-dependencies.md +4 -7
  545. package/.agents/workflows/audit-devops.md +4 -8
  546. package/.agents/workflows/audit-documentation.md +1 -4
  547. package/.agents/workflows/audit-mobile.md +4 -7
  548. package/.agents/workflows/audit-navigability.md +3 -6
  549. package/.agents/workflows/audit-performance.md +2 -4
  550. package/.agents/workflows/audit-privacy.md +4 -7
  551. package/.agents/workflows/audit-quality.md +4 -7
  552. package/.agents/workflows/audit-security.md +4 -7
  553. package/.agents/workflows/audit-seo.md +4 -7
  554. package/.agents/workflows/audit-sre.md +4 -7
  555. package/.agents/workflows/audit-to-stories.md +17 -30
  556. package/.agents/workflows/audit-ux-ui.md +4 -7
  557. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  558. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  559. package/.agents/workflows/helpers/deliver-digest.md +6 -4
  560. package/.agents/workflows/helpers/deliver-reference.md +114 -188
  561. package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
  562. package/.agents/workflows/helpers/plan-reference.md +86 -139
  563. package/.agents/workflows/helpers/qa-core.md +12 -0
  564. package/.agents/workflows/memory-consolidate.md +1 -1
  565. package/.agents/workflows/qa-assist.md +27 -71
  566. package/.agents/workflows/qa-explore.md +19 -59
  567. package/.agents/workflows/qa-run.md +11 -33
  568. package/README.md +1 -1
  569. package/bin/mandrel.js +5 -46
  570. package/bin/postinstall.js +18 -107
  571. package/docs/CHANGELOG.md +25 -0
  572. package/lib/cli/doctor.js +11 -71
  573. package/lib/cli/init.js +26 -165
  574. package/lib/cli/migrate.js +5 -64
  575. package/lib/cli/registry.js +84 -467
  576. package/lib/cli/sync-agents.js +4 -64
  577. package/lib/cli/sync-commands.js +11 -64
  578. package/lib/cli/sync.js +34 -213
  579. package/lib/cli/uninstall.js +40 -219
  580. package/lib/cli/update.js +105 -661
  581. package/lib/cli/version-check.js +8 -72
  582. package/lib/cli/version-helpers.js +14 -87
  583. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  584. package/lib/migrations/index.js +15 -92
  585. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  586. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  587. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  588. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  589. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  590. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  591. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  592. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  593. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
  594. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  595. package/package.json +16 -14
  596. package/.agents/docs/SDLC.md +0 -590
  597. package/.agents/docs/quality-gates.md +0 -1183
  598. package/.agents/rules/known-tooling-behavior.md +0 -200
  599. package/.agents/rules/orchestration-error-handling.md +0 -61
  600. package/.agents/rules/test-seams.md +0 -59
  601. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  602. package/.agents/schemas/baselines/lint.schema.json +0 -47
  603. package/.agents/scripts/check-action-pinning.js +0 -260
  604. package/.agents/scripts/check-audit-attribution.js +0 -302
  605. package/.agents/scripts/check-baseline-drift.js +0 -211
  606. package/.agents/scripts/check-baseline-scope.js +0 -362
  607. package/.agents/scripts/check-generated-validator.js +0 -202
  608. package/.agents/scripts/check-knip-entries.js +0 -159
  609. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  610. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  611. package/.agents/scripts/check-schema-references.js +0 -368
  612. package/.agents/scripts/check-test-portability.js +0 -512
  613. package/.agents/scripts/check-workflow-citations.js +0 -218
  614. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  615. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  616. package/.agents/scripts/install-matrix-assert.js +0 -326
  617. package/.agents/scripts/lib/audit-advisories.js +0 -195
  618. package/.agents/scripts/lib/audit-attribution.js +0 -134
  619. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  620. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  621. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  622. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  623. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  624. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  625. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  626. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  627. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  628. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  629. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  630. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  631. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  632. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  633. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  634. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  635. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  636. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  637. package/.agents/scripts/lib/fs-walk.js +0 -52
  638. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  639. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  640. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  641. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  642. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  643. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  644. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  645. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  646. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  647. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  648. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  649. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  650. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  651. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  652. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  653. package/.agents/scripts/post-structured-comment.js +0 -127
  654. package/.agents/scripts/provision-git-hooks.js +0 -85
  655. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  656. package/.agents/scripts/run-coverage.js +0 -197
  657. package/.agents/scripts/run-lint.js +0 -133
  658. package/.agents/scripts/run-test-profile.js +0 -129
  659. package/.agents/scripts/run-verify.js +0 -125
  660. package/.agents/scripts/test-isolate.js +0 -55
  661. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -1,41 +1,9 @@
1
1
  // .agents/scripts/lib/story-body/story-body.js
2
2
  /**
3
- * Canonical Story-body parser/serializer (Gap 1, Epic #3211).
4
- *
5
- * This module is the single source of truth for the Story body shape.
6
- * Every consumer that reads or writes a structured Story body MUST go
7
- * through these exports — do not inline ad-hoc parsing elsewhere.
8
- *
9
- * ## Structured Story body shape
10
- *
11
- * ```js
12
- * {
13
- * goal: string, // one-sentence purpose
14
- * slicing: string, // v2 intra-Story delivery slice plan (optional; '' when absent)
15
- * spec: string, // folded Tech Spec text block (optional; '' when absent)
16
- * changes: PathEntry[], // files/globs this Story touches
17
- * acceptance: string[], // observable criteria
18
- * verify: string[], // exact commands / tier annotation
19
- * references: PathEntry[], // read-only paths (optional)
20
- * non_goals: string[], // negative-scope bullets (optional, advisory)
21
- * depends_on: string[], // blocker story slugs or #ids
22
- * }
23
- * ```
24
- *
25
- * Where `PathEntry` is:
26
- * - `{ path: string, assumption: "creates"|"refactors-existing"|"exists"|"deletes" }`
27
- * (canonical form — string bullets are rejected at parse time)
28
- *
29
- * ## Round-trip contract
30
- *
31
- * `serialize(parse(markdown)) === markdown` when the input is already
32
- * in the canonical serialized form. Non-canonical whitespace or
33
- * section ordering may produce a normalized (but equivalent) output.
34
- *
35
- * The parser MUST fail closed: a body that cannot be mapped to the
36
- * canonical shape throws `StoryBodyParseError` — it does NOT silently
37
- * coerce malformed input. This prevents a corrupt body from supplying
38
- * wrong `depends_on` edges that reorder the wave DAG.
3
+ * Canonical Story-body parser/serializer — the single source of truth for
4
+ * the Story body shape. The parser fails closed: a body that cannot be mapped
5
+ * to the canonical shape throws, so a corrupt body cannot supply wrong
6
+ * `depends_on` edges. `serialize(parse(md)) === md` for canonical input.
39
7
  *
40
8
  * @module story-body
41
9
  */
@@ -48,10 +16,6 @@ import {
48
16
  } from './body-format-lints.js';
49
17
  import { isFooterSeparator, parseFooterBlockedByRefs } from './footer-block.js';
50
18
 
51
- // ---------------------------------------------------------------------------
52
- // Public types (JSDoc only — no runtime schema file)
53
- // ---------------------------------------------------------------------------
54
-
55
19
  /**
56
20
  * @typedef {'creates'|'refactors-existing'|'exists'|'deletes'} AssumptionEnum
57
21
  */
@@ -66,52 +30,45 @@ import { isFooterSeparator, parseFooterBlockedByRefs } from './footer-block.js';
66
30
 
67
31
  /**
68
32
  * @typedef {object} StoryBody
69
- * @property {string} goal - One-sentence purpose statement.
70
- * @property {string} slicing - Optional v2 intra-Story delivery slice plan text block; '' when absent.
71
- * @property {string} spec - Optional folded Tech Spec text block; '' when absent.
72
- * @property {PathEntry[]} changes - Files / globs this Story modifies.
73
- * @property {string[]} acceptance - Observable acceptance criteria.
74
- * @property {string[]} verify - Exact commands the deliverer runs.
75
- * @property {PathEntry[]} references - Read-only paths (may be empty).
76
- * @property {string[]} non_goals - Negative-scope bullets (advisory; may be empty).
33
+ * @property {string} goal
34
+ * @property {string} slicing - Intra-Story slice plan; '' when absent.
35
+ * @property {string} spec - Folded Tech Spec; '' when absent.
36
+ * @property {PathEntry[]} changes
37
+ * @property {string[]} acceptance
38
+ * @property {string[]} verify
39
+ * @property {PathEntry[]} references - Read-only paths.
40
+ * @property {string[]} non_goals - Advisory negative scope.
77
41
  * @property {string[]} depends_on - Blocking story slugs / issue refs.
78
42
  */
79
43
 
80
44
  /**
81
45
  * @typedef {object} ParseResult
82
- * @property {StoryBody} body - The parsed structured body.
83
- * @property {string[]} warnings - Non-fatal issues (e.g. unstructured-body).
84
- * @property {ParseInfo} info - Metadata about the parse.
46
+ * @property {StoryBody} body
47
+ * @property {string[]} warnings
48
+ * @property {ParseInfo} info
85
49
  */
86
50
 
87
51
  /**
88
52
  * @typedef {object} ParseInfo
89
- * @property {boolean} hasGoalSection - Whether a `## Goal` section was found.
90
- * @property {boolean} hasChangesSection - Whether a `## Changes` section was found.
91
- * @property {boolean} hasAcceptanceSection - Whether a `## Acceptance` section was found.
92
- * @property {boolean} hasVerifySection - Whether a `## Verify` section was found.
93
- * @property {boolean} hasReferencesSection - Whether a `## References` section was found.
94
- * @property {boolean} hasNonGoalsSection - Whether a `## Non-Goals` section was found.
95
- * @property {boolean} hasSlicingSection - Whether a `## Slicing` section was found (v2 folded slice plan).
96
- * @property {boolean} hasSpecSection - Whether a `## Spec` section was found (folded Tech Spec).
53
+ * @property {boolean} hasGoalSection
54
+ * @property {boolean} hasChangesSection
55
+ * @property {boolean} hasAcceptanceSection
56
+ * @property {boolean} hasVerifySection
57
+ * @property {boolean} hasReferencesSection
58
+ * @property {boolean} hasNonGoalsSection
59
+ * @property {boolean} hasSlicingSection
60
+ * @property {boolean} hasSpecSection
97
61
  * @property {boolean} isUnstructuredBody - True when no structured sections were found.
98
62
  */
99
63
 
100
64
  /**
101
65
  * @typedef {object} SerializeOptions
102
66
  * @property {boolean} [includeFooter=false] - Include `---\nparent/blocked-by` footer.
103
- * @property {object} [footer] - Footer fields when `includeFooter` is true.
104
- * @property {number} [footer.parent] - Parent feature issue number.
67
+ * @property {object} [footer]
68
+ * @property {number} [footer.parent]
105
69
  */
106
70
 
107
- // ---------------------------------------------------------------------------
108
- // Error class
109
- // ---------------------------------------------------------------------------
110
-
111
- /**
112
- * Thrown when the Story body cannot be parsed into the canonical shape.
113
- * The parser fails closed — do not catch this to silently continue.
114
- */
71
+ /** Thrown when a Story body cannot be parsed; never catch to continue. */
115
72
  export class StoryBodyParseError extends Error {
116
73
  /**
117
74
  * @param {string} message
@@ -125,13 +82,7 @@ export class StoryBodyParseError extends Error {
125
82
  }
126
83
  }
127
84
 
128
- // ---------------------------------------------------------------------------
129
- // Section heading map
130
- // ---------------------------------------------------------------------------
131
-
132
- // Heading text → body field name. Keys are normalized: lower-cased with `-`
133
- // folded to `_` (see splitSections), so the hyphenated `## Non-Goals` heading
134
- // maps to the `non_goals` field.
85
+ // Keys are lower-cased with `-` folded to `_` (see splitSections).
135
86
  const HEADING_TO_FIELD = new Map([
136
87
  ['goal', 'goal'],
137
88
  ['slicing', 'slicing'],
@@ -144,14 +95,7 @@ const HEADING_TO_FIELD = new Map([
144
95
  ]);
145
96
  const TEXT_BLOCK_FIELDS = new Set(['slicing', 'spec']);
146
97
 
147
- // ---------------------------------------------------------------------------
148
- // Helpers
149
- // ---------------------------------------------------------------------------
150
-
151
98
  /**
152
- * Strip leading `- ` or `- [ ] ` from a markdown list item, returning the
153
- * raw content.
154
- *
155
99
  * @param {string} line
156
100
  * @returns {string}
157
101
  */
@@ -159,66 +103,30 @@ function stripListMarker(line) {
159
103
  return line.replace(/^-\s+(?:\[\s*[xX ]?\s*\]\s+)?/, '').trim();
160
104
  }
161
105
 
162
- // Humanized PathEntry bullet (Story #4600): `path` — assumption. This is the
163
- // shape serialize() now emits for `## Changes` / `## References`; the legacy
164
- // inline-JSON object bullet remains accepted at parse time indefinitely (live
165
- // issue bodies are never rewritten).
106
+ // `path` — assumption: the shape serialize() emits. The inline-JSON bullet is
107
+ // still accepted at parse time because live issue bodies are never rewritten.
166
108
  const HUMANIZED_PATH_ENTRY_RE = /^`([^`]+)`\s+—\s+(\S+)$/;
167
109
 
168
- // Bare path bullet (Story #5342): `src/app.js` or `` `src/app.js` `` with no
169
- // assumption. The assumption is a fact about the base branch, not a thing the
170
- // author knows better than a probe does, so the default authored form omits
171
- // it and persist derives it. The grammar itself — a single whitespace-free
172
- // token, so prose bullets do not match and are still rejected — is
173
- // `body-format-lints.js#matchBarePathToken`, the one definition the persist
174
- // repair pass scores against too (Story #5361).
175
-
176
- // AC-<n> presentation prefix on acceptance checkboxes (Story #4600). The
177
- // numbering is a stable 1-based human handle only — parse() strips it so the
178
- // top-level acceptance[] machine contract round-trips byte-identical.
179
- //
180
- // The lettered form (`AC-14a:`) is accepted too (Story #5323). Nothing emits
181
- // one — `serialize()` numbers from the array index — but a Story planned from
182
- // an existing ticket can copy one out of the source issue's rendered
183
- // checkboxes, and a body that already carries one must still parse to the
184
- // handle-free text or the round-trip invariant breaks for it alone. Trailing
185
- // whitespace is optional so `AC-3:text` normalises as readily as `AC-3: text`.
110
+ // Presentation-only `AC-<n>:` handle (lettered `AC-14a:` too, copied from
111
+ // source tickets); parse() strips it so acceptance[] round-trips.
186
112
  const AC_PREFIX_RE = /^AC-\d+[a-z]?:\s*/i;
187
113
 
188
- // Machine-managed marker lines a body authored before Story #5312 may still
189
- // carry: the `> **Wide:** <reason>` rationale line (Story #4600), the
190
- // `> 🏷️ Authored with Mandrel …` provenance line, and the trailing
191
- // `<!-- meta: {...} -->` block. Nothing writes them any more — the `wide` /
192
- // `reason_to_exist` fields and the provenance stamp went with the plan-time
193
- // sizing model — but live issue bodies are never rewritten, so the parser
194
- // still skips them wherever they appear rather than absorbing a stray line
195
- // into the last structured section. A skipped block is dropped on
196
- // re-serialize, which is the cutover working as intended.
114
+ // Retired machine-managed marker lines nothing writes any more. Live bodies
115
+ // still carry them, so the parser skips them rather than absorbing them into
116
+ // the last section; they are dropped on re-serialize.
197
117
  const WIDE_MARKER_LINE_RE = /^>\s*\*\*Wide:\*\*/;
198
118
  const AUTHORED_MARKER_LINE_RE = /^\s*>\s*🏷️\s+Authored with Mandrel\b/;
199
119
  const META_BLOCK_RE = /<!--\s*meta:[\s\S]*?-->/;
200
120
 
201
121
  /**
202
- * Parse a single `changes` / `references` bullet into a `PathEntry`.
203
- *
204
- * Accepted markdown shapes (all parsed indefinitely — live issue bodies
205
- * are never rewritten):
206
- * - Bare path (the default authored form since Story #5342):
207
- * `` `src/x.js` `` or `src/x.js`, parsed with `assumption: null`
208
- * - Humanized bullet (canonical serialize() output since Story #4600):
209
- * `` `src/x.js` — refactors-existing ``
210
- * - Legacy inline-JSON object bullet:
211
- * `- { "path": "...", "assumption": "..." }`
212
- *
213
- * A structured object entry (from a parsed JSON body that was never
214
- * serialized to markdown) arrives as-is and is validated directly.
122
+ * Parse one `changes` / `references` bullet: bare path (`assumption: null`),
123
+ * humanized `` `path` — assumption ``, or inline-JSON object.
215
124
  *
216
125
  * @param {string|object} raw
217
126
  * @param {string[]} warnings
218
127
  * @returns {PathEntry}
219
128
  */
220
129
  function parsePathEntry(raw, warnings) {
221
- // Already a structured object (from a parsed JSON body, not markdown).
222
130
  if (raw !== null && typeof raw === 'object') {
223
131
  return pathEntryFromObject(raw);
224
132
  }
@@ -232,17 +140,9 @@ function parsePathEntry(raw, warnings) {
232
140
  }
233
141
 
234
142
  /**
235
- * Parse the bare path bullet — the default authored form since Story #5342 —
236
- * or refuse the bullet. This is the last shape `parsePathEntry` tries, so it
237
- * owns the rejection too.
238
- *
239
- * `assumption: null` records only what the author said; persist derives the
240
- * rest by probing the base branch. A `{`-leading string reached here because
241
- * it failed to parse as the inline JSON object it announced itself as, so it
242
- * is malformed JSON rather than a path and keeps failing closed.
243
- *
244
- * Story #5361: the two failures need different fixes, so they get different
245
- * refusals — rewrite a sentence as a path, versus fix a token that is not one.
143
+ * Last shape tried, so it owns the rejection. A `{`-leading string here is
144
+ * malformed JSON, not a path. Prose and non-path tokens get distinct refusals
145
+ * because they need different fixes.
246
146
  *
247
147
  * @param {string} str
248
148
  * @returns {PathEntry}
@@ -263,16 +163,8 @@ function pathEntryFromBare(str) {
263
163
  }
264
164
 
265
165
  /**
266
- * Read the assumption a raw entry declares, collapsing the three cases the
267
- * parser has to tell apart into one value:
268
- *
269
- * - a canonical `FILE_ASSUMPTION_VALUES` member — the author pinned one;
270
- * - `null` — the author named no assumption at all. Since Story #5342 that
271
- * is the **bare form**, and persist derives the value by probing the base
272
- * branch rather than the author guessing it;
273
- * - `undefined` — the author named something that is not an assumption.
274
- * Distinct from absent on purpose: a typo must fail closed where an
275
- * omission is the default shape.
166
+ * A canonical value (pinned), `null` (omitted — persist derives it), or
167
+ * `undefined` (not an assumption — a typo must fail closed).
276
168
  *
277
169
  * @param {unknown} raw
278
170
  * @returns {string|null|undefined}
@@ -283,9 +175,6 @@ function readAssumption(raw) {
283
175
  }
284
176
 
285
177
  /**
286
- * Validate an already-structured `{ path, assumption }` object. Fails closed
287
- * on a malformed object.
288
- *
289
178
  * @param {object} raw
290
179
  * @returns {PathEntry}
291
180
  */
@@ -295,7 +184,6 @@ function pathEntryFromObject(raw) {
295
184
  if (path !== '' && assumption !== undefined) {
296
185
  return { path, assumption };
297
186
  }
298
- // Malformed object: fail closed.
299
187
  throw new StoryBodyParseError(
300
188
  `changes/references entry is an object but not a valid PathEntry: ${JSON.stringify(raw)}`,
301
189
  { field: 'changes', raw: JSON.stringify(raw) },
@@ -303,10 +191,7 @@ function pathEntryFromObject(raw) {
303
191
  }
304
192
 
305
193
  /**
306
- * Parse the humanized bullet shape (the canonical serialize() output since
307
- * Story #4600): `` `path` — assumption ``. Returns `null` when the line is
308
- * not that shape at all; fails closed when the shape is recognized but the
309
- * fields are invalid.
194
+ * `null` when not the humanized shape; throws when recognized but invalid.
310
195
  *
311
196
  * @param {string} str
312
197
  * @returns {PathEntry|null}
@@ -318,7 +203,6 @@ function pathEntryFromHumanized(str) {
318
203
  if (path.length > 0 && FILE_ASSUMPTION_VALUES.includes(humanized[2])) {
319
204
  return { path, assumption: humanized[2] };
320
205
  }
321
- // Recognized the humanized shape but the fields are invalid: fail closed.
322
206
  throw new StoryBodyParseError(
323
207
  `changes/references entry is a humanized bullet but not a valid PathEntry: ${str.slice(0, 120)}${pathEntryFixIt(str)}`,
324
208
  { field: 'changes', raw: str },
@@ -326,12 +210,7 @@ function pathEntryFromHumanized(str) {
326
210
  }
327
211
 
328
212
  /**
329
- * Parse the legacy inline-JSON object bullet:
330
- * `{ "path": "...", "assumption": "..." }`. Returns `null` when the line is
331
- * not a JSON object at all (including a JSON parse failure — the caller then
332
- * tries the bare-path form and finally rejects the bullet); delegates the
333
- * field check to {@link pathEntryFromObject}, which is the same judgment on
334
- * the same shape and fails closed the same way.
213
+ * `null` when not a JSON object (the caller then tries the bare form).
335
214
  *
336
215
  * @param {string} str
337
216
  * @returns {PathEntry|null}
@@ -342,7 +221,6 @@ function pathEntryFromInlineJson(str) {
342
221
  try {
343
222
  parsed = JSON.parse(str);
344
223
  } catch {
345
- // JSON parse failed — the caller falls through to the bare-path form.
346
224
  return null;
347
225
  }
348
226
  return parsed !== null && typeof parsed === 'object'
@@ -351,10 +229,8 @@ function pathEntryFromInlineJson(str) {
351
229
  }
352
230
 
353
231
  /**
354
- * Build the ` Suggested fix: …` suffix for a rejected changes/references
355
- * bullet, when a `{ path, assumption }` object can be salvaged from it. Returns
356
- * an empty string when nothing is inferable, so callers can append it
357
- * unconditionally (Story #4684 — mechanical auto-fix in the failure output).
232
+ * ` Suggested fix: …` suffix for a rejected bullet, or '' when nothing is
233
+ * inferable.
358
234
  *
359
235
  * @param {string} raw The rejected bullet text.
360
236
  * @returns {string}
@@ -366,11 +242,7 @@ function pathEntryFixIt(raw) {
366
242
  }
367
243
 
368
244
  /**
369
- * Extract the `blocked by #N` lines from the footer block (text after
370
- * the last `---` separator). Returns an array of "#N" strings.
371
- *
372
- * Delegates to `./footer-block.js`, which owns the footer-block grammar
373
- * (Story #5046) so the body parser and the dispatch-edge parser cannot
245
+ * Delegates to footer-block.js so the body and dispatch-edge parsers cannot
374
246
  * disagree about what declares an edge.
375
247
  *
376
248
  * @param {string} footerBlock
@@ -381,15 +253,8 @@ function extractBlockedBy(footerBlock) {
381
253
  }
382
254
 
383
255
  /**
384
- * Split markdown into named sections plus a footer block.
385
- *
386
- * Returns `{ sections: Map<string, string[]>, footer: string }`.
387
- * Each map value is the raw non-empty content lines under that heading
388
- * (heading line stripped).
389
- *
390
- * A `---` followed by recognised footer keys (`parent:`, `Epic:`,
391
- * `blocked by`) marks the start of the footer block. Content after the
392
- * footer separator is NOT parsed as sections.
256
+ * Split markdown into named sections plus the footer block; content after
257
+ * the footer separator is not parsed as sections.
393
258
  *
394
259
  * @param {string} markdown
395
260
  * @returns {{ sections: Map<string, string[]>, footer: string, preamble: string }}
@@ -410,20 +275,9 @@ function splitSections(markdown) {
410
275
  break;
411
276
  }
412
277
 
413
- // Detect `## Heading` (canonical) or `### Heading` lines. GitHub Issue
414
- // Forms (Story #4227) render every field label as a level-3 heading
415
- // (`### Goal`), not the level-2 the canonical serializer emits, so the
416
- // parser accepts both levels. Any other heading depth is ignored.
417
- //
418
- // The token class is `[\w-]+` (not bare `\w+`) so a single hyphenated
419
- // heading word — the canonical `## Non-Goals` negative-scope section —
420
- // matches as one token. The captured name is normalized (lower-cased,
421
- // `-` folded to `_`) before the HEADING_TO_FIELD lookup, so `Non-Goals`
422
- // resolves to the `non_goals` field. Multi-word headings that contain a
423
- // space (`## Out of Scope`, `## Agent Prompts`) still do NOT match this
424
- // single-token shape — they fall through to the section-terminator branch
425
- // below, which closes the open section. The chosen canonical spelling is
426
- // therefore the hyphenated single token `## Non-Goals`.
278
+ // `##` or `###` (GitHub Issue Forms render labels as level 3). The token
279
+ // is a single `[\w-]+` word so `Non-Goals` matches; multi-word headings
280
+ // fall through to the terminator branch below.
427
281
  const fieldHeadingMatch = line.match(/^#{2,3}\s+([\w-]+)\s*$/i);
428
282
  const fieldName = fieldHeadingMatch?.[1]?.toLowerCase().replace(/-/g, '_');
429
283
  if (HEADING_TO_FIELD.has(fieldName)) {
@@ -454,14 +308,9 @@ function splitSections(markdown) {
454
308
  }
455
309
 
456
310
  /**
457
- * True for a non-canonical markdown heading that TERMINATES the current
458
- * structured section. Trailing extended content a producer appends after the
459
- * canonical block — `audit-to-stories`'s `## Agent Prompts` / `## Context`
460
- * / `## Sequencing` blocks, for instance — must not bleed into the last
461
- * structured section's bullet list (Story #4270). Without this, those
462
- * lines were silently absorbed into `verify[]` / `acceptance[]`. The
463
- * heading and everything under it is dropped from structured parsing
464
- * (it is extended, non-canonical markdown).
311
+ * A non-canonical heading closes the current section so appended extended
312
+ * content (e.g. `## Agent Prompts`) never bleeds into `verify[]` /
313
+ * `acceptance[]`. Text-block sections keep their own headings.
465
314
  *
466
315
  * @param {string} line
467
316
  * @param {boolean} inPreamble
@@ -477,11 +326,6 @@ function isSectionTerminatorHeading(line, inPreamble, currentSection) {
477
326
  }
478
327
 
479
328
  /**
480
- * True for the legacy machine-managed marker lines section parsing skips
481
- * wherever they appear (see the regexes above): a `## References` section
482
- * immediately followed by a retired meta block must not swallow the comment
483
- * as a references entry.
484
- *
485
329
  * @param {string} line
486
330
  * @returns {boolean}
487
331
  */
@@ -493,19 +337,13 @@ function isMachineMarkerLine(line) {
493
337
  );
494
338
  }
495
339
 
496
- // ---------------------------------------------------------------------------
497
- // Parser — per-section sub-parsers
498
- // ---------------------------------------------------------------------------
499
-
500
340
  /**
501
- * Build the minimal {@link ParseResult} returned for an unstructured body —
502
- * markdown that carries no recognised structured section. The goal falls
503
- * back to the preamble text (or the whole trimmed input), `depends_on` is
504
- * still recovered from the footer, and all section arrays are empty.
341
+ * Minimal result for a body with no structured section: goal falls back to
342
+ * the preamble, `depends_on` is still read from the footer.
505
343
  *
506
- * @param {string} input - The original markdown string.
507
- * @param {string} preamble - Text before the first heading (from splitSections).
508
- * @param {string} footer - Footer block text (from splitSections).
344
+ * @param {string} input
345
+ * @param {string} preamble
346
+ * @param {string} footer
509
347
  * @returns {ParseResult}
510
348
  */
511
349
  function parseUnstructuredBody(input, preamble, footer) {
@@ -541,10 +379,7 @@ function parseUnstructuredBody(input, preamble, footer) {
541
379
  }
542
380
 
543
381
  /**
544
- * Parse the `## Goal` section: join its non-empty content lines into a
545
- * single one-line goal string.
546
- *
547
- * @param {string[]} lines - Raw content lines under the heading.
382
+ * @param {string[]} lines
548
383
  * @returns {string}
549
384
  */
550
385
  function parseGoalSection(lines) {
@@ -555,10 +390,8 @@ function parseGoalSection(lines) {
555
390
  }
556
391
 
557
392
  /**
558
- * Parse a verbatim text-block section (`## Slicing` or `## Spec`) into a
559
- * newline-joined string. Unlike {@link parseGoalSection}, line breaks are
560
- * preserved so a bullet list, compact table, or folded Tech Spec survives the
561
- * round-trip; only blank lines and trailing whitespace are normalized.
393
+ * Line breaks are preserved so lists and tables round-trip; only blank edge
394
+ * lines and trailing whitespace are normalized.
562
395
  *
563
396
  * @param {string[]} lines
564
397
  * @returns {string}
@@ -571,12 +404,8 @@ function parseTextBlockSection(lines) {
571
404
  }
572
405
 
573
406
  /**
574
- * Parse a `## Changes` / `## References` section into a list of
575
- * `PathEntry` entries. List markers are stripped, blank entries are
576
- * dropped, and each surviving entry is normalized via {@link parsePathEntry}.
577
- *
578
- * @param {string[]} lines - Raw content lines under the heading.
579
- * @param {string[]} warnings - Mutable warnings sink.
407
+ * @param {string[]} lines
408
+ * @param {string[]} warnings
580
409
  * @returns {PathEntry[]}
581
410
  */
582
411
  function parsePathEntrySection(lines, warnings) {
@@ -591,46 +420,17 @@ function parsePathEntrySection(lines, warnings) {
591
420
  }
592
421
 
593
422
  /**
594
- * Parse a plain bullet-list section (`## Acceptance` / `## Verify`) into a
595
- * list of trimmed strings, dropping blank entries.
596
- *
597
- * @param {string[]} lines - Raw content lines under the heading.
423
+ * @param {string[]} lines
598
424
  * @returns {string[]}
599
425
  */
600
426
  function parseTextListSection(lines) {
601
427
  return lines.map((l) => stripListMarker(l)).filter(Boolean);
602
428
  }
603
429
 
604
- // ---------------------------------------------------------------------------
605
- // Parser
606
- // ---------------------------------------------------------------------------
607
-
608
- /**
609
- * Parse a GitHub Story issue body (markdown string) into a structured
610
- * {@link StoryBody}. Fails closed on malformed input.
611
- *
612
- * Returns a {@link ParseResult} containing the body, any non-fatal
613
- * warnings, and parse metadata. Use `result.body` directly; inspect
614
- * `result.warnings` to detect legacy path entries that should be
615
- * migrated.
616
- *
617
- * @param {string|object} input - Markdown string or already-structured body object.
618
- * @returns {ParseResult}
619
- * @throws {StoryBodyParseError} When the body is structurally unrecoverable.
620
- */
621
430
  /**
622
- * Strip the presentation `AC-<n>:` handle off one acceptance item.
623
- *
624
- * The handle belongs to {@link serialize}, which numbers every checkbox from
625
- * its position in `acceptance[]`; an authored item that already carries one
626
- * would render doubled (`- [ ] AC-1: AC-1: …`) and a lettered handle copied
627
- * from a source ticket would survive into the machine contract. Both parse
628
- * and the persist-side normalisation resolve the grammar here so the two can
629
- * never disagree about what a handle is (Story #5323).
630
- *
631
- * Stacked handles are peeled in full — a body persisted while the doubling
632
- * was live carries two, and leaving the inner one would normalise to
633
- * something that still is not the authored text.
431
+ * Strip every stacked `AC-<n>:` handle. serialize() numbers checkboxes from
432
+ * position, so a kept handle would render doubled; parse and persist share
433
+ * this so they agree on the grammar.
634
434
  *
635
435
  * @param {string} item
636
436
  * @returns {{ text: string, stripped: boolean }} The handle-free text, and
@@ -645,6 +445,13 @@ export function stripAcceptanceHandle(item) {
645
445
  return { text, stripped: text !== original };
646
446
  }
647
447
 
448
+ /**
449
+ * Parse a Story issue body (markdown or structured object).
450
+ *
451
+ * @param {string|object} input - Markdown string or already-structured body object.
452
+ * @returns {ParseResult}
453
+ * @throws {StoryBodyParseError} When the body is structurally unrecoverable.
454
+ */
648
455
  export function parse(input) {
649
456
  if (input === null || input === undefined) {
650
457
  throw new StoryBodyParseError('Story body is null or undefined', {
@@ -652,8 +459,6 @@ export function parse(input) {
652
459
  });
653
460
  }
654
461
 
655
- // If the caller already has a structured object (e.g. from the decomposer
656
- // before it's serialized to markdown), parse it directly.
657
462
  if (typeof input === 'object' && !Array.isArray(input)) {
658
463
  return parseStructuredObject(input);
659
464
  }
@@ -677,7 +482,6 @@ export function parse(input) {
677
482
  const hasSlicingSection = sections.has('slicing');
678
483
  const hasSpecSection = sections.has('spec');
679
484
 
680
- // If no structured sections found, treat as unstructured body.
681
485
  const isUnstructuredBody =
682
486
  !hasGoalSection &&
683
487
  !hasChangesSection &&
@@ -689,19 +493,12 @@ export function parse(input) {
689
493
  }
690
494
 
691
495
  const goal = parseGoalSection(sections.get('goal') ?? []);
692
- // Optional v2 intra-Story delivery slice plan (`## Slicing`). Preserved as
693
- // a verbatim text block — a large Story (what v1 called an Epic) folds its
694
- // Delivery Slicing here instead of fanning out into sibling Stories; a
695
- // trivial Story omits it entirely. Parsed as a text block so a bullet list
696
- // or compact table round-trips.
697
496
  const slicing = parseTextBlockSection(sections.get('slicing') ?? []);
698
497
  const spec = parseTextBlockSection(sections.get('spec') ?? []);
699
498
  const changes = parsePathEntrySection(
700
499
  sections.get('changes') ?? [],
701
500
  warnings,
702
501
  );
703
- // The AC-<n> checkbox prefix is presentation-only (Story #4600): strip it
704
- // so acceptance[] round-trips byte-identical to the authored array.
705
502
  const acceptance = parseTextListSection(sections.get('acceptance') ?? []).map(
706
503
  (a) => stripAcceptanceHandle(a).text,
707
504
  );
@@ -743,9 +540,7 @@ export function parse(input) {
743
540
  }
744
541
 
745
542
  /**
746
- * Parse a structured body object (as produced by the decomposer's JSON
747
- * output, before markdown serialization). Normalizes all fields to the
748
- * canonical shape.
543
+ * Normalize a structured body object (pre-serialization decomposer output).
749
544
  *
750
545
  * @param {object} obj
751
546
  * @returns {ParseResult}
@@ -753,10 +548,6 @@ export function parse(input) {
753
548
  function parseStructuredObject(obj) {
754
549
  const warnings = [];
755
550
 
756
- // The declarative half of the normalization: every field whose value is a
757
- // pure function of its raw input (plus the shared warnings sink) is one
758
- // table row, walked in canonical body-key order. Adding a field of an
759
- // existing kind is a one-row change.
760
551
  const body = {};
761
552
  for (const { name, kind } of STRUCTURED_FIELD_SPECS) {
762
553
  body[name] = STRUCTURED_FIELD_NORMALIZERS[kind](obj[name], warnings);
@@ -780,36 +571,23 @@ function parseStructuredObject(obj) {
780
571
  }
781
572
 
782
573
  /**
783
- * The field-spec table driving {@link parseStructuredObject}, in canonical
784
- * body-key order. `kind` selects the normalizer from
785
- * {@link STRUCTURED_FIELD_NORMALIZERS}:
786
- * - `text` — trimmed string, or `''` when absent/non-string.
787
- * - `stringList` — array filtered to non-empty strings, else `[]`.
788
- * - `pathEntryList` — array normalized entry-wise via `parsePathEntry`
789
- * (fails closed on a malformed entry), else `[]`.
574
+ * Field specs in canonical body-key order.
790
575
  *
791
576
  * @type {Array<{ name: string, kind: keyof typeof STRUCTURED_FIELD_NORMALIZERS }>}
792
577
  */
793
578
  const STRUCTURED_FIELD_SPECS = [
794
579
  { name: 'goal', kind: 'text' },
795
- // slicing — optional v2 intra-Story delivery slice plan (verbatim text).
796
580
  { name: 'slicing', kind: 'text' },
797
- // spec — optional folded Tech Spec (verbatim text).
798
581
  { name: 'spec', kind: 'text' },
799
582
  { name: 'changes', kind: 'pathEntryList' },
800
583
  { name: 'acceptance', kind: 'stringList' },
801
584
  { name: 'verify', kind: 'stringList' },
802
585
  { name: 'references', kind: 'pathEntryList' },
803
- // non_goals — advisory negative-scope bullets.
804
586
  { name: 'non_goals', kind: 'stringList' },
805
- // depends_on — may be at top level or in body.
806
587
  { name: 'depends_on', kind: 'stringList' },
807
588
  ];
808
589
 
809
590
  /**
810
- * One normalizer per {@link STRUCTURED_FIELD_SPECS} kind. Each takes the raw
811
- * field value plus the shared warnings sink and returns the canonical value.
812
- *
813
591
  * @type {Record<string, (raw: unknown, warnings: string[]) => unknown>}
814
592
  */
815
593
  const STRUCTURED_FIELD_NORMALIZERS = {
@@ -828,37 +606,19 @@ const STRUCTURED_FIELD_NORMALIZERS = {
828
606
  },
829
607
  };
830
608
 
831
- // ---------------------------------------------------------------------------
832
- // Serializer
833
- // ---------------------------------------------------------------------------
834
-
835
609
  /**
836
- * Render a `PathEntry | string` as a markdown list item.
837
- *
838
610
  * @param {PathEntry | string} entry
839
611
  * @returns {string}
840
612
  */
841
613
  function serializePathEntry(entry) {
842
614
  if (typeof entry === 'string') return entry;
843
- // Canonical object form (Story #4600): a human-readable bullet — path in
844
- // backticks, em-dash, assumption. parsePathEntry recognizes this shape (and
845
- // the legacy inline-JSON one) for round-trip fidelity. Story #5342: a bare
846
- // entry — a path the author wrote with no assumption — serializes back bare
847
- // rather than silently acquiring a derivation they never made; persist
848
- // fills it in by probing base before it writes a body.
615
+ // A bare entry (no assumption) stays bare; persist derives the assumption.
849
616
  return [`\`${entry.path}\``, entry.assumption].filter(Boolean).join(' — ');
850
617
  }
851
618
 
852
619
  /**
853
- * Descriptor table for the human-readable Story-body sections, in canonical
854
- * emit order (`## Goal`, `## Slicing`, `## Spec`, `## Changes`,
855
- * `## Acceptance`, `## Verify`, `## References`, `## Non-Goals`). Each
856
- * descriptor reads one body field and returns the section's markdown block
857
- * when the field is present and non-empty, or `null` to omit the section.
858
- *
859
- * Standardising the section ladder as a single data table makes adding a new
860
- * optional section a one-line edit here rather than a new control-flow branch
861
- * in {@link serialize}.
620
+ * Sections in canonical emit order; `render` returns `null` to omit, so an
621
+ * absent optional field keeps older bodies round-tripping byte-identically.
862
622
  *
863
623
  * @type {Array<{ field: string, render: (value: unknown) => string | null }>}
864
624
  */
@@ -871,10 +631,6 @@ const SERIALIZE_SECTIONS = [
871
631
  : null,
872
632
  },
873
633
  {
874
- // Optional v2 intra-Story delivery slice plan. Single-token `## Slicing`
875
- // heading (recognized by the `[\w-]+` field-heading regex). Verbatim text
876
- // block. Render-when-non-empty: an absent/empty `slicing` emits nothing,
877
- // so every pre-v2 body round-trips byte-identically.
878
634
  field: 'slicing',
879
635
  render: (slicing) =>
880
636
  typeof slicing === 'string' && slicing.trim().length > 0
@@ -882,8 +638,6 @@ const SERIALIZE_SECTIONS = [
882
638
  : null,
883
639
  },
884
640
  {
885
- // Optional folded Tech Spec. Like `## Slicing`, this is a verbatim text
886
- // block and emits nothing for absent/empty pre-v2 bodies.
887
641
  field: 'spec',
888
642
  render: (spec) =>
889
643
  typeof spec === 'string' && spec.trim().length > 0
@@ -898,10 +652,6 @@ const SERIALIZE_SECTIONS = [
898
652
  : null,
899
653
  },
900
654
  {
901
- // Each checkbox carries a stable 1-based `AC-<n>:` handle (Story #4600)
902
- // so humans and reviewers can reference criteria by number. The prefix
903
- // is presentation-only — parse() strips it, and validators compare the
904
- // top-level acceptance[] array, so numbering never affects gating.
905
655
  field: 'acceptance',
906
656
  render: (acceptance) =>
907
657
  Array.isArray(acceptance) && acceptance.length > 0
@@ -923,11 +673,6 @@ const SERIALIZE_SECTIONS = [
923
673
  : null,
924
674
  },
925
675
  {
926
- // Advisory negative-scope bullets. Rendered as the hyphenated canonical
927
- // `## Non-Goals` heading (the spelling the parser's widened
928
- // `[\w-]+` field-heading regex recognizes). Render-when-non-empty: an
929
- // empty or absent `non_goals` emits nothing, so every pre-existing body
930
- // round-trips byte-identically.
931
676
  field: 'non_goals',
932
677
  render: (nonGoals) =>
933
678
  Array.isArray(nonGoals) && nonGoals.length > 0
@@ -937,9 +682,6 @@ const SERIALIZE_SECTIONS = [
937
682
  ];
938
683
 
939
684
  /**
940
- * Build the optional `---` footer block (`parent` / `blocked by` lines).
941
- * Returns the empty string when `opts.includeFooter` is falsy.
942
- *
943
685
  * @param {StoryBody} body
944
686
  * @param {SerializeOptions} opts
945
687
  * @returns {string}
@@ -948,9 +690,7 @@ function serializeFooter(body, opts) {
948
690
  if (!opts.includeFooter) return '';
949
691
  const footerLines = ['---'];
950
692
  if (opts.footer?.parent) footerLines.push(`parent: #${opts.footer.parent}`);
951
- // Story #4545 — no `Epic: #N` branch. `pr-base-guard.js` hard-refuses a
952
- // Story body carrying that footer, so composing one here would let the
953
- // framework generate work it would then reject at delivery.
693
+ // Never an `Epic: #N` line: pr-base-guard.js refuses a body carrying one.
954
694
  if (Array.isArray(body.depends_on)) {
955
695
  for (const dep of body.depends_on) {
956
696
  footerLines.push(`blocked by ${dep}`);
@@ -960,13 +700,6 @@ function serializeFooter(body, opts) {
960
700
  }
961
701
 
962
702
  /**
963
- * Serialize a structured {@link StoryBody} back to the canonical markdown
964
- * format written to GitHub issue bodies.
965
- *
966
- * The output matches the section order the spec-renderer uses:
967
- * `## Goal`, `## Slicing`, `## Spec`, `## Changes`, `## Acceptance`,
968
- * `## Verify`, `## References`, `## Non-Goals` (each omitted when empty).
969
- *
970
703
  * @param {StoryBody} body
971
704
  * @param {SerializeOptions} [opts]
972
705
  * @returns {string}
@@ -987,17 +720,9 @@ export function serialize(body, opts = {}) {
987
720
  return sections.join('\n\n') + serializeFooter(body, opts);
988
721
  }
989
722
 
990
- // ---------------------------------------------------------------------------
991
- // Convenience: extract changes paths for the wave planner
992
- // ---------------------------------------------------------------------------
993
-
994
723
  /**
995
- * Extract the list of path strings from a parsed `changes[]` array.
996
- * Glob-bearing entries are flagged via `{ path, isGlob: true }`.
997
- *
998
- * The wave planner (Feature 3) uses this to compute file-overlap
999
- * serialization between Stories: if any entry `isGlob`, the Story's
1000
- * footprint is `unknown-width`.
724
+ * Path strings from `changes[]`; any glob entry makes the footprint
725
+ * unknown-width for the wave planner.
1001
726
  *
1002
727
  * @param {ChangeEntry[]} changes
1003
728
  * @returns {Array<{ path: string, isGlob: boolean }>}