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,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
  */
@@ -44,28 +34,16 @@ import {
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.
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.
100
76
  *
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.
109
- *
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 plan comments, 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,25 +392,10 @@ function assertSharedSpecAllowed(tickets, sharedSpec) {
512
392
  }
513
393
 
514
394
  /**
515
- * Assemble markdown bodies for every Story: normalize → fold spec →
516
- * order by dependency → resolveSupersedePartition → serialize.
517
- *
518
- * **The dependency sort runs here, once** (Story #5361). It used to run again
519
- * inside the create loop, which meant "the primary Story" was derived twice
520
- * from two different orderings: supersede assignment took the first *authored*
521
- * Story, while the plan summary took the first *created*
522
- * one. A draft whose authoring order differed from its dependency order made
523
- * the `superseded-by` comment name a different Story from the summary. One
524
- * sort, one ordered list threaded on to every consumer, so `stories[0]` is the
525
- * only primary there is. The sort also refuses an unknown sibling or a cycle,
526
- * which now fails the write-free pass rather than the first create.
527
- *
528
- * The partition pass runs **before** any GitHub write so a mis-authored
529
- * plan never leaves Stories live against an inconsistent tracker. Story #5332
530
- * retired the acceptance partition that used to run beside it: it refused
531
- * only byte-identical acceptance text across siblings, and the split gate is
532
- * now `assertNoWaveCollisions` in `run-plan-persist.js`, ahead of the first
533
- * 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.
534
399
  *
535
400
  * @param {object[]} tickets
536
401
  * @param {object} [opts]
@@ -576,9 +441,8 @@ function orderStoriesByDependencies(stories) {
576
441
  const scheduled = new Set();
577
442
  const pending = [...list];
578
443
  while (pending.length > 0) {
579
- // External refs gate delivery, never creation order: the blocker is
580
- // already live, so it can never become "scheduled" in this run and would
581
- // 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.
582
446
  const index = pending.findIndex((story) =>
583
447
  story.depends_on
584
448
  .filter((slug) => !isExternalDependencyRef(slug))
@@ -597,21 +461,9 @@ function orderStoriesByDependencies(stories) {
597
461
  }
598
462
 
599
463
  /**
600
- * Index the open `type::story` backlog so a re-run can recognise Stories a
601
- * previous, partially-failed persist already created.
602
- *
603
- * Two indexes come back. `byFingerprint` is the adoption key — an exact match
604
- * on the authored content (see {@link planStoryFingerprint}). `idsByTitle` is
605
- * only used to *warn*: it catches the near miss where a Story with this title
606
- * is already open but its content differs, which is what an abandoned earlier
607
- * plan or an edited `stories.json` leaves behind. Adoption deliberately does
608
- * not key on it — a title is not an identity, and adopting on one would let a
609
- * later unrelated plan overwrite someone else's Story.
610
- *
611
- * Best-effort by construction: a provider with no `listIssuesByLabel` (or a
612
- * listing that errors) yields empty indexes and the create loop proceeds
613
- * un-deduplicated, exactly as it did before. That degrades resume, not
614
- * 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.
615
467
  *
616
468
  * @param {object} provider
617
469
  * @returns {Promise<{
@@ -662,19 +514,9 @@ async function indexExistingStories(provider) {
662
514
  }
663
515
 
664
516
  /**
665
- * Re-run the resume lookup for a single fingerprint and return the **raw**
666
- * issue, or `null`.
667
- *
668
- * This is the probe `createIssue` calls before any retry POST (Story #5112).
669
- * A create whose response was lost has already filed the issue; retrying
670
- * blind duplicates it. Because the body posted carries the fingerprint
671
- * marker, the same content-keyed lookup the resume path uses answers "did
672
- * attempt 1 land?" authoritatively — from the server's state, not from a
673
- * client-side guess about where the connection broke.
674
- *
675
- * Best-effort like {@link indexExistingStories}: a provider without the
676
- * listing surface, or a listing that throws, yields `null` and the retry
677
- * 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.
678
520
  *
679
521
  * @param {{ provider: object, fingerprint: string }} args
680
522
  * @returns {Promise<object|null>}
@@ -698,15 +540,8 @@ async function findOpenStoryByPlanFingerprint({ provider, fingerprint }) {
698
540
  }
699
541
 
700
542
  /**
701
- * Warn when a Story with this title is already open but did **not** match the
702
- * fingerprint — i.e. its authored content differs from what this run is about
703
- * to create.
704
- *
705
- * This is the visible half of the fingerprint tightening. Keying adoption on
706
- * content means these cases correctly get a fresh Story rather than a silent
707
- * stale-body adoption, but the divergent Story stays open, and a duplicate the
708
- * operator never hears about is its own small trap. Naming it converts silent
709
- * 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.
710
545
  *
711
546
  * @param {{ slug: string, title: string }} story
712
547
  * @param {Map<string, number[]>} idsByTitle
@@ -724,9 +559,8 @@ function warnOnDivergentSameTitleStory(story, idsByTitle) {
724
559
  }
725
560
 
726
561
  /**
727
- * Render the body actually posted for a Story: the assembled markdown with
728
- * sibling `depends_on` slugs resolved to real issue ids, plus the invisible
729
- * plan-fingerprint marker that makes the create loop resumable.
562
+ * The posted body: sibling slugs resolved to issue ids, plus the fingerprint
563
+ * marker.
730
564
  *
731
565
  * @param {object} story
732
566
  * @param {Map<string, number>} idBySlug
@@ -738,19 +572,10 @@ function renderStoryBodyForCreate(story, idBySlug) {
738
572
  );
739
573
  let base = story.body;
740
574
  if (dependencyRefs.length > 0) {
741
- // Re-serializing from `bodyObject` is what resolves the sibling slugs to
742
- // real issue ids — but `bodyObject` never held the provenance footers
743
- // (`assembleOnePlanStory` appends those to the body *string*), so this
744
- // branch drops them unless the carry is re-applied. That is the exact
745
- // loss site Story #4935 diagnosed, #4939 fixed, and #4956 reverted
746
- // wholesale hours later; Story #5056 restored it with a persist-side
747
- // regression test that reads the POSTed body.
748
- //
749
- // `from: story.body` — not the seed — is load-bearing: it re-carries the
750
- // identities *this* Story was stamped with under Story #5045 attribution
751
- // rather than reintroducing the whole seed's union. `carryProvenanceFooters`
752
- // is additive, union-preserving and idempotent, so re-applying is safe by
753
- // 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.
754
579
  const reserialized = serializeStoryBody(
755
580
  { ...story.bodyObject, depends_on: dependencyRefs },
756
581
  { includeFooter: true },
@@ -764,34 +589,18 @@ function renderStoryBodyForCreate(story, idBySlug) {
764
589
  }
765
590
 
766
591
  /**
767
- * Mirror the plan's sibling `depends_on` edges into native GitHub `blocked_by`
768
- * dependency edges (Story #4544).
769
- *
770
- * Ordering is authored as slugs and, until now, survived persist only as
771
- * `blocked by #N` prose in the body footer. That footer stays — it is what
772
- * `/mandrel-deliver`'s resolver falls back on — but a native edge is the durable,
773
- * machine-readable form: visible in the GitHub UI, readable without parsing
774
- * markdown, and settable by an operator later for cross-run order.
592
+ * Mirror sibling `depends_on` into native `blocked_by` edges. Non-fatal: the
593
+ * `blocked by #N` body footer already carries the ordering.
775
594
  *
776
- * **Non-fatal by design, and deliberately asymmetric with the read path.** A
777
- * missing native edge is cosmetic here: `renderStoryBodyForCreate` has already
778
- * written the footer, so ordering is not lost when the dependencies API says
779
- * no. `/mandrel-deliver`'s *read* of these edges is a real dispatch gate, which is why
780
- * that side fails loud. Persist reports the failure and completes.
781
- *
782
- * Two shape hazards this crossing has to get right, both silent if missed:
783
- * `applyBlockedByDependencies` indexes `slugToIssueNumber` with property
784
- * access, so the `Map` the create loop builds must be flattened to a plain
785
- * object — a `Map` would yield `undefined` for every lookup, skip every edge,
786
- * and (being non-fatal) report success having written nothing. And it reads
787
- * `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.
788
598
  *
789
599
  * @param {object} args
790
600
  * @param {object} args.provider
791
601
  * @param {Array<{ slug: string, depends_on: string[] }>} args.stories
792
602
  * @param {Map<string, number>} args.idBySlug
793
603
  * @returns {Promise<{ edgesAdded: number, edgesSkipped: number, edgesFailed: number, storiesProcessed: number }|null>}
794
- * `null` when there was nothing to mirror or no interface to mirror through.
795
604
  */
796
605
  async function mirrorNativeDependencyEdges({ provider, stories, idBySlug }) {
797
606
  const withEdges = stories.filter((story) => story.depends_on.length > 0);
@@ -811,9 +620,7 @@ async function mirrorNativeDependencyEdges({ provider, stories, idBySlug }) {
811
620
 
812
621
  try {
813
622
  const { gh, owner, repo } = provider.getDependencyWriteContext();
814
- // `applyBlockedByDependencies` resolves every entry through this one map,
815
- // so an external `#<id>` ref only needs an identity entry to be mirrored
816
- // by the same code path as a sibling (Story #5155).
623
+ // An external `#<id>` ref needs only an identity entry here.
817
624
  const slugToIssueNumber = Object.fromEntries(idBySlug);
818
625
  for (const story of stories) {
819
626
  for (const entry of story.depends_on) {
@@ -855,27 +662,17 @@ async function mirrorNativeDependencyEdges({ provider, stories, idBySlug }) {
855
662
  }
856
663
 
857
664
  /**
858
- * Ensure the runtime-derived `plan-run::<id>` cohort label exists before it
859
- * is applied — GitHub's create-issue path does not auto-create unknown
860
- * labels on every provider route, and an opaque derived label never exists
861
- * yet.
862
- *
863
- * **Non-fatal by design**, matching the native-blocked_by mirroring posture:
864
- * the label is not load-bearing for correctness (grouping is cosmetic), so
865
- * it is never a reason to fail persist. On an ensure
866
- * failure (throw, or the label reported `missing` by the post-loop
867
- * reconcile) the create loop proceeds **without** the label — applying an
868
- * unensured label could fail the issue create itself, and the Stories matter
869
- * more than their metadata. A provider that exposes no `ensureLabels` (test
870
- * 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.
871
668
  *
872
669
  * @param {object} args
873
670
  * @param {object} args.provider
874
671
  * @param {string} args.label
875
672
  * @param {string} args.color
876
673
  * @param {string} args.description
877
- * @param {string} args.role Human-readable role for the degrade warning.
878
- * @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.
879
676
  */
880
677
  async function ensurePersistLabel({
881
678
  provider,
@@ -911,51 +708,12 @@ async function ensurePersistLabel({
911
708
  }
912
709
 
913
710
  /**
914
- * Create Story issues via `provider.createIssue`, resumably.
915
- *
916
- * **Stories are born without `agent::ready`** (Story #4541). They used to
917
- * carry it in the creating POST while the `story-plan-state` comment was
918
- * upserted afterwards, so anything that picked a Story up inside that window —
919
- * or after a comment failure aborted the loop — found a ready Story carrying
920
- * none of the operator's delivery instructions. Creation now applies
921
- * `type::story` plus the sanitized authored labels only; `markStoriesReady`
922
- * performs the flip as the terminal step, once every plan comment is on the
923
- * ticket.
924
- *
925
- * **The loop is resumable, and adoption is content-keyed.** Each body carries
926
- * a plan-fingerprint marker, and the open `type::story` backlog is indexed by
927
- * it before the first POST. A Story whose fingerprint already exists is
928
- * adopted rather than re-created, so a re-run after a 502 at story *k* of *N*
929
- * completes the cohort instead of minting a second copy of `1..k-1`.
930
- *
931
- * The fingerprint covers the assembled body, not just slug + title, so a hit
932
- * means the open Story *is* what this run would author and adoption changes
933
- * nothing. A same-named Story whose content has drifted — an abandoned plan, or
934
- * an edited `stories.json` — misses the lookup, gets a correct new Story, and
935
- * is named in a warning. Adoption never rewrites a body, so keying it on
936
- * anything weaker than content would silently ship a stale one.
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.
937
714
  *
938
- * **Every created Story carries the cohort's `plan-run::<id>` grouping
939
- * label** (Story #4692, metadata only). The id is deterministic over the
940
- * authored artifacts ({@link derivePlanRunId}), so a resumed persist derives
941
- * the identical label its adopted Stories already carry from their original
942
- * create — no relabel call is needed on the resume path, and the cohort is
943
- * never split across two labels. The label is ensured to exist before the
944
- * first POST, **non-fatally**: grouping is cosmetic and never fails the run
945
- * (see `ensureCohortLabel`). `/mandrel-deliver` never reads it — delivery stays
946
- * ids-only over live state (Story #4540's actual point).
947
- *
948
- * **The create loop stays serial and dependency-ordered** — deliberately, and
949
- * unlike every other per-Story loop on this path (Story #4952). It is not an
950
- * independent fan-out: `renderStoryBodyForCreate(story, idBySlug)` resolves a
951
- * Story's `depends_on` slugs to the real issue ids its siblings were just
952
- * minted with, and `idBySlug` is filled *in loop order* by the POSTs
953
- * themselves. Running it concurrently would render `#undefined` dependency
954
- * refs for any Story whose dependency had not yet returned an id.
955
- *
956
- * **Sibling order is mirrored into native GitHub `blocked_by` edges** once
957
- * every id is known (Story #4544), so plan-created order stops depending on
958
- * 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.
959
717
  *
960
718
  * @param {object} args
961
719
  * @param {object} args.provider
@@ -978,9 +736,6 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
978
736
 
979
737
  const list = Array.isArray(stories) ? stories : [];
980
738
 
981
- // Derived once for the whole cohort, before any write — a pure function of
982
- // the authored artifacts, so dry-run can report it write-free and a resume
983
- // re-derives the identical label.
984
739
  const cohortLabel = planRunLabel(
985
740
  derivePlanRunId(list.map((story) => story.fingerprint)),
986
741
  );
@@ -996,9 +751,6 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
996
751
  })),
997
752
  dependencyEdges: null,
998
753
  planRunLabel: cohortLabel,
999
- // A dry run writes nothing, so nothing was ensured and nothing carries
1000
- // the label — the derived id is still reported, the application is not
1001
- // claimed.
1002
754
  planRunLabelApplied: false,
1003
755
  };
1004
756
  }
@@ -1016,16 +768,11 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1016
768
  const created = [];
1017
769
  const idBySlug = new Map();
1018
770
 
1019
- // Already in dependency order: `assemblePlanStories` sorted once, and
1020
- // sorting again here is what gave the run a second, disagreeing notion of
1021
- // which Story is primary (Story #5361).
771
+ // Already dependency-ordered; re-sorting would disagree on the primary.
1022
772
  for (const story of list) {
1023
773
  const already = byFingerprint.get(story.fingerprint);
1024
774
  if (!already) warnOnDivergentSameTitleStory(story, idsByTitle);
1025
775
  if (already) {
1026
- // Adopted Stories already carry the cohort label from their original
1027
- // create — the deterministic derivation guarantees it is the same
1028
- // label this run derived, so no relabel call is needed here.
1029
776
  Logger.info(
1030
777
  `[plan-persist] resuming: Story "${story.slug}" already exists as ` +
1031
778
  `#${already.id} with byte-identical authored content ` +
@@ -1046,9 +793,6 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1046
793
  title: story.title,
1047
794
  body: renderStoryBodyForCreate(story, idBySlug),
1048
795
  labels: [...story.labels, ...(applyCohortLabel ? [cohortLabel] : [])],
1049
- // Story #5112 — hand the provider the same content-keyed lookup this
1050
- // loop's resume path uses, so a retry after a lost response adopts the
1051
- // issue attempt 1 already filed instead of creating a twin.
1052
796
  findExisting: () =>
1053
797
  findOpenStoryByPlanFingerprint({
1054
798
  provider,
@@ -1066,21 +810,15 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1066
810
  id,
1067
811
  title: story.title,
1068
812
  url: result.url,
1069
- // Kept, not discarded (Story #5280). `createIssue` hands back the
1070
- // database id, which is the only identifier the native sub-issue write
1071
- // accepts — and dropping it here is what made the Epic linker re-read
1072
- // every Story this run had just created to recover it.
813
+ // The database id — the only id the native sub-issue write accepts.
1073
814
  internalId: result.internalId,
1074
- // True when the provider's retry probe adopted an issue a lost-response
1075
- // first attempt had already filed — pre-existing either way.
815
+ // True when the retry probe adopted a lost-response first attempt.
1076
816
  adopted: result.adopted === true,
1077
817
  });
1078
818
  idBySlug.set(story.slug, id);
1079
819
  }
1080
820
 
1081
- // Every id is known now — including the adopted ones a resumed run reused —
1082
- // so a re-run mirrors the whole cohort's edges, not just the Stories this
1083
- // invocation happened to POST. Re-application is idempotent.
821
+ // Includes adopted ids, so a resume mirrors the whole cohort (idempotent).
1084
822
  const dependencyEdges = await mirrorNativeDependencyEdges({
1085
823
  provider,
1086
824
  stories: list,
@@ -1090,35 +828,17 @@ export async function createStoryIssues({ provider, stories, opts = {} }) {
1090
828
  return {
1091
829
  created,
1092
830
  dependencyEdges,
1093
- // The derived id and whether it actually landed are separate facts. The id
1094
- // is reported either way (a resumed persist re-derives it, and the
1095
- // dry-run path reports it write-free); the flag is what an epilogue must
1096
- // consult before advertising a `label:` filter that may match nothing.
831
+ // Check the flag before advertising a `label:` filter that may match nothing.
1097
832
  planRunLabel: cohortLabel,
1098
833
  planRunLabelApplied: applyCohortLabel,
1099
834
  };
1100
835
  }
1101
836
 
1102
837
  /**
1103
- * Flip every created Story to `agent::ready` — the terminal step of persist
1104
- * (Story #4541).
1105
- *
1106
- * This is what makes `agent::ready` *mean* "fully persisted": by the time it
1107
- * lands, the Story's `story-plan-state` comment is already on the ticket, so a
1108
- * `/mandrel-deliver` that picks it up always has the plan summary beside it.
1109
- *
1110
- * Fails closed: an un-flipped Story is invisible to `/mandrel-deliver`, which is the
1111
- * safe direction — the operator is told exactly which ids need the label.
1112
- *
1113
- * **Collect failures, never fast-fail** (preserved verbatim under the
1114
- * Story #4952 concurrency conversion). Every Story is attempted even when an
1115
- * earlier one's PATCH rejects, because the whole value of the closing error is
1116
- * naming the *complete* set of ids that still need the label by hand. The
1117
- * mapper below therefore absorbs its own rejection into a per-Story outcome
1118
- * rather than letting `concurrentMap`'s first-rejection-wins policy abandon
1119
- * the remaining flips. `concurrentMap` preserves input order, so `readied[]`
1120
- * and the reported failures come back in `created[]` order exactly as the
1121
- * 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.
1122
842
  *
1123
843
  * @param {object} args
1124
844
  * @param {object} args.provider
@@ -1147,9 +867,6 @@ export async function markStoriesReady({ provider, created }) {
1147
867
  };
1148
868
  }
1149
869
  },
1150
- // The terminal per-Story `agent::ready` PATCHes (Story #4952): each flip
1151
- // is an independent single-issue write, so the loop was serial only by
1152
- // construction. A latency fix, not a throughput one.
1153
870
  { concurrency: FANOUT_CONCURRENCY },
1154
871
  );
1155
872
  const readied = outcomes