mandrel 2.59.0 → 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (678) hide show
  1. package/.agents/README.md +21 -19
  2. package/.agents/agents/acceptance-critic.md +24 -43
  3. package/.agents/agents/story-worker.md +20 -21
  4. package/.agents/docs/agentrc-reference.json +5 -84
  5. package/.agents/docs/configuration.md +48 -132
  6. package/.agents/docs/workflows.md +2 -2
  7. package/.agents/instructions.md +5 -8
  8. package/.agents/rules/ci-remediation.md +41 -8
  9. package/.agents/rules/gherkin-standards.md +4 -0
  10. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  11. package/.agents/schemas/agentrc.schema.json +16 -496
  12. package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
  13. package/.agents/schemas/validation-evidence.schema.json +2 -1
  14. package/.agents/scripts/README.md +23 -13
  15. package/.agents/scripts/acceptance-eval.js +35 -169
  16. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  17. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  18. package/.agents/scripts/audit-baselines.js +6 -27
  19. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  20. package/.agents/scripts/audit-to-stories.js +91 -361
  21. package/.agents/scripts/boot-sweep.js +19 -72
  22. package/.agents/scripts/bootstrap.js +74 -395
  23. package/.agents/scripts/ceremony-derive.js +10 -41
  24. package/.agents/scripts/check-arch-cycles.js +14 -64
  25. package/.agents/scripts/check-baselines.js +8 -48
  26. package/.agents/scripts/check-context-budget.js +105 -311
  27. package/.agents/scripts/check-cyclomatic.js +12 -44
  28. package/.agents/scripts/check-dead-exports.js +13 -64
  29. package/.agents/scripts/check-doc-links.js +38 -186
  30. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  31. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  32. package/.agents/scripts/coverage-capture.js +34 -98
  33. package/.agents/scripts/deliver-light.js +25 -171
  34. package/.agents/scripts/deliver-recover.js +6 -42
  35. package/.agents/scripts/deliver-run.js +534 -0
  36. package/.agents/scripts/diagnose-friction.js +24 -116
  37. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  38. package/.agents/scripts/evidence-gate.js +23 -85
  39. package/.agents/scripts/file-ci-gap.js +57 -49
  40. package/.agents/scripts/generate-config-docs.js +30 -170
  41. package/.agents/scripts/generate-lens-checklists.js +8 -52
  42. package/.agents/scripts/generate-skills-index.js +14 -112
  43. package/.agents/scripts/generate-workflows-doc.js +10 -70
  44. package/.agents/scripts/git-cleanup.js +2 -34
  45. package/.agents/scripts/lib/Graph.js +24 -81
  46. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  47. package/.agents/scripts/lib/Logger.js +14 -76
  48. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  49. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  50. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  51. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  52. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  53. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  54. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  55. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  56. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  57. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  58. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  59. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  60. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  61. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  62. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  63. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  64. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  65. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  66. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  67. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  68. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  69. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  70. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  71. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  72. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  73. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  74. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  75. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  76. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  77. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  78. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  79. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  80. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  81. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  82. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  83. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  84. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  85. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  86. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  87. package/.agents/scripts/lib/baseline-loader.js +12 -51
  88. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  89. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  90. package/.agents/scripts/lib/baselines/components.js +10 -61
  91. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  92. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
  93. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  94. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  95. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  96. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  97. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  98. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  99. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  100. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  101. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  102. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  103. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  104. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  105. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  106. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  107. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  108. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  109. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  110. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  111. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  112. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  113. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  114. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  115. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  116. package/.agents/scripts/lib/baselines/reader.js +14 -107
  117. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  118. package/.agents/scripts/lib/baselines/scope.js +11 -135
  119. package/.agents/scripts/lib/baselines/writer.js +16 -149
  120. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  121. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  122. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  123. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  124. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  125. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  126. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  127. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  128. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  129. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  130. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  131. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  132. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  133. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  134. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  135. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  136. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  137. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  138. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  139. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  140. package/.agents/scripts/lib/changed-files.js +39 -121
  141. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  142. package/.agents/scripts/lib/checks/index.js +18 -101
  143. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  144. package/.agents/scripts/lib/checks/state.js +16 -91
  145. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  146. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  147. package/.agents/scripts/lib/child-exec.js +39 -108
  148. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  149. package/.agents/scripts/lib/cli-args.js +31 -146
  150. package/.agents/scripts/lib/cli-usage.js +5 -27
  151. package/.agents/scripts/lib/cli-utils.js +2 -12
  152. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  153. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  154. package/.agents/scripts/lib/close-validation/process.js +121 -151
  155. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  156. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  157. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  158. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  159. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  160. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  161. package/.agents/scripts/lib/command-header.js +6 -28
  162. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  163. package/.agents/scripts/lib/config/baselines.js +3 -14
  164. package/.agents/scripts/lib/config/ci.js +8 -38
  165. package/.agents/scripts/lib/config/commands.js +1 -15
  166. package/.agents/scripts/lib/config/defaults.js +4 -33
  167. package/.agents/scripts/lib/config/delivery-routing.js +6 -34
  168. package/.agents/scripts/lib/config/explain.js +10 -83
  169. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  170. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
  171. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  172. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  173. package/.agents/scripts/lib/config/gates/index.js +2 -17
  174. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  175. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  176. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  177. package/.agents/scripts/lib/config/github.js +4 -22
  178. package/.agents/scripts/lib/config/limits.js +4 -57
  179. package/.agents/scripts/lib/config/paths.js +2 -21
  180. package/.agents/scripts/lib/config/qa.js +4 -38
  181. package/.agents/scripts/lib/config/quality.js +76 -432
  182. package/.agents/scripts/lib/config/runners.js +12 -56
  183. package/.agents/scripts/lib/config/runtime.js +13 -57
  184. package/.agents/scripts/lib/config/shared.js +2 -16
  185. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  186. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  187. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  188. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  189. package/.agents/scripts/lib/config-resolver.js +11 -52
  190. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  191. package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
  192. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  193. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  194. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  195. package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
  196. package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
  197. package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
  198. package/.agents/scripts/lib/coverage-capture.js +99 -224
  199. package/.agents/scripts/lib/coverage-utils.js +14 -79
  200. package/.agents/scripts/lib/cpu-pool.js +17 -123
  201. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  202. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  203. package/.agents/scripts/lib/crap-engine.js +40 -153
  204. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  205. package/.agents/scripts/lib/crap-utils.js +31 -155
  206. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  207. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  208. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  209. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  210. package/.agents/scripts/lib/degraded-mode.js +3 -26
  211. package/.agents/scripts/lib/dependency-parser.js +8 -40
  212. package/.agents/scripts/lib/dependency-version.js +13 -35
  213. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  214. package/.agents/scripts/lib/doc-tiers.js +22 -124
  215. package/.agents/scripts/lib/duplicate-search.js +8 -72
  216. package/.agents/scripts/lib/env-loader.js +5 -27
  217. package/.agents/scripts/lib/error-redactor.js +6 -31
  218. package/.agents/scripts/lib/errors/index.js +2 -22
  219. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  220. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  221. package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
  222. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  223. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
  224. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  225. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  226. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  227. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  228. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  229. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  230. package/.agents/scripts/lib/findings/severity.js +18 -104
  231. package/.agents/scripts/lib/format-generated-json.js +12 -44
  232. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  233. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  234. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  235. package/.agents/scripts/lib/gates/friction.js +1 -3
  236. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  237. package/.agents/scripts/lib/gh-exec.js +123 -191
  238. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  239. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  240. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  241. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  242. package/.agents/scripts/lib/git-utils.js +37 -161
  243. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  244. package/.agents/scripts/lib/github-url.js +2 -17
  245. package/.agents/scripts/lib/import-graph.js +11 -38
  246. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  247. package/.agents/scripts/lib/json-utils.js +3 -18
  248. package/.agents/scripts/lib/label-constants.js +16 -111
  249. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  250. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  251. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  252. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  253. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  254. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  255. package/.agents/scripts/lib/npm-scripts.js +4 -23
  256. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  257. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  258. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  259. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  260. package/.agents/scripts/lib/observability/source-classifier.js +22 -203
  261. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  262. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  263. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  264. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  265. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  266. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  267. package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
  268. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  274. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  275. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  276. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  277. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  278. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  279. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
  280. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  281. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  282. package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
  283. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  284. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  285. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  286. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  287. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  288. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  289. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  290. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  291. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  292. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  293. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  294. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  295. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  308. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  309. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  310. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  311. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  313. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  314. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  315. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  316. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  317. package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
  318. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  319. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  320. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  321. package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
  322. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  323. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  324. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  325. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  326. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  327. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  328. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
  329. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  330. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  331. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  332. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  333. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  334. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  335. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
  336. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  337. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
  338. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
  339. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
  340. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  341. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  342. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  343. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  344. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  345. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  346. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  347. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  348. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  349. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  350. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  351. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  352. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  353. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  354. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  355. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  356. package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
  357. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  358. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  359. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  360. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  361. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  362. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  363. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  364. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  365. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  366. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  367. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  368. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  369. package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
  370. package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
  371. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  372. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  373. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  391. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  392. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  393. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
  394. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  395. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  396. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  397. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  398. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  399. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  400. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  401. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  402. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
  403. package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
  404. package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
  405. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  406. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  407. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
  408. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  409. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  410. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  411. package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
  412. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  413. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
  414. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  415. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  416. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  417. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  418. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  419. package/.agents/scripts/lib/path-security.js +3 -6
  420. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  421. package/.agents/scripts/lib/preflight-runner.js +13 -69
  422. package/.agents/scripts/lib/process-group.js +143 -0
  423. package/.agents/scripts/lib/project-root.js +2 -8
  424. package/.agents/scripts/lib/provider-factory.js +2 -25
  425. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  426. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  427. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  428. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  429. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  430. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  431. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  432. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  433. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  434. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  435. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  436. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  437. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  438. package/.agents/scripts/lib/signals/index.js +2 -19
  439. package/.agents/scripts/lib/signals/schema.js +14 -109
  440. package/.agents/scripts/lib/signals/write.js +2 -11
  441. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  442. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  443. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  444. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  445. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  446. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  447. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  448. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  449. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  450. package/.agents/scripts/lib/source-extensions.js +11 -42
  451. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  452. package/.agents/scripts/lib/stdio-flush.js +9 -36
  453. package/.agents/scripts/lib/story-adjacency.js +8 -40
  454. package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
  455. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  456. package/.agents/scripts/lib/story-body/story-body.js +123 -344
  457. package/.agents/scripts/lib/temp-retention.js +42 -143
  458. package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
  459. package/.agents/scripts/lib/test-env.js +12 -65
  460. package/.agents/scripts/lib/test-run-credit.js +10 -65
  461. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  462. package/.agents/scripts/lib/test-temp.js +38 -184
  463. package/.agents/scripts/lib/test-tiers.js +12 -96
  464. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  465. package/.agents/scripts/lib/transpile.js +15 -74
  466. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  467. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  468. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  469. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  470. package/.agents/scripts/lib/validation-evidence.js +21 -96
  471. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  472. package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
  473. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  474. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  475. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  476. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  477. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  478. package/.agents/scripts/lib/workflow-closure.js +22 -105
  479. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  480. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  481. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  482. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  483. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  484. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  485. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  486. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  487. package/.agents/scripts/lib/worktree-manager.js +15 -40
  488. package/.agents/scripts/lint-issue-body.js +12 -68
  489. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  490. package/.agents/scripts/merge-baseline.js +30 -105
  491. package/.agents/scripts/nav-registry-diff.js +22 -108
  492. package/.agents/scripts/notify.js +12 -69
  493. package/.agents/scripts/plan-context.js +97 -92
  494. package/.agents/scripts/plan-critics.js +12 -66
  495. package/.agents/scripts/plan-persist.js +71 -137
  496. package/.agents/scripts/plan-run-epilogue.js +20 -43
  497. package/.agents/scripts/pr-watch-with-update.js +79 -263
  498. package/.agents/scripts/providers/github/auth.js +3 -8
  499. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  500. package/.agents/scripts/providers/github/board-add.js +5 -21
  501. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  502. package/.agents/scripts/providers/github/cache.js +2 -14
  503. package/.agents/scripts/providers/github/comments.js +7 -40
  504. package/.agents/scripts/providers/github/compose.js +3 -19
  505. package/.agents/scripts/providers/github/errors.js +22 -125
  506. package/.agents/scripts/providers/github/issues.js +31 -123
  507. package/.agents/scripts/providers/github/labels.js +24 -124
  508. package/.agents/scripts/providers/github/mappers.js +5 -27
  509. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  510. package/.agents/scripts/providers/github/project-board.js +2 -17
  511. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  512. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  513. package/.agents/scripts/providers/github/search-budget.js +9 -39
  514. package/.agents/scripts/providers/github/search-query.js +5 -26
  515. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  516. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  517. package/.agents/scripts/providers/github/tickets.js +32 -134
  518. package/.agents/scripts/providers/github.js +18 -59
  519. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  520. package/.agents/scripts/quality-preview.js +35 -220
  521. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  522. package/.agents/scripts/resolve-stories.js +16 -67
  523. package/.agents/scripts/resync-status-column.js +6 -25
  524. package/.agents/scripts/run-tests.js +29 -104
  525. package/.agents/scripts/single-story-close.js +23 -135
  526. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  527. package/.agents/scripts/single-story-init.js +47 -259
  528. package/.agents/scripts/stories-wave-tick.js +179 -415
  529. package/.agents/scripts/sync-agentrc.js +3 -21
  530. package/.agents/scripts/sync-claude-agents.js +9 -55
  531. package/.agents/scripts/sync-claude-commands.js +20 -110
  532. package/.agents/scripts/test-wrapper.js +6 -43
  533. package/.agents/scripts/update-coverage-baseline.js +5 -22
  534. package/.agents/scripts/update-crap-baseline.js +7 -30
  535. package/.agents/scripts/update-duplication-baseline.js +16 -92
  536. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  537. package/.agents/scripts/update-ticket-state.js +1 -7
  538. package/.agents/scripts/validate-skills.js +6 -26
  539. package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
  540. package/.agents/skills/skills.index.json +2 -2
  541. package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
  542. package/.agents/templates/agent-protocol.md +2 -2
  543. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  544. package/.agents/workflows/audit-accessibility.md +4 -7
  545. package/.agents/workflows/audit-adrs.md +3 -6
  546. package/.agents/workflows/audit-architecture.md +3 -11
  547. package/.agents/workflows/audit-baselines.md +6 -9
  548. package/.agents/workflows/audit-clean-code.md +8 -12
  549. package/.agents/workflows/audit-data-model.md +3 -7
  550. package/.agents/workflows/audit-dependencies.md +4 -7
  551. package/.agents/workflows/audit-devops.md +4 -8
  552. package/.agents/workflows/audit-documentation.md +1 -4
  553. package/.agents/workflows/audit-mobile.md +4 -7
  554. package/.agents/workflows/audit-navigability.md +3 -6
  555. package/.agents/workflows/audit-performance.md +2 -4
  556. package/.agents/workflows/audit-privacy.md +4 -7
  557. package/.agents/workflows/audit-quality.md +4 -7
  558. package/.agents/workflows/audit-security.md +4 -7
  559. package/.agents/workflows/audit-seo.md +4 -7
  560. package/.agents/workflows/audit-sre.md +4 -7
  561. package/.agents/workflows/audit-to-stories.md +17 -30
  562. package/.agents/workflows/audit-ux-ui.md +4 -7
  563. package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
  564. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  565. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  566. package/.agents/workflows/helpers/code-review.md +4 -2
  567. package/.agents/workflows/helpers/deliver-digest.md +37 -28
  568. package/.agents/workflows/helpers/deliver-light.md +92 -101
  569. package/.agents/workflows/helpers/deliver-reference.md +162 -220
  570. package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
  571. package/.agents/workflows/helpers/deliver-story.md +17 -18
  572. package/.agents/workflows/helpers/plan-reference.md +125 -167
  573. package/.agents/workflows/helpers/qa-core.md +12 -0
  574. package/.agents/workflows/mandrel-deliver.md +47 -31
  575. package/.agents/workflows/mandrel-plan.md +22 -21
  576. package/.agents/workflows/mandrel-update.md +36 -21
  577. package/.agents/workflows/memory-consolidate.md +1 -1
  578. package/.agents/workflows/qa-assist.md +27 -71
  579. package/.agents/workflows/qa-explore.md +19 -59
  580. package/.agents/workflows/qa-run.md +11 -33
  581. package/README.md +1 -1
  582. package/bin/mandrel.js +5 -46
  583. package/bin/postinstall.js +18 -107
  584. package/docs/CHANGELOG.md +60 -0
  585. package/lib/cli/doctor.js +11 -71
  586. package/lib/cli/init.js +26 -165
  587. package/lib/cli/migrate.js +5 -64
  588. package/lib/cli/registry.js +84 -467
  589. package/lib/cli/sync-agents.js +4 -64
  590. package/lib/cli/sync-commands.js +11 -64
  591. package/lib/cli/sync.js +34 -213
  592. package/lib/cli/uninstall.js +40 -219
  593. package/lib/cli/update.js +326 -523
  594. package/lib/cli/version-check.js +8 -72
  595. package/lib/cli/version-helpers.js +14 -87
  596. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  597. package/lib/migrations/index.js +17 -92
  598. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  599. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  600. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  601. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  602. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  603. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  604. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  605. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  606. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
  607. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  608. package/package.json +17 -14
  609. package/.agents/docs/SDLC.md +0 -590
  610. package/.agents/docs/quality-gates.md +0 -1179
  611. package/.agents/rules/known-tooling-behavior.md +0 -150
  612. package/.agents/rules/orchestration-error-handling.md +0 -61
  613. package/.agents/rules/test-seams.md +0 -59
  614. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  615. package/.agents/schemas/baselines/lint.schema.json +0 -47
  616. package/.agents/schemas/model-attribution.schema.json +0 -53
  617. package/.agents/scripts/check-action-pinning.js +0 -260
  618. package/.agents/scripts/check-audit-attribution.js +0 -302
  619. package/.agents/scripts/check-baseline-drift.js +0 -211
  620. package/.agents/scripts/check-baseline-scope.js +0 -362
  621. package/.agents/scripts/check-generated-validator.js +0 -202
  622. package/.agents/scripts/check-knip-entries.js +0 -159
  623. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  624. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  625. package/.agents/scripts/check-schema-references.js +0 -366
  626. package/.agents/scripts/check-test-portability.js +0 -512
  627. package/.agents/scripts/check-workflow-citations.js +0 -332
  628. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  629. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  630. package/.agents/scripts/install-matrix-assert.js +0 -326
  631. package/.agents/scripts/lib/audit-advisories.js +0 -195
  632. package/.agents/scripts/lib/audit-attribution.js +0 -134
  633. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  634. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  635. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  636. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  637. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  638. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  639. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  640. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  641. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  642. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  643. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  644. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  645. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  646. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  647. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  648. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  649. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  650. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  651. package/.agents/scripts/lib/fs-walk.js +0 -52
  652. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  653. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  654. package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
  655. package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
  656. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
  657. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  658. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  659. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  660. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  661. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  662. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  663. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  664. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  665. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  666. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  667. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  668. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  669. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  670. package/.agents/scripts/post-structured-comment.js +0 -127
  671. package/.agents/scripts/provision-git-hooks.js +0 -85
  672. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  673. package/.agents/scripts/run-coverage.js +0 -197
  674. package/.agents/scripts/run-lint.js +0 -133
  675. package/.agents/scripts/run-test-profile.js +0 -129
  676. package/.agents/scripts/run-verify.js +0 -118
  677. package/.agents/scripts/test-isolate.js +0 -55
  678. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -1,17 +1,7 @@
1
1
  /**
2
- * story-ops.js — flat Story creation for v2 plan-persist (Stage 3).
3
- *
4
- * Under the Story collapse (`docs/roadmap.md` § Stage 3), `/mandrel-plan` persists
5
- * zero-or-more Story issues directly — no Epic parent, no reconciler tree,
6
- * no `deliveryShape` mode matrix. Default is **one Story**; N>1 is gated by
7
- * the supersede partition check.
8
- *
9
- * Each Story body is the single executable document: Tech Spec stays inline
10
- * under `## Spec`, at whatever length the work needs (Story #5312 deleted
11
- * the token budget that used to refuse it) — never spilled to `docs/`.
12
- * Top-level `acceptance[]` / `verify[]` are the machine
13
- * contract and are synced into the body so the GitHub issue stays complete
14
- * without requiring the LLM to dual-author the same lists.
2
+ * Flat Story creation for plan-persist. Each Story body is the single
3
+ * executable document: the Spec stays inline at any length, and top-level
4
+ * `acceptance[]` / `verify[]` (the machine contract) are synced into it.
15
5
  *
16
6
  * @module lib/orchestration/plan-persist/story-ops
17
7
  */
@@ -39,33 +29,21 @@ import {
39
29
  isExternalDependencyRef,
40
30
  } from './external-deps.js';
41
31
  import {
42
- assertSupersedePartition,
43
32
  normalizeSupersedes,
33
+ resolveSupersedePartition,
44
34
  } from './supersede-ops.js';
45
35
 
46
36
  /**
47
- * Label prefix grouping the Stories one plan-persist run authored.
48
- *
49
- * Reintroduced (Story #4692) after Story #4540 retired it: #4540 was right
50
- * that batch identity is the wrong axis for *ordering delivery across runs*
51
- * (`/mandrel-deliver` takes ids and resolves the graph from live state — that stays),
52
- * but it is the correct axis for *grouping the Stories one plan run created*
53
- * so a cohort is filterable and traceable in the GitHub UI. The label is
54
- * metadata only; nothing in persist or delivery reads it as a
55
- * delivery-resolution input.
37
+ * Label prefix grouping the Stories one plan-persist run authored. Metadata
38
+ * only: delivery never reads it as an ordering input.
56
39
  */
57
40
  export const PLAN_RUN_LABEL_PREFIX = 'plan-run::';
58
41
 
59
- /** Stable color for the cohort grouping label (`ensureLabels`). */
60
42
  const PLAN_RUN_LABEL_COLOR = '#C5DEF5';
61
43
 
62
- /** Length of the derived plan-run id (hex chars). */
63
44
  const PLAN_RUN_ID_LENGTH = 8;
64
45
 
65
46
  /**
66
- * Normalize a caller-supplied plan-run token. Kept shared so human-readable
67
- * ids map to one canonical label shape.
68
- *
69
47
  * @param {string} id
70
48
  * @returns {string}
71
49
  */
@@ -82,11 +60,8 @@ export function normalizePlanRunId(id) {
82
60
  }
83
61
 
84
62
  /**
85
- * Build a `plan-run::<id>` label from an explicit id.
86
- *
87
- * Unlike the pre-#4540 shape, this never mints a random token — a random id
88
- * would split a resumed persist's cohort across two labels. Derive the id
89
- * from the authored artifacts via {@link derivePlanRunId} instead.
63
+ * Never mints a random token — that would split a resumed persist's cohort
64
+ * across two labels; derive the id via {@link derivePlanRunId}.
90
65
  *
91
66
  * @param {string} id
92
67
  * @returns {string}
@@ -96,19 +71,11 @@ export function planRunLabel(id) {
96
71
  }
97
72
 
98
73
  /**
99
- * Derive the deterministic plan-run id for a cohort of assembled Stories.
100
- *
101
- * Hashes the **sorted** set of per-Story plan fingerprints (the same
102
- * content identities the resumable-create contract adopts on), so the id is
103
- * a pure function of the authored artifacts: the same `stories.json` yields
104
- * the same `plan-run::<id>` on every run — a persist resumed after a
105
- * mid-run failure applies the identical label to the newly-created
106
- * remainder that the already-created (adopted) Stories carry — while a
107
- * different plan derives a different label. Sorting makes the id
108
- * independent of creation order.
74
+ * Hash of the sorted per-Story fingerprints, so a resumed persist derives the
75
+ * same label its adopted Stories already carry, independent of creation order.
109
76
  *
110
- * @param {string[]} fingerprints Per-Story plan fingerprints.
111
- * @returns {string} Hex id, {@link PLAN_RUN_ID_LENGTH} chars.
77
+ * @param {string[]} fingerprints
78
+ * @returns {string}
112
79
  */
113
80
  export function derivePlanRunId(fingerprints) {
114
81
  const sorted = (Array.isArray(fingerprints) ? fingerprints : [])
@@ -121,59 +88,27 @@ export function derivePlanRunId(fingerprints) {
121
88
  }
122
89
 
123
90
  /**
124
- * Marker prefix for the per-Story plan fingerprint appended to every
125
- * created body. `createStoryIssues` greps open `type::story` issues for
126
- * `<!-- plan-story: <fingerprint> -->` to decide whether a Story already
127
- * exists — the idempotency half of the resumable-create contract.
91
+ * Marker prefix stamped into every created body; the resume path adopts an
92
+ * open Story whose marker matches.
128
93
  */
129
94
  const PLAN_FINGERPRINT_MARKER_PREFIX = 'plan-story:';
130
95
 
131
- /** Length of the hex fingerprint digest. Collision-free at plan scale. */
132
96
  const PLAN_FINGERPRINT_LENGTH = 16;
133
97
 
134
98
  /**
135
- * Compute the deterministic identity of one authored Story within a plan.
136
- *
137
- * Derived from `slug` + `title` + the **assembled** body, so the fingerprint
138
- * identifies the authored *content*, not merely a name. Because the marker is
139
- * what `createStoryIssues` adopts on, that is the whole safety property of the
140
- * resume path: a fingerprint hit means the open Story on the tracker is
141
- * byte-identical to what this run would author, so adopting it instead of
142
- * creating it is a genuine no-op.
143
- *
144
- * **Why the body is in scope.** It used to be excluded, on the rationale that
145
- * creation rewrites the body to substitute real issue ids into `depends_on`
146
- * footers, so a body-derived fingerprint would differ between an aborted run
147
- * and its resume. That conflated two different bodies. The fingerprint is
148
- * computed in `assembleOnePlanStory` over the *assembled* body — whose
149
- * `depends_on` are still sibling **slugs**, and which is a pure function of
150
- * `stories.json` plus the shared Spec. The id substitution happens later, and
151
- * only inside `renderStoryBodyForCreate`, which produces the *posted* body.
152
- * Nothing ever re-derives a fingerprint from a posted body; the lookup reads
153
- * the marker that body carries. The assembled body is therefore stable across
154
- * a run and its resume, and folding it in defeats no lookup.
155
- *
156
- * Excluding it cost two silent failures, both closed by this:
157
- *
158
- * 1. A later, unrelated plan that reused a slug **and** title adopted the
159
- * stale open Story — never rewriting its body or Spec, and landing this
160
- * run's checkpoints, ready-flip, and supersede comments on the wrong
161
- * issue.
162
- * 2. A legitimate resume after the operator edited `stories.json` adopted
163
- * the pre-edit Story and kept its stale body, discarding the edit.
164
- *
165
- * With the body in scope both cases simply miss the lookup, and a correct new
166
- * Story is created; only a genuinely identical Story is ever adopted.
99
+ * Content identity of one authored Story: slug + title + the *assembled* body
100
+ * (whose `depends_on` are still slugs, so it is stable across a run and its
101
+ * resume). A hit means the open Story is byte-identical to what this run
102
+ * would author; a reused slug/title or an edited `stories.json` misses and
103
+ * gets a fresh Story instead of a stale adoption.
167
104
  *
168
105
  * The fields are joined on NUL separators, written as the `\u0000` escape and
169
106
  * never as a raw byte — a literal NUL would make git classify this file as
170
- * binary and silently drop its diffs. NUL cannot occur in a slug, a title, or
171
- * a serialized body, so the join is unambiguous: `{slug:'a-b', title:'c'}` and
172
- * `{slug:'a', title:'b-c'}` cannot collide the way a hyphen or space separator
173
- * would let them.
107
+ * binary and silently drop its diffs. NUL cannot occur in any field, so the
108
+ * join is unambiguous.
174
109
  *
175
110
  * @param {{ slug: string, title: string, body?: string }} story
176
- * @returns {string} Hex digest.
111
+ * @returns {string}
177
112
  */
178
113
  export function planStoryFingerprint({ slug, title, body = '' }) {
179
114
  return createHash('sha256')
@@ -183,10 +118,6 @@ export function planStoryFingerprint({ slug, title, body = '' }) {
183
118
  }
184
119
 
185
120
  /**
186
- * Render the HTML-comment marker carrying a Story's plan fingerprint. It is
187
- * invisible in GitHub's rendered issue body and survives edits to every
188
- * other section.
189
- *
190
121
  * @param {string} fingerprint
191
122
  * @returns {string}
192
123
  */
@@ -194,16 +125,13 @@ function planFingerprintMarker(fingerprint) {
194
125
  return `<!-- ${PLAN_FINGERPRINT_MARKER_PREFIX} ${fingerprint} -->`;
195
126
  }
196
127
 
197
- /** The one parser for the marker {@link planFingerprintMarker} renders. */
198
128
  const PLAN_FINGERPRINT_MARKER_RE = new RegExp(
199
129
  `<!--\\s*${PLAN_FINGERPRINT_MARKER_PREFIX}\\s*([0-9a-f]+)\\s*-->`,
200
130
  );
201
131
 
202
132
  /**
203
- * Recover the plan fingerprint an issue body was stamped with, or `null` when
204
- * the body carries no marker. Module-private: both readers of the marker (the
205
- * resume index and the create-retry adoption probe) go through it so they can
206
- * never drift into recognising different Stories as "already created".
133
+ * The single marker reader, shared by the resume index and the create-retry
134
+ * probe so they never disagree on "already created".
207
135
  *
208
136
  * @param {unknown} body
209
137
  * @returns {string|null}
@@ -215,13 +143,8 @@ function extractPlanFingerprint(body) {
215
143
  }
216
144
 
217
145
  /**
218
- * Labels the authoring pass is never allowed to set. The `agent::*` axis is
219
- * the runtime's lifecycle state (persist owns the terminal `agent::ready`
220
- * flip itself), `type::*` is fixed to `type::story` by the v2 hierarchy,
221
- * `persona::*` and `route::*` are retired axes (the latter with the
222
- * plan-side lite claim, Story #5312), and `plan-run::*` is the
223
- * runtime-derived cohort grouping axis (Story #4692) — a hand-authored entry
224
- * on it would compete with the deterministic label persist applies itself.
146
+ * Label axes the runtime owns (lifecycle, type, cohort) or has retired
147
+ * (persona, route); authored entries on them are dropped.
225
148
  */
226
149
  const FORBIDDEN_LABEL_PREFIXES = Object.freeze([
227
150
  'agent::',
@@ -235,17 +158,11 @@ const FORBIDDEN_LABEL_PREFIXES = Object.freeze([
235
158
  const MAX_LABEL_LENGTH = 50;
236
159
 
237
160
  /**
238
- * Sanitize the author-supplied `labels[]` on a plan Story (Story #4541).
239
- *
240
- * The schema descriptor and the authoring prompt both ask for `labels[]`,
241
- * but persist never read the field — it hard-coded its own list, so every
242
- * authored label was silently discarded. Rather than keep asking for input
243
- * that goes nowhere, apply it: drop the axes the runtime owns, drop
244
- * malformed entries, dedupe, and always guarantee `type::story`.
161
+ * Drop runtime-owned and malformed labels, dedupe, and guarantee `type::story`.
245
162
  *
246
163
  * @param {unknown} rawLabels
247
- * @param {string} slug For the dropped-label warning.
248
- * @returns {string[]} Sanitized labels, always including `type::story`.
164
+ * @param {string} slug
165
+ * @returns {string[]}
249
166
  */
250
167
  export function sanitizeAuthoredLabels(rawLabels, slug) {
251
168
  const kept = new Set([TYPE_LABELS.STORY]);
@@ -306,10 +223,8 @@ function arraysEqual(a, b) {
306
223
  }
307
224
 
308
225
  /**
309
- * Top-level `acceptance[]` / `verify[]` are the machine contract (validator
310
- * SSOT). Sync them into the body so the persisted GitHub issue is complete.
311
- * When the body already lists the same items, keep them; when the body is
312
- * empty, fill from top-level; when both disagree, fail closed.
226
+ * Sync a top-level contract field into the body; fail closed when both are
227
+ * set and disagree.
313
228
  *
314
229
  * @param {object} ticket
315
230
  * @param {object} bodyObject
@@ -330,16 +245,8 @@ function syncContractFieldFromTopLevel(ticket, bodyObject, field) {
330
245
  }
331
246
 
332
247
  /**
333
- * Normalize a plan Story ticket into `{ slug, title, bodyObject }`.
334
- * Accepts either a serialized markdown `body` string or a structured body.
335
- *
336
- * `supersedes[]` is a top-level-only field (Story #4535) — it is planning
337
- * bookkeeping for the `--tickets` source issues, not part of the Story's
338
- * executable body, so it is deliberately not serialized into the markdown.
339
- *
340
- * `provenance` is likewise top-level-only (Story #5045) — it names the audit
341
- * identities *this* Story owns, and is stamped into the body as footers rather
342
- * than serialized as a section.
248
+ * `supersedes[]` and `provenance` are top-level-only: planning bookkeeping and
249
+ * footer input respectively, never serialized as body sections.
343
250
  *
344
251
  * @param {object} ticket
345
252
  * @returns {{ slug: string, title: string, bodyObject: object, depends_on: string[], labels: string[], supersedes: Array<{ id: number, note: string|null }>, provenance: { fingerprints: string[], semanticKeys: string[] }|null }}
@@ -386,11 +293,7 @@ export function normalizeStoryTicket(ticket) {
386
293
  }
387
294
 
388
295
  /**
389
- * Fold optional shared Tech Spec prose into a Story body when the Story has
390
- * no inline Spec. Specs stay inline, verbatim, at any length.
391
- *
392
- * Precedence: per-Story `body.spec` wins; otherwise `sharedSpec` is used
393
- * (N===1 convenience only — callers must not share one Spec across N>1).
296
+ * Per-Story `body.spec` wins; otherwise `sharedSpec` (N===1 only).
394
297
  *
395
298
  * @param {object} bodyObject
396
299
  * @param {string} slug
@@ -424,25 +327,13 @@ export function foldSpecIntoStoryBody(bodyObject, slug, opts = {}) {
424
327
  }
425
328
 
426
329
  /**
427
- * Resolve the provenance source one Story is stamped from (Story #5045).
428
- *
429
- * Two channels, and the precedence between them is the whole contract:
430
- *
431
- * - **Attributed** — the Story authored a `provenance` field naming the audit
432
- * identities *it* owns. Exactly those are stamped. This is what makes the
433
- * footers answer "which Story tracks this finding?" instead of "which sweep
434
- * planned it?": under the union every sibling carried every key, so the next
435
- * sweep's confirmation pass could only pick an arbitrary open Story, and a
436
- * key whose owner had since closed was masked by any open neighbour.
437
- * - **Union fallback** — no `provenance` field, so the whole seed's footers are
438
- * carried, exactly as before. This is **not** dead weight to be tidied away:
439
- * hand-carried provenance is the failure Stories #4626 / #4877 measured, and
440
- * the union is what closed it. Attribution is additive and recall-safe;
441
- * deleting the fallback would re-open that hole for every plan that does not
442
- * attribute.
330
+ * An authored `provenance` stamps exactly the identities this Story owns;
331
+ * otherwise the whole seed's footers are carried. Keep that union fallback:
332
+ * without it a non-attributing plan persists Stories with no provenance and
333
+ * the next audit sweep re-files planned work.
443
334
  *
444
335
  * @param {{ fingerprints: string[], semanticKeys: string[] }|null} provenance
445
- * @param {object} opts Assembly options carrying `provenanceSource`.
336
+ * @param {object} opts
446
337
  * @returns {string}
447
338
  */
448
339
  function resolveProvenanceSource(provenance, opts) {
@@ -463,17 +354,9 @@ function assembleOnePlanStory(ticket, opts) {
463
354
  const { bodyObject: folded } = foldSpecIntoStoryBody(bodyObject, slug, {
464
355
  sharedSpec: opts.sharedSpec ?? null,
465
356
  });
466
- // Body first: the fingerprint is an identity over the *assembled* content,
467
- // so it cannot be computed until that content exists.
468
357
  const serialized = serializeStoryBody({ ...folded, depends_on });
469
- // Carry audit dedup provenance into the persisted body (Story #4877). The
470
- // audit sweep's Single-plan path stamps the `audit-fingerprints` /
471
- // `audit-semantic-keys` footers into the seed it hands `/mandrel-plan`; without this
472
- // the persisted Story carries no provenance and the next sweep re-files work
473
- // it already planned. Mechanical on purpose — the authoring agent is not
474
- // asked to notice HTML comments in a one-pager. A non-audit seed carries no
475
- // footers, so this is a no-op there. Which identities reach *this* Story is
476
- // `resolveProvenanceSource`'s call (Story #5045).
358
+ // Mechanical on purpose: the authoring agent is not asked to hand-carry
359
+ // audit footers. A non-audit seed has none, so this is a no-op there.
477
360
  const { body } = carryProvenanceFooters({
478
361
  from: resolveProvenanceSource(provenance, opts),
479
362
  into: serialized,
@@ -495,9 +378,6 @@ function assembleOnePlanStory(ticket, opts) {
495
378
  }
496
379
 
497
380
  /**
498
- * Shared techspec.md is an N===1 convenience only — folding one Spec into
499
- * every sibling duplicates approach prose and breaks Story-as-SSOT.
500
- *
501
381
  * @param {object[]} tickets
502
382
  * @param {string|null|undefined} sharedSpec
503
383
  */
@@ -512,21 +392,16 @@ function assertSharedSpecAllowed(tickets, sharedSpec) {
512
392
  }
513
393
 
514
394
  /**
515
- * Assemble markdown bodies for every Story: normalize → fold spec →
516
- * assertSupersedePartition → serialize.
517
- *
518
- * The partition check runs **before** any GitHub write so a mis-authored
519
- * plan never leaves Stories live against an inconsistent tracker. Story #5332
520
- * retired the acceptance partition that used to run beside it: it refused
521
- * only byte-identical acceptance text across siblings, and the split gate is
522
- * now `assertNoWaveCollisions` in `run-plan-persist.js`, ahead of the first
523
- * create.
395
+ * Normalize → fold spec → dependency-order → supersede partition, all before
396
+ * any GitHub write. The dependency sort runs here only, so `stories[0]` is the
397
+ * one primary Story every consumer sees; an unknown sibling or cycle fails
398
+ * this write-free pass.
524
399
  *
525
400
  * @param {object[]} tickets
526
401
  * @param {object} [opts]
527
402
  * @param {string|null} [opts.sharedSpec]
528
403
  * @param {number[]} [opts.sourceTicketIds] Ids passed to `/mandrel-plan --tickets`.
529
- * @returns {{ stories: Array<{ slug: string, title: string, body: string, acceptance: string[], depends_on: string[], supersedes: Array<{ id: number, note: string|null }> }> }}
404
+ * @returns {{ stories: Array<{ slug: string, title: string, body: string, acceptance: string[], depends_on: string[], supersedes: Array<{ id: number, note: string|null }> }>, warnings: string[] }}
530
405
  */
531
406
  export function assemblePlanStories(tickets, opts = {}) {
532
407
  if (!Array.isArray(tickets) || tickets.length === 0) {
@@ -537,13 +412,16 @@ export function assemblePlanStories(tickets, opts = {}) {
537
412
 
538
413
  assertSharedSpecAllowed(tickets, opts.sharedSpec);
539
414
 
540
- const stories = tickets.map(
541
- (ticket) => assembleOnePlanStory(ticket, opts).story,
415
+ const stories = orderStoriesByDependencies(
416
+ tickets.map((ticket) => assembleOnePlanStory(ticket, opts).story),
542
417
  );
543
418
 
544
- assertSupersedePartition(stories, opts.sourceTicketIds ?? []);
419
+ const warnings = resolveSupersedePartition(
420
+ stories,
421
+ opts.sourceTicketIds ?? [],
422
+ );
545
423
 
546
- return { stories };
424
+ return { stories, warnings };
547
425
  }
548
426
 
549
427
  function orderStoriesByDependencies(stories) {
@@ -563,9 +441,8 @@ function orderStoriesByDependencies(stories) {
563
441
  const scheduled = new Set();
564
442
  const pending = [...list];
565
443
  while (pending.length > 0) {
566
- // External refs gate delivery, never creation order: the blocker is
567
- // already live, so it can never become "scheduled" in this run and would
568
- // otherwise wedge the sort into a false cycle (Story #5155).
444
+ // External refs are already live, never "scheduled" here; counting them
445
+ // would wedge the sort into a false cycle.
569
446
  const index = pending.findIndex((story) =>
570
447
  story.depends_on
571
448
  .filter((slug) => !isExternalDependencyRef(slug))
@@ -584,21 +461,9 @@ function orderStoriesByDependencies(stories) {
584
461
  }
585
462
 
586
463
  /**
587
- * Index the open `type::story` backlog so a re-run can recognise Stories a
588
- * previous, partially-failed persist already created.
589
- *
590
- * Two indexes come back. `byFingerprint` is the adoption key — an exact match
591
- * on the authored content (see {@link planStoryFingerprint}). `idsByTitle` is
592
- * only used to *warn*: it catches the near miss where a Story with this title
593
- * is already open but its content differs, which is what an abandoned earlier
594
- * plan or an edited `stories.json` leaves behind. Adoption deliberately does
595
- * not key on it — a title is not an identity, and adopting on one would let a
596
- * later unrelated plan overwrite someone else's Story.
597
- *
598
- * Best-effort by construction: a provider with no `listIssuesByLabel` (or a
599
- * listing that errors) yields empty indexes and the create loop proceeds
600
- * un-deduplicated, exactly as it did before. That degrades resume, not
601
- * correctness of a first run — so it warns rather than throws.
464
+ * Index open Stories for resume. `byFingerprint` is the adoption key;
465
+ * `idsByTitle` only warns (a title is not an identity). Best-effort: a
466
+ * missing or failing listing degrades resume, not a first run, so it warns.
602
467
  *
603
468
  * @param {object} provider
604
469
  * @returns {Promise<{
@@ -649,19 +514,9 @@ async function indexExistingStories(provider) {
649
514
  }
650
515
 
651
516
  /**
652
- * Re-run the resume lookup for a single fingerprint and return the **raw**
653
- * issue, or `null`.
654
- *
655
- * This is the probe `createIssue` calls before any retry POST (Story #5112).
656
- * A create whose response was lost has already filed the issue; retrying
657
- * blind duplicates it. Because the body posted carries the fingerprint
658
- * marker, the same content-keyed lookup the resume path uses answers "did
659
- * attempt 1 land?" authoritatively — from the server's state, not from a
660
- * client-side guess about where the connection broke.
661
- *
662
- * Best-effort like {@link indexExistingStories}: a provider without the
663
- * listing surface, or a listing that throws, yields `null` and the retry
664
- * proceeds exactly as it did before.
517
+ * Probe `createIssue` runs before a retry POST: a create whose response was
518
+ * lost already filed the issue, and the posted marker answers that from
519
+ * server state. Best-effort — `null` lets the retry proceed.
665
520
  *
666
521
  * @param {{ provider: object, fingerprint: string }} args
667
522
  * @returns {Promise<object|null>}
@@ -685,15 +540,8 @@ async function findOpenStoryByPlanFingerprint({ provider, fingerprint }) {
685
540
  }
686
541
 
687
542
  /**
688
- * Warn when a Story with this title is already open but did **not** match the
689
- * fingerprint — i.e. its authored content differs from what this run is about
690
- * to create.
691
- *
692
- * This is the visible half of the fingerprint tightening. Keying adoption on
693
- * content means these cases correctly get a fresh Story rather than a silent
694
- * stale-body adoption, but the divergent Story stays open, and a duplicate the
695
- * operator never hears about is its own small trap. Naming it converts silent
696
- * litter into a decision.
543
+ * Name a same-title open Story whose content differs, so the duplicate a fresh
544
+ * create leaves behind is a visible decision rather than silent litter.
697
545
  *
698
546
  * @param {{ slug: string, title: string }} story
699
547
  * @param {Map<string, number[]>} idsByTitle
@@ -711,9 +559,8 @@ function warnOnDivergentSameTitleStory(story, idsByTitle) {
711
559
  }
712
560
 
713
561
  /**
714
- * Render the body actually posted for a Story: the assembled markdown with
715
- * sibling `depends_on` slugs resolved to real issue ids, plus the invisible
716
- * plan-fingerprint marker that makes the create loop resumable.
562
+ * The posted body: sibling slugs resolved to issue ids, plus the fingerprint
563
+ * marker.
717
564
  *
718
565
  * @param {object} story
719
566
  * @param {Map<string, number>} idBySlug
@@ -725,19 +572,10 @@ function renderStoryBodyForCreate(story, idBySlug) {
725
572
  );
726
573
  let base = story.body;
727
574
  if (dependencyRefs.length > 0) {
728
- // Re-serializing from `bodyObject` is what resolves the sibling slugs to
729
- // real issue ids — but `bodyObject` never held the provenance footers
730
- // (`assembleOnePlanStory` appends those to the body *string*), so this
731
- // branch drops them unless the carry is re-applied. That is the exact
732
- // loss site Story #4935 diagnosed, #4939 fixed, and #4956 reverted
733
- // wholesale hours later; Story #5056 restored it with a persist-side
734
- // regression test that reads the POSTed body.
735
- //
736
- // `from: story.body` — not the seed — is load-bearing: it re-carries the
737
- // identities *this* Story was stamped with under Story #5045 attribution
738
- // rather than reintroducing the whole seed's union. `carryProvenanceFooters`
739
- // is additive, union-preserving and idempotent, so re-applying is safe by
740
- // construction.
575
+ // `bodyObject` never held the provenance footers (they were appended to
576
+ // the body string), so re-serializing drops them unless re-carried.
577
+ // `from: story.body`, not the seed, keeps this Story's attributed
578
+ // identities; the carry is idempotent.
741
579
  const reserialized = serializeStoryBody(
742
580
  { ...story.bodyObject, depends_on: dependencyRefs },
743
581
  { includeFooter: true },
@@ -751,34 +589,18 @@ function renderStoryBodyForCreate(story, idBySlug) {
751
589
  }
752
590
 
753
591
  /**
754
- * Mirror the plan's sibling `depends_on` edges into native GitHub `blocked_by`
755
- * dependency edges (Story #4544).
756
- *
757
- * Ordering is authored as slugs and, until now, survived persist only as
758
- * `blocked by #N` prose in the body footer. That footer stays — it is what
759
- * `/mandrel-deliver`'s resolver falls back on — but a native edge is the durable,
760
- * machine-readable form: visible in the GitHub UI, readable without parsing
761
- * markdown, and settable by an operator later for cross-run order.
762
- *
763
- * **Non-fatal by design, and deliberately asymmetric with the read path.** A
764
- * missing native edge is cosmetic here: `renderStoryBodyForCreate` has already
765
- * written the footer, so ordering is not lost when the dependencies API says
766
- * no. `/mandrel-deliver`'s *read* of these edges is a real dispatch gate, which is why
767
- * that side fails loud. Persist reports the failure and completes.
592
+ * Mirror sibling `depends_on` into native `blocked_by` edges. Non-fatal: the
593
+ * `blocked by #N` body footer already carries the ordering.
768
594
  *
769
- * Two shape hazards this crossing has to get right, both silent if missed:
770
- * `applyBlockedByDependencies` indexes `slugToIssueNumber` with property
771
- * access, so the `Map` the create loop builds must be flattened to a plain
772
- * object — a `Map` would yield `undefined` for every lookup, skip every edge,
773
- * and (being non-fatal) report success having written nothing. And it reads
774
- * `dependsOn`, not the `depends_on` the assembled Story carries.
595
+ * `applyBlockedByDependencies` indexes `slugToIssueNumber` by property access
596
+ * and reads `dependsOn`, so the Map must be flattened to an object and the key
597
+ * renamed — either miss silently skips every edge and reports success.
775
598
  *
776
599
  * @param {object} args
777
600
  * @param {object} args.provider
778
601
  * @param {Array<{ slug: string, depends_on: string[] }>} args.stories
779
602
  * @param {Map<string, number>} args.idBySlug
780
603
  * @returns {Promise<{ edgesAdded: number, edgesSkipped: number, edgesFailed: number, storiesProcessed: number }|null>}
781
- * `null` when there was nothing to mirror or no interface to mirror through.
782
604
  */
783
605
  async function mirrorNativeDependencyEdges({ provider, stories, idBySlug }) {
784
606
  const withEdges = stories.filter((story) => story.depends_on.length > 0);
@@ -798,9 +620,7 @@ async function mirrorNativeDependencyEdges({ provider, stories, idBySlug }) {
798
620
 
799
621
  try {
800
622
  const { gh, owner, repo } = provider.getDependencyWriteContext();
801
- // `applyBlockedByDependencies` resolves every entry through this one map,
802
- // so an external `#<id>` ref only needs an identity entry to be mirrored
803
- // by the same code path as a sibling (Story #5155).
623
+ // An external `#<id>` ref needs only an identity entry here.
804
624
  const slugToIssueNumber = Object.fromEntries(idBySlug);
805
625
  for (const story of stories) {
806
626
  for (const entry of story.depends_on) {
@@ -842,27 +662,17 @@ async function mirrorNativeDependencyEdges({ provider, stories, idBySlug }) {
842
662
  }
843
663
 
844
664
  /**
845
- * Ensure the runtime-derived `plan-run::<id>` cohort label exists before it
846
- * is applied — GitHub's create-issue path does not auto-create unknown
847
- * labels on every provider route, and an opaque derived label never exists
848
- * yet.
849
- *
850
- * **Non-fatal by design**, matching the native-blocked_by mirroring posture:
851
- * the label is not load-bearing for correctness (grouping is cosmetic), so
852
- * it is never a reason to fail persist. On an ensure
853
- * failure (throw, or the label reported `missing` by the post-loop
854
- * reconcile) the create loop proceeds **without** the label — applying an
855
- * unensured label could fail the issue create itself, and the Stories matter
856
- * more than their metadata. A provider that exposes no `ensureLabels` (test
857
- * fakes, minimal providers) is assumed to accept arbitrary labels on create.
665
+ * Ensure a label exists before it is applied (create-issue does not always
666
+ * auto-create). Non-fatal: on failure the Stories are created without it,
667
+ * since an unensured label could fail the create itself.
858
668
  *
859
669
  * @param {object} args
860
670
  * @param {object} args.provider
861
671
  * @param {string} args.label
862
672
  * @param {string} args.color
863
673
  * @param {string} args.description
864
- * @param {string} args.role Human-readable role for the degrade warning.
865
- * @returns {Promise<boolean>} Whether the create loop should apply the label.
674
+ * @param {string} args.role
675
+ * @returns {Promise<boolean>} Whether to apply the label.
866
676
  */
867
677
  async function ensurePersistLabel({
868
678
  provider,
@@ -898,50 +708,12 @@ async function ensurePersistLabel({
898
708
  }
899
709
 
900
710
  /**
901
- * Create Story issues via `provider.createIssue`, resumably.
902
- *
903
- * **Stories are born without `agent::ready`** (Story #4541). They used to
904
- * carry it in the creating POST while the `story-plan-state` checkpoint was
905
- * upserted afterwards, so anything that picked a Story up inside that window —
906
- * or after a comment failure aborted the loop — read the checkpoint as `null`.
907
- * Creation now applies `type::story` plus the sanitized authored labels only;
908
- * `markStoriesReady` performs the flip as the terminal step, once every
909
- * checkpoint is on the ticket.
910
- *
911
- * **The loop is resumable, and adoption is content-keyed.** Each body carries
912
- * a plan-fingerprint marker, and the open `type::story` backlog is indexed by
913
- * it before the first POST. A Story whose fingerprint already exists is
914
- * adopted rather than re-created, so a re-run after a 502 at story *k* of *N*
915
- * completes the cohort instead of minting a second copy of `1..k-1`.
916
- *
917
- * The fingerprint covers the assembled body, not just slug + title, so a hit
918
- * means the open Story *is* what this run would author and adoption changes
919
- * nothing. A same-named Story whose content has drifted — an abandoned plan, or
920
- * an edited `stories.json` — misses the lookup, gets a correct new Story, and
921
- * is named in a warning. Adoption never rewrites a body, so keying it on
922
- * anything weaker than content would silently ship a stale one.
923
- *
924
- * **Every created Story carries the cohort's `plan-run::<id>` grouping
925
- * label** (Story #4692, metadata only). The id is deterministic over the
926
- * authored artifacts ({@link derivePlanRunId}), so a resumed persist derives
927
- * the identical label its adopted Stories already carry from their original
928
- * create — no relabel call is needed on the resume path, and the cohort is
929
- * never split across two labels. The label is ensured to exist before the
930
- * first POST, **non-fatally**: grouping is cosmetic and never fails the run
931
- * (see `ensureCohortLabel`). `/mandrel-deliver` never reads it — delivery stays
932
- * ids-only over live state (Story #4540's actual point).
711
+ * Create Story issues resumably, adopting any open Story whose fingerprint
712
+ * matches. Stories are born without `agent::ready`; `markStoriesReady` flips
713
+ * it last, once every plan comment is on the ticket.
933
714
  *
934
- * **The create loop stays serial and dependency-ordered** — deliberately, and
935
- * unlike every other per-Story loop on this path (Story #4952). It is not an
936
- * independent fan-out: `renderStoryBodyForCreate(story, idBySlug)` resolves a
937
- * Story's `depends_on` slugs to the real issue ids its siblings were just
938
- * minted with, and `idBySlug` is filled *in loop order* by the POSTs
939
- * themselves. Running it concurrently would render `#undefined` dependency
940
- * refs for any Story whose dependency had not yet returned an id.
941
- *
942
- * **Sibling order is mirrored into native GitHub `blocked_by` edges** once
943
- * every id is known (Story #4544), so plan-created order stops depending on
944
- * prose. That pass is non-fatal — see `mirrorNativeDependencyEdges`.
715
+ * The loop stays serial: `idBySlug` is filled in loop order by the POSTs, and
716
+ * a concurrent create would render `#undefined` dependency refs.
945
717
  *
946
718
  * @param {object} args
947
719
  * @param {object} args.provider
@@ -964,9 +736,6 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
964
736
 
965
737
  const list = Array.isArray(stories) ? stories : [];
966
738
 
967
- // Derived once for the whole cohort, before any write — a pure function of
968
- // the authored artifacts, so dry-run can report it write-free and a resume
969
- // re-derives the identical label.
970
739
  const cohortLabel = planRunLabel(
971
740
  derivePlanRunId(list.map((story) => story.fingerprint)),
972
741
  );
@@ -982,9 +751,6 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
982
751
  })),
983
752
  dependencyEdges: null,
984
753
  planRunLabel: cohortLabel,
985
- // A dry run writes nothing, so nothing was ensured and nothing carries
986
- // the label — the derived id is still reported, the application is not
987
- // claimed.
988
754
  planRunLabelApplied: false,
989
755
  };
990
756
  }
@@ -1002,13 +768,11 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1002
768
  const created = [];
1003
769
  const idBySlug = new Map();
1004
770
 
1005
- for (const story of orderStoriesByDependencies(list)) {
771
+ // Already dependency-ordered; re-sorting would disagree on the primary.
772
+ for (const story of list) {
1006
773
  const already = byFingerprint.get(story.fingerprint);
1007
774
  if (!already) warnOnDivergentSameTitleStory(story, idsByTitle);
1008
775
  if (already) {
1009
- // Adopted Stories already carry the cohort label from their original
1010
- // create — the deterministic derivation guarantees it is the same
1011
- // label this run derived, so no relabel call is needed here.
1012
776
  Logger.info(
1013
777
  `[plan-persist] resuming: Story "${story.slug}" already exists as ` +
1014
778
  `#${already.id} with byte-identical authored content ` +
@@ -1029,9 +793,6 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1029
793
  title: story.title,
1030
794
  body: renderStoryBodyForCreate(story, idBySlug),
1031
795
  labels: [...story.labels, ...(applyCohortLabel ? [cohortLabel] : [])],
1032
- // Story #5112 — hand the provider the same content-keyed lookup this
1033
- // loop's resume path uses, so a retry after a lost response adopts the
1034
- // issue attempt 1 already filed instead of creating a twin.
1035
796
  findExisting: () =>
1036
797
  findOpenStoryByPlanFingerprint({
1037
798
  provider,
@@ -1049,21 +810,15 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1049
810
  id,
1050
811
  title: story.title,
1051
812
  url: result.url,
1052
- // Kept, not discarded (Story #5280). `createIssue` hands back the
1053
- // database id, which is the only identifier the native sub-issue write
1054
- // accepts — and dropping it here is what made the Epic linker re-read
1055
- // every Story this run had just created to recover it.
813
+ // The database id — the only id the native sub-issue write accepts.
1056
814
  internalId: result.internalId,
1057
- // True when the provider's retry probe adopted an issue a lost-response
1058
- // first attempt had already filed — pre-existing either way.
815
+ // True when the retry probe adopted a lost-response first attempt.
1059
816
  adopted: result.adopted === true,
1060
817
  });
1061
818
  idBySlug.set(story.slug, id);
1062
819
  }
1063
820
 
1064
- // Every id is known now — including the adopted ones a resumed run reused —
1065
- // so a re-run mirrors the whole cohort's edges, not just the Stories this
1066
- // invocation happened to POST. Re-application is idempotent.
821
+ // Includes adopted ids, so a resume mirrors the whole cohort (idempotent).
1067
822
  const dependencyEdges = await mirrorNativeDependencyEdges({
1068
823
  provider,
1069
824
  stories: list,
@@ -1073,35 +828,17 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1073
828
  return {
1074
829
  created,
1075
830
  dependencyEdges,
1076
- // The derived id and whether it actually landed are separate facts. The id
1077
- // is reported either way (a resumed persist re-derives it, and the
1078
- // dry-run path reports it write-free); the flag is what an epilogue must
1079
- // consult before advertising a `label:` filter that may match nothing.
831
+ // Check the flag before advertising a `label:` filter that may match nothing.
1080
832
  planRunLabel: cohortLabel,
1081
833
  planRunLabelApplied: applyCohortLabel,
1082
834
  };
1083
835
  }
1084
836
 
1085
837
  /**
1086
- * Flip every created Story to `agent::ready` — the terminal step of persist
1087
- * (Story #4541).
1088
- *
1089
- * This is what makes `agent::ready` *mean* "fully persisted": by the time it
1090
- * lands, the Story's `story-plan-state` checkpoint is already on the ticket, so
1091
- * a `/mandrel-deliver` that picks it up cannot read a null checkpoint.
1092
- *
1093
- * Fails closed: an un-flipped Story is invisible to `/mandrel-deliver`, which is the
1094
- * safe direction — the operator is told exactly which ids need the label.
1095
- *
1096
- * **Collect failures, never fast-fail** (preserved verbatim under the
1097
- * Story #4952 concurrency conversion). Every Story is attempted even when an
1098
- * earlier one's PATCH rejects, because the whole value of the closing error is
1099
- * naming the *complete* set of ids that still need the label by hand. The
1100
- * mapper below therefore absorbs its own rejection into a per-Story outcome
1101
- * rather than letting `concurrentMap`'s first-rejection-wins policy abandon
1102
- * the remaining flips. `concurrentMap` preserves input order, so `readied[]`
1103
- * and the reported failures come back in `created[]` order exactly as the
1104
- * serial loop produced them.
838
+ * Terminal step: flip every created Story to `agent::ready`, so the label
839
+ * means "fully persisted". Fails closed, but attempts every Story first — the
840
+ * mapper absorbs its own rejection so the error names the complete set of ids
841
+ * still needing the label.
1105
842
  *
1106
843
  * @param {object} args
1107
844
  * @param {object} args.provider
@@ -1130,9 +867,6 @@ export async function markStoriesReady({ provider, created }) {
1130
867
  };
1131
868
  }
1132
869
  },
1133
- // The terminal per-Story `agent::ready` PATCHes (Story #4952): each flip
1134
- // is an independent single-issue write, so the loop was serial only by
1135
- // construction. A latency fix, not a throughput one.
1136
870
  { concurrency: FANOUT_CONCURRENCY },
1137
871
  );
1138
872
  const readied = outcomes
@@ -1144,7 +878,7 @@ export async function markStoriesReady({ provider, created }) {
1144
878
  if (failed.length > 0) {
1145
879
  throw new Error(
1146
880
  `[plan-persist] ${failed.length} Story(ies) were created with their ` +
1147
- 'checkpoints but could not be flipped to agent::ready:\n' +
881
+ 'plan comments but could not be flipped to agent::ready:\n' +
1148
882
  `${failed.map((f) => ` - ${f}`).join('\n')}\n` +
1149
883
  'They are invisible to /mandrel-deliver until the label lands. Re-run persist ' +
1150
884
  '(it resumes rather than duplicating) or add the label by hand.',