mandrel 1.94.0 → 2.1.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 (560) hide show
  1. package/.agents/README.md +116 -99
  2. package/.agents/agents/acceptance-critic.md +9 -7
  3. package/.agents/agents/story-worker.md +45 -51
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +498 -1287
  6. package/.agents/docs/agentrc-reference.json +185 -80
  7. package/.agents/docs/configuration.md +132 -190
  8. package/.agents/docs/execution-reference.md +51 -25
  9. package/.agents/docs/quality-gates.md +25 -33
  10. package/.agents/docs/workflows.md +8 -8
  11. package/.agents/instructions.md +113 -139
  12. package/.agents/rules/ci-remediation.md +11 -15
  13. package/.agents/rules/git-conventions-reference.md +48 -58
  14. package/.agents/rules/git-conventions.md +16 -22
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  16. package/.agents/schemas/agentrc.schema.json +83 -254
  17. package/.agents/schemas/audit-rules.json +59 -1
  18. package/.agents/schemas/audit-rules.schema.json +33 -1
  19. package/.agents/schemas/lifecycle/README.md +1 -2
  20. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  21. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  22. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  23. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  24. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  25. package/.agents/schemas/signal-event.schema.json +3 -3
  26. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  27. package/.agents/schemas/validation-evidence.schema.json +1 -1
  28. package/.agents/scripts/acceptance-eval.js +22 -66
  29. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  30. package/.agents/scripts/audit-to-stories.js +7 -7
  31. package/.agents/scripts/boot-sweep.js +1 -1
  32. package/.agents/scripts/bootstrap.js +3 -3
  33. package/.agents/scripts/check-dead-exports.js +43 -104
  34. package/.agents/scripts/check-doc-links.js +2 -2
  35. package/.agents/scripts/check-lifecycle-lint.js +7 -10
  36. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  37. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  38. package/.agents/scripts/deliver-recover.js +122 -0
  39. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  40. package/.agents/scripts/evidence-gate.js +20 -50
  41. package/.agents/scripts/generate-skills-index.js +17 -1
  42. package/.agents/scripts/generate-workflows-doc.js +4 -4
  43. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  44. package/.agents/scripts/lib/Logger.js +6 -10
  45. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  46. package/.agents/scripts/lib/audit-suite/selector.js +328 -28
  47. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  48. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  49. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
  50. package/.agents/scripts/lib/baselines/reader.js +1 -6
  51. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  52. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  53. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  54. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  55. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  56. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  57. package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
  58. package/.agents/scripts/lib/checks/index.js +3 -2
  59. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  60. package/.agents/scripts/lib/checks/state.js +17 -248
  61. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
  62. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  63. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  64. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  65. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  66. package/.agents/scripts/lib/cli-args.js +39 -9
  67. package/.agents/scripts/lib/close-validation/gates.js +15 -15
  68. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  69. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  70. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  71. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  72. package/.agents/scripts/lib/config/ci.js +6 -31
  73. package/.agents/scripts/lib/config/delivery-routing.js +52 -35
  74. package/.agents/scripts/lib/config/explain.js +61 -48
  75. package/.agents/scripts/lib/config/github.js +7 -5
  76. package/.agents/scripts/lib/config/limits.js +29 -80
  77. package/.agents/scripts/lib/config/paths.js +0 -2
  78. package/.agents/scripts/lib/config/quality.js +12 -15
  79. package/.agents/scripts/lib/config/runners.js +20 -66
  80. package/.agents/scripts/lib/config/temp-paths.js +30 -63
  81. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  82. package/.agents/scripts/lib/config-resolver.js +2 -7
  83. package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
  84. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
  85. package/.agents/scripts/lib/config-settings-schema.js +100 -60
  86. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  87. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  88. package/.agents/scripts/lib/dependency-parser.js +3 -2
  89. package/.agents/scripts/lib/doc-tiers.js +2 -2
  90. package/.agents/scripts/lib/duplicate-search.js +242 -41
  91. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  93. package/.agents/scripts/lib/format-generated-json.js +97 -0
  94. package/.agents/scripts/lib/framework-version.js +19 -190
  95. package/.agents/scripts/lib/gh-exec.js +8 -0
  96. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  97. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
  98. package/.agents/scripts/lib/git-utils.js +32 -20
  99. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  100. package/.agents/scripts/lib/json-utils.js +1 -2
  101. package/.agents/scripts/lib/label-constants.js +10 -38
  102. package/.agents/scripts/lib/label-taxonomy.js +10 -55
  103. package/.agents/scripts/lib/observability/active-story-env.js +44 -165
  104. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  105. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  106. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  107. package/.agents/scripts/lib/observability/source-classifier.js +5 -5
  108. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  109. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  110. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  111. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  112. package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
  113. package/.agents/scripts/lib/orchestration/code-review.js +78 -436
  114. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  115. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
  116. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  117. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  118. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  119. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  120. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  121. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  122. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  123. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  124. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  125. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
  126. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  127. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  128. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  129. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
  130. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  131. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  132. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  133. package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
  134. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  135. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  136. package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
  137. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
  138. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
  139. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  140. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  141. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
  142. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
  143. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  144. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
  145. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
  146. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
  147. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  148. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  149. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  150. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
  151. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  152. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
  153. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  154. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  155. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  156. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  157. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  158. package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
  159. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  160. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  161. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  162. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  163. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  164. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  165. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  166. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  167. package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  170. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  171. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
  172. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  173. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
  174. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  175. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  176. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
  177. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  178. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  179. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
  180. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  181. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  182. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  183. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  184. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  185. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  186. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  187. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
  188. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  189. package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
  190. package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
  191. package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
  192. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  193. package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
  194. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  195. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
  196. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
  197. package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
  198. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
  199. package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
  200. package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
  201. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  202. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  203. package/.agents/scripts/lib/planning-corpus.js +12 -281
  204. package/.agents/scripts/lib/preflight-runner.js +4 -4
  205. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  206. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  207. package/.agents/scripts/lib/signals/index.js +4 -17
  208. package/.agents/scripts/lib/signals/read.js +35 -35
  209. package/.agents/scripts/lib/signals/schema.js +8 -11
  210. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  211. package/.agents/scripts/lib/signals/write.js +0 -1
  212. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  213. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  214. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  215. package/.agents/scripts/lib/story-adjacency.js +17 -19
  216. package/.agents/scripts/lib/story-body/story-body.js +130 -75
  217. package/.agents/scripts/lib/story-plan.js +2 -4
  218. package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
  219. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  220. package/.agents/scripts/lib/test-env.js +14 -1
  221. package/.agents/scripts/lib/test-tiers.js +0 -3
  222. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
  223. package/.agents/scripts/lib/validation-evidence.js +32 -60
  224. package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
  225. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  226. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
  228. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  229. package/.agents/scripts/lint-issue-body.js +71 -40
  230. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  231. package/.agents/scripts/notify.js +4 -3
  232. package/.agents/scripts/plan-context.js +102 -80
  233. package/.agents/scripts/plan-persist.js +230 -279
  234. package/.agents/scripts/plan-run-epilogue.js +142 -0
  235. package/.agents/scripts/post-structured-comment.js +0 -38
  236. package/.agents/scripts/pr-watch-with-update.js +43 -22
  237. package/.agents/scripts/providers/github/compose.js +0 -1
  238. package/.agents/scripts/providers/github/errors.js +0 -19
  239. package/.agents/scripts/providers/github/issues.js +13 -39
  240. package/.agents/scripts/providers/github/mappers.js +5 -12
  241. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  242. package/.agents/scripts/providers/github/tickets.js +33 -156
  243. package/.agents/scripts/providers/github.js +17 -6
  244. package/.agents/scripts/resolve-stories.js +236 -0
  245. package/.agents/scripts/run-coverage.js +4 -1
  246. package/.agents/scripts/run-lint.js +2 -2
  247. package/.agents/scripts/run-verify.js +31 -2
  248. package/.agents/scripts/signals-view.js +25 -21
  249. package/.agents/scripts/single-story-close.js +178 -26
  250. package/.agents/scripts/single-story-confirm-merge.js +313 -24
  251. package/.agents/scripts/single-story-init.js +35 -30
  252. package/.agents/scripts/stories-wave-tick.js +85 -10
  253. package/.agents/scripts/story-plan.js +28 -49
  254. package/.agents/scripts/update-ticket-state.js +14 -65
  255. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  256. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  257. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  258. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  259. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  260. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  261. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  262. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  263. package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
  264. package/.agents/skills/core/scope-triage/SKILL.md +31 -172
  265. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  266. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  267. package/.agents/skills/skills.index.json +3 -53
  268. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  269. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  270. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  271. package/.agents/starter-agentrc.json +0 -5
  272. package/.agents/templates/agent-protocol.md +9 -10
  273. package/.agents/workflows/audit-architecture.md +6 -7
  274. package/.agents/workflows/audit-clean-code.md +7 -7
  275. package/.agents/workflows/audit-dependencies.md +3 -3
  276. package/.agents/workflows/audit-devops.md +3 -3
  277. package/.agents/workflows/audit-documentation.md +9 -10
  278. package/.agents/workflows/audit-lighthouse.md +11 -3
  279. package/.agents/workflows/audit-navigability.md +13 -2
  280. package/.agents/workflows/audit-performance.md +5 -6
  281. package/.agents/workflows/audit-privacy.md +3 -3
  282. package/.agents/workflows/audit-quality.md +11 -12
  283. package/.agents/workflows/audit-security.md +4 -5
  284. package/.agents/workflows/audit-seo.md +13 -3
  285. package/.agents/workflows/audit-sre.md +3 -3
  286. package/.agents/workflows/audit-to-stories.md +20 -20
  287. package/.agents/workflows/audit-ux-ui.md +10 -3
  288. package/.agents/workflows/deliver.md +177 -176
  289. package/.agents/workflows/git-cleanup.md +5 -6
  290. package/.agents/workflows/git-deliver.md +1 -1
  291. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  292. package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
  293. package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
  294. package/.agents/workflows/helpers/code-review.md +75 -196
  295. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
  296. package/.agents/workflows/helpers/deliver-story.md +606 -0
  297. package/.agents/workflows/helpers/diagnose.md +10 -10
  298. package/.agents/workflows/helpers/parallel-tooling.md +3 -3
  299. package/.agents/workflows/helpers/signals.md +16 -16
  300. package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
  301. package/.agents/workflows/mandrel-update.md +2 -1
  302. package/.agents/workflows/plan.md +277 -145
  303. package/.agents/workflows/qa-assist.md +27 -33
  304. package/.agents/workflows/qa-explore.md +29 -38
  305. package/.agents/workflows/qa-run.md +2 -6
  306. package/README.md +9 -8
  307. package/bin/mandrel.js +12 -1
  308. package/docs/CHANGELOG.md +70 -0
  309. package/lib/cli/registry.js +262 -19
  310. package/lib/cli/sync-agents.js +157 -0
  311. package/lib/cli/sync-commands.js +115 -6
  312. package/lib/cli/sync.js +168 -6
  313. package/lib/cli/update.js +105 -8
  314. package/lib/cli/version-helpers.js +131 -0
  315. package/lib/migrations/README.md +7 -5
  316. package/lib/migrations/index.js +12 -8
  317. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  318. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  319. package/package.json +2 -2
  320. package/.agents/agents/retro.md +0 -42
  321. package/.agents/personas/architect.md +0 -113
  322. package/.agents/personas/devops-engineer.md +0 -38
  323. package/.agents/personas/engineer.md +0 -33
  324. package/.agents/personas/project-manager.md +0 -114
  325. package/.agents/personas/qa-engineer.md +0 -95
  326. package/.agents/personas/security-engineer.md +0 -111
  327. package/.agents/personas/technical-writer.md +0 -101
  328. package/.agents/schemas/dispatch-manifest.json +0 -232
  329. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  330. package/.agents/schemas/epic-spec.schema.json +0 -153
  331. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  332. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  333. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  334. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  335. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  336. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  337. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  338. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  339. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  340. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  341. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  342. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  343. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  344. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  345. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  346. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  347. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  348. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  349. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  350. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  351. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  352. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  353. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  354. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  355. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  356. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  357. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  358. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  359. package/.agents/schemas/risk-verdict.schema.json +0 -66
  360. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  361. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  362. package/.agents/scripts/analyze-execution.js +0 -444
  363. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  364. package/.agents/scripts/check-prepush-recovery.js +0 -90
  365. package/.agents/scripts/dispatcher.js +0 -295
  366. package/.agents/scripts/epic-audit-prepare.js +0 -497
  367. package/.agents/scripts/epic-audit-recheck.js +0 -274
  368. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  369. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  370. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  371. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  372. package/.agents/scripts/epic-plan-clarity.js +0 -211
  373. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  374. package/.agents/scripts/epic-reconcile.js +0 -625
  375. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  376. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  377. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  378. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  379. package/.agents/scripts/lib/config/preflight.js +0 -58
  380. package/.agents/scripts/lib/config/retro.js +0 -77
  381. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  382. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  383. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  384. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  385. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  386. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
  387. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  388. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  389. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  390. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
  391. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  392. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  393. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  394. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  395. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  396. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  397. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  398. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  399. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  400. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  401. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  402. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  403. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  404. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  405. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  406. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  407. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  408. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
  409. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  410. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  411. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  412. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  413. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  414. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  415. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  416. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  417. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  418. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  419. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  420. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  421. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  422. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  423. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  424. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  425. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  426. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
  427. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  428. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  429. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  430. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  431. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  432. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  433. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  434. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  435. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  436. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  437. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  438. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  439. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  440. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  441. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  442. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  443. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  444. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  445. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  446. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  447. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  448. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  449. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  450. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  451. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  452. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  453. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  454. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  455. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  456. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  457. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  458. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  459. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  460. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  461. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
  462. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  463. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  464. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  465. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
  466. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  467. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  468. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  469. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  470. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  471. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  472. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  473. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  474. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  475. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  476. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  477. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  478. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  479. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  480. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  481. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  482. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  483. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  484. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  485. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  486. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  487. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  488. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  489. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  490. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  491. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  492. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  493. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  494. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  495. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  496. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  497. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  498. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  499. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  500. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  501. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  502. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  503. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  504. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  505. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  506. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  507. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  508. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  509. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  510. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  511. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  512. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  513. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  514. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  515. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  516. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  517. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  518. package/.agents/scripts/lib/spec/index.js +0 -36
  519. package/.agents/scripts/lib/spec/loader.js +0 -425
  520. package/.agents/scripts/lib/spec/state.js +0 -208
  521. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  522. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  523. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  524. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  525. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  526. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  527. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  528. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  529. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  530. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  531. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  532. package/.agents/scripts/lifecycle-emit.js +0 -510
  533. package/.agents/scripts/retro-run.js +0 -218
  534. package/.agents/scripts/slice-phase.js +0 -361
  535. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  536. package/.agents/scripts/story-close.js +0 -294
  537. package/.agents/scripts/story-init.js +0 -599
  538. package/.agents/scripts/story-phase.js +0 -369
  539. package/.agents/scripts/wave-tick.js +0 -464
  540. package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
  541. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  542. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  543. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  544. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  545. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  546. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  547. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  548. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  549. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  550. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  551. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  552. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  553. package/.agents/workflows/helpers/epic-audit.md +0 -189
  554. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  555. package/.agents/workflows/helpers/epic-testing.md +0 -125
  556. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  557. package/.agents/workflows/helpers/plan-epic.md +0 -353
  558. package/.agents/workflows/helpers/plan-story.md +0 -251
  559. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  560. package/.agents/workflows/helpers/single-story-deliver.md +0 -557
@@ -8,13 +8,16 @@
8
8
  *
9
9
  * The gateway is constructed with a `{ gh, owner, repo, hooks }` object so
10
10
  * cross-gateway concerns can be threaded in without bloating the constructor
11
- * signature. Today the only hooks the ticket surface reaches for are
12
- * `addSubIssue` (from the future SubIssueGateway, used by `createTicket` to
13
- * link a freshly-created child as a native sub-issue) and `addItemToProject`
14
- * (from the projects-v2 shim, used by `createTicket` to add the new issue
15
- * to the configured Project V2).
11
+ * signature. The `addItemToProject` hook (from the projects-v2 shim) adds a
12
+ * newly-created issue to the configured Project V2.
16
13
  *
17
- * Public surface: `GitHubProvider.createTicket / createIssue / getTicket /
14
+ * Story #4545 deleted `createTicket` and its `composeStoryBody` helper — the
15
+ * Epic-hierarchy write surface. It composed the exact `Epic: #N` footer that
16
+ * `pr-base-guard.js` hard-refuses at delivery, so the framework retained the
17
+ * ability to generate work it would then reject; it had no production caller
18
+ * (`/plan` persists through the bare `createIssue` below).
19
+ *
20
+ * Public surface: `GitHubProvider.createIssue / getTicket /
18
21
  * getTickets / updateTicket / getTicketDependencies / primeTicketCache /
19
22
  * invalidateTicket` all delegate to the same-named methods on this class.
20
23
  *
@@ -22,9 +25,7 @@
22
25
  */
23
26
 
24
27
  import { parseBlockedBy, parseBlocks } from '../../lib/dependency-parser.js';
25
- import { stampFrameworkVersion } from '../../lib/framework-version.js';
26
28
  import { Logger } from '../../lib/Logger.js';
27
- import { TYPE_LABELS } from '../../lib/label-constants.js';
28
29
  import { addIssueToBoard } from './board-add.js';
29
30
  import { createInlineTicketCache } from './cache.js';
30
31
  import { withTransientRetry } from './errors.js';
@@ -43,70 +44,6 @@ import {
43
44
  */
44
45
  const SEARCH_PAGE_CAP = 10;
45
46
 
46
- /**
47
- * Compose the final markdown body for a created ticket. Under the 2-tier
48
- * hierarchy (Epic → Story), `body` is always a string supplied
49
- * by the caller (the decomposer, the spec planner, or the reconciler-apply
50
- * engine). This helper appends the canonical orchestrator footer
51
- * (`parent: #<n>` / `Epic: #<m>` / `blocked by #<x>`) byte-stable with the
52
- * format consumers (manifest, close-gate, dispatcher) parse.
53
- *
54
- * Story #3186 — inlined here when the Task-tier body-renderer helpers
55
- * were retired. The structured-body (object) path is gone: Stories carry
56
- * inline `acceptance[]` / `verify[]`
57
- * arrays on the Story body authored by the decomposer; there is no
58
- * server-side rendering of a four-section payload at create time.
59
- *
60
- * Story #4382 — this is also where a Story body is stamped, once, with the
61
- * running Mandrel framework version and authoring date (hidden `mandrel_version`
62
- * / `authored_at` meta field + a visible `> 🏷️ Authored with Mandrel …`
63
- * marker) via {@link stampFrameworkVersion}. The stamp is immutable: a body
64
- * that already carries a version (e.g. a reconciler re-create) is preserved
65
- * verbatim. The `stamp` override exists for deterministic tests; production
66
- * callers omit it so the running version and today's date are used.
67
- *
68
- * @param {{
69
- * body: string,
70
- * parentId: number,
71
- * epicId?: number,
72
- * dependencies?: number[],
73
- * stamp?: { version?: string, authoredAt?: string } | false,
74
- * }} opts
75
- * @returns {string}
76
- *
77
- * Story #3958 — this is the single owner of the `blocked by #N` footer.
78
- * Callers (the reconciler-apply create path, the spec planner) pass
79
- * resolved dependency issue numbers via `dependencies` and supply a body
80
- * WITHOUT any pre-appended footer. A caller that also appends a
81
- * `blocked by` block to `body` would double every dependency line.
82
- */
83
- export function composeStoryBody({
84
- body,
85
- parentId,
86
- epicId,
87
- dependencies = [],
88
- stamp,
89
- }) {
90
- const rawHead = typeof body === 'string' ? body : '';
91
- // `stamp === false` → footer-only recomposition: the caller (the reconciler
92
- // UPDATE/diff path) owns stamp preservation itself and must NOT introduce a
93
- // fresh authoring stamp, which would churn or bump the version on every
94
- // reconcile. Every other call is a create — stamp once (immutably).
95
- const head =
96
- stamp === false ? rawHead : stampFrameworkVersion(rawHead, stamp ?? {});
97
- const lines = ['---', `parent: #${parentId}`];
98
- if (epicId !== undefined && epicId !== null) {
99
- lines.push(`Epic: #${epicId}`);
100
- }
101
- if (dependencies.length > 0) {
102
- lines.push('');
103
- for (const dep of dependencies) {
104
- lines.push(`blocked by #${dep}`);
105
- }
106
- }
107
- return `${head}\n\n${lines.join('\n')}`;
108
- }
109
-
110
47
  export class TicketGateway {
111
48
  /**
112
49
  * @param {{
@@ -114,7 +51,6 @@ export class TicketGateway {
114
51
  * owner: string,
115
52
  * repo: string,
116
53
  * hooks?: {
117
- * addSubIssue?: (parentNumber: number, childNodeId: string) => Promise<unknown>,
118
54
  * addItemToProject?: (nodeId: string) => Promise<unknown>,
119
55
  * getProjectNumber?: () => number|null,
120
56
  * },
@@ -314,84 +250,10 @@ export class TicketGateway {
314
250
  // ---------------------------------------------------------------------------
315
251
 
316
252
  /**
317
- * Create a new issue. Renders the body via the inline `composeStoryBody`
318
- * helper so the `parent: #N` / `Epic: #M` / `blocked by #X` footer is
319
- * consistent across creators.
320
- *
321
- * After the POST, opportunistically link the child as a native sub-issue
322
- * (via the `addSubIssue` hook — retried internally on the sub-issue
323
- * gateway) and add it to the configured Project V2 (best-effort —
324
- * failures warn but do not fail the create).
325
- *
326
- * @field-manifest POST /repos/{owner}/{repo}/issues: number, id, node_id,
327
- * html_url
328
- */
329
- /* node:coverage ignore next */
330
- async createTicket(parentId, ticketData) {
331
- const epicId = ticketData.epicId || parentId;
332
- const renderedBody = composeStoryBody({
333
- body: ticketData.body ?? '',
334
- parentId,
335
- epicId,
336
- dependencies: ticketData.dependencies ?? [],
337
- });
338
-
339
- // Mirror the Epic create path (issues.js:160 → `labels: TYPE_LABELS.EPIC`):
340
- // inject TYPE_LABELS.STORY so a spec that omits the labels array cannot
341
- // produce an unlabeled, undispatchable Story. Dedupe to avoid duplicates
342
- // when the caller already carries the label. (Story #4324 retired the
343
- // `context::*` ticket classes, so every ticket created through this
344
- // factory is a Story.)
345
- const callerLabels = ticketData.labels ?? [];
346
- const labels = callerLabels.includes(TYPE_LABELS.STORY)
347
- ? callerLabels
348
- : [TYPE_LABELS.STORY, ...callerLabels];
349
- const result = await this._gh.api({
350
- method: 'POST',
351
- endpoint: `/repos/${this.owner}/${this.repo}/issues`,
352
- body: {
353
- title: ticketData.title,
354
- body: renderedBody,
355
- labels,
356
- },
357
- });
358
- const issue = parseApiJson(result);
359
- this._listCache.clear();
360
-
361
- let subIssueLinked = false;
362
- let subIssueError = null;
363
- try {
364
- if (typeof this._hooks.addSubIssue === 'function') {
365
- await this._hooks.addSubIssue(parentId, issue.node_id);
366
- subIssueLinked = true;
367
- }
368
- } catch (err) {
369
- subIssueError = err;
370
- }
371
-
372
- await addIssueToBoard({
373
- nodeId: issue.node_id,
374
- issueNumber: issue.number,
375
- getProjectNumber: this._hooks.getProjectNumber,
376
- addItemToProject: this._hooks.addItemToProject,
377
- });
378
-
379
- return {
380
- id: issue.number,
381
- internalId: issue.id,
382
- nodeId: issue.node_id,
383
- url: issue.html_url,
384
- subIssueLinked,
385
- subIssueError,
386
- };
387
- }
388
-
389
- /**
390
- * Create a **bare** issue — no `parent: #N` footer composition and no
391
- * sub-issue link. Serves the standalone create paths that bypass
392
- * `createTicket`'s Story-shaped body rendering: the `/plan`
393
- * persist step and the `/plan` Phase 4 Epic open
394
- * (`openEpicFromOnePager`'s `createIssue` port).
253
+ * Create a **bare** issue no footer composition and no sub-issue link.
254
+ * Since Story #4545 this is the *only* create path: `/plan` persist and the
255
+ * `/plan` Phase 4 Epic open (`openEpicFromOnePager`'s `createIssue` port)
256
+ * both route through it.
395
257
  *
396
258
  * After the POST, the new issue is added to the configured Project V2
397
259
  * board via the shared `addIssueToBoard` helper (Story #3822) —
@@ -399,6 +261,17 @@ export class TicketGateway {
399
261
  * so board membership never depends on GitHub's "Auto-add to project"
400
262
  * built-in workflow.
401
263
  *
264
+ * The POST is wrapped in `withTransientRetry` (Story #4541) so it absorbs
265
+ * the same 502/429/ECONNRESET blips the read surfaces already do. It used
266
+ * to post bare, which made a single transient failure at story *k* of *N*
267
+ * abort `/plan` persist with `1..k-1` already live on the tracker.
268
+ *
269
+ * Retry alone is not sufficient for that failure mode — a POST whose
270
+ * response is lost would double-create on the retry — so the caller
271
+ * (`plan-persist`'s `createStoryIssues`) carries the idempotency half via
272
+ * a plan fingerprint it looks up before creating. Retry narrows the
273
+ * window; the fingerprint closes it.
274
+ *
402
275
  * @field-manifest POST /repos/{owner}/{repo}/issues: number, id, node_id,
403
276
  * html_url
404
277
  *
@@ -413,11 +286,15 @@ export class TicketGateway {
413
286
  * }>}
414
287
  */
415
288
  async createIssue({ title, body, labels = [] }) {
416
- const result = await this._gh.api({
417
- method: 'POST',
418
- endpoint: `/repos/${this.owner}/${this.repo}/issues`,
419
- body: { title, body, labels },
420
- });
289
+ const result = await withTransientRetry(
290
+ () =>
291
+ this._gh.api({
292
+ method: 'POST',
293
+ endpoint: `/repos/${this.owner}/${this.repo}/issues`,
294
+ body: { title, body, labels },
295
+ }),
296
+ { label: `createIssue "${title}"`, onRetry: defaultRetryWarn },
297
+ );
421
298
  const issue = parseApiJson(result);
422
299
  this._listCache.clear();
423
300
 
@@ -80,9 +80,23 @@ export class GitHubProvider extends ITicketingProvider {
80
80
  return this._memoizedToken;
81
81
  }
82
82
 
83
- /* node:coverage ignore next */
84
- async listIssues(filters = {}) {
85
- return this.getEpics(filters);
83
+ /**
84
+ * The identifiers a native dependency-edge writer needs, handed over as an
85
+ * explicit interface (Story #4544).
86
+ *
87
+ * `providers/github/blocked-by-add.js` talks to the dependencies REST API
88
+ * directly, so it needs the `gh` facade plus `owner`/`repo` — none of which
89
+ * the `ITicketingProvider` surface exposes. Its caller lives in the
90
+ * orchestration layer (`plan-persist/story-ops.js`), and the alternative was
91
+ * for that caller to reach through `provider._gh` — a private-by-convention
92
+ * field — from outside this module. Naming the hand-off here keeps the
93
+ * coupling declared and greppable instead of incidental: the provider
94
+ * decides what it lends out, and the field stays private.
95
+ *
96
+ * @returns {{ gh: object, owner: string, repo: string }}
97
+ */
98
+ getDependencyWriteContext() {
99
+ return { gh: this._gh, owner: this.owner, repo: this.repo };
86
100
  }
87
101
 
88
102
  static isInsufficientScopes(err) {
@@ -100,7 +114,6 @@ const DELEGATIONS = [
100
114
  ['graphql', 'issues.ghGraphql'],
101
115
  ['searchIssues', 'issues.searchIssues'],
102
116
  ['listIssuesByLabel', 'issues.listIssuesByLabel'],
103
- ['getEpics', 'issues.getEpics'],
104
117
  ['getEpic', 'issues.getEpic'],
105
118
  ['branchExists', 'issues.branchExists'],
106
119
  ['getSubTickets', 'issues.getSubTickets'],
@@ -108,12 +121,10 @@ const DELEGATIONS = [
108
121
  ['getTickets', 'tickets.getTickets'],
109
122
  ['getTicket', 'tickets.getTicket'],
110
123
  ['getTicketDependencies', 'tickets.getTicketDependencies'],
111
- ['createTicket', 'tickets.createTicket'],
112
124
  ['createIssue', 'tickets.createIssue'],
113
125
  ['updateTicket', 'tickets.updateTicket'],
114
126
  ['_applyLabelMutations', 'tickets._applyLabelMutations'],
115
127
  ['_getNativeSubIssues', 'subIssues.getNativeSubIssues'],
116
- ['_getNativeParent', 'subIssues.getNativeParent'],
117
128
  ['addSubIssue', 'subIssues.addSubIssue'],
118
129
  ['removeSubIssue', 'subIssues.removeSubIssue'],
119
130
  ['reconcileSubIssueLinks', 'subIssues.reconcileSubIssueLinks'],
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * resolve-stories.js — resolve a list of Story ids into the
5
+ * `{ stories, dag, done }` envelope `/deliver` sequences from.
6
+ *
7
+ * This is the ONE resolution step for multi-Story delivery. `/deliver` takes
8
+ * only Story ids; the graph is discovered here, from live state, rather than
9
+ * hand-transcribed by the host or implied by a batch label.
10
+ *
11
+ * What it resolves, per Story:
12
+ * - the issue itself, fetched with **state=all** so an already-landed
13
+ * sibling is present rather than silently dropped;
14
+ * - its dependency edges: the union of body-parsed `blocked by #N` /
15
+ * `depends on #N` and native GitHub `blocked_by` edges;
16
+ * - its declared file footprint, as plain path strings, so the scheduler's
17
+ * co-dispatch overlap guard has something to work with.
18
+ *
19
+ * And across the set: every dependency id — inside the requested set or
20
+ * foreign to it — is checked against live issue state, and a blocker that is
21
+ * closed or `agent::done` lands in `done[]`. That is what makes "deliver
22
+ * Stories across plan runs and over time" work: a Story whose blocker merged
23
+ * weeks ago in a different run is simply ready.
24
+ *
25
+ * Usage:
26
+ * node .agents/scripts/resolve-stories.js --ids 101,102
27
+ * node .agents/scripts/resolve-stories.js --ids 101,102 --pretty
28
+ * node .agents/scripts/resolve-stories.js --ids 101 --no-native # skip the dependencies API
29
+ *
30
+ * Exit codes: 0 ok, 1 usage/resolution error.
31
+ */
32
+
33
+ import { parseArgs } from 'node:util';
34
+
35
+ import { runAsCli } from './lib/cli-utils.js';
36
+ import { resolveConfig } from './lib/config-resolver.js';
37
+ import { Logger, routeAllOutputToStderr } from './lib/Logger.js';
38
+ import {
39
+ buildStoriesEnvelope,
40
+ isSatisfiedBlocker,
41
+ parseIds,
42
+ readNativeBlockedBy,
43
+ toStoryRecord,
44
+ } from './lib/orchestration/resolve-stories.js';
45
+ import { createProvider } from './lib/provider-factory.js';
46
+ import { concurrentMap } from './lib/util/concurrent-map.js';
47
+ import { parseApiJson } from './providers/github/request-helpers.js';
48
+
49
+ export { buildStoriesEnvelope, parseIds, readNativeBlockedBy, toStoryRecord };
50
+
51
+ /**
52
+ * Bounded concurrency for the per-issue round-trips. Matches the edge-writer's
53
+ * cap: modest enough for GitHub's secondary rate limits, while collapsing
54
+ * wall-clock from sum(round-trips) toward sum/concurrency.
55
+ */
56
+ const FETCH_CONCURRENCY = 5;
57
+
58
+ const HELP = `\
59
+ Usage:
60
+ resolve-stories.js --ids <n,n,...> [--pretty] [--no-native]
61
+
62
+ Resolve Story ids into the { stories, dag, done } envelope /deliver sequences
63
+ from. Dependencies are discovered from live state: body edges union native
64
+ blocked_by edges, with every blocker (in-set or foreign) resolved against its
65
+ real issue state.
66
+
67
+ Options:
68
+ --ids <csv> Comma-separated Story issue numbers. Required.
69
+ --pretty Pretty-print the JSON envelope.
70
+ --no-native Skip the native blocked_by read (body edges only).
71
+ --help Show this help.
72
+ `;
73
+
74
+ /**
75
+ * @param {object} [deps]
76
+ * @returns {{ provider: object, config: object }}
77
+ */
78
+ export function resolveStoriesProvider({
79
+ resolveConfigFn = resolveConfig,
80
+ createProviderFn = createProvider,
81
+ } = {}) {
82
+ const config = resolveConfigFn();
83
+ return { provider: createProviderFn(config), config };
84
+ }
85
+
86
+ /**
87
+ * Fetch every requested id and map it to a Story record, failing on the first
88
+ * id that is not a deliverable Story.
89
+ *
90
+ * @param {object} provider
91
+ * @param {number[]} ids
92
+ * @returns {Promise<object[]>}
93
+ */
94
+ export async function fetchStories(provider, ids) {
95
+ return concurrentMap(
96
+ ids,
97
+ async (id) => {
98
+ const issue = await provider.getTicket(id);
99
+ if (!issue) {
100
+ throw new Error(`[resolve-stories] Issue #${id} was not found.`);
101
+ }
102
+ return toStoryRecord(issue, id);
103
+ },
104
+ { concurrency: FETCH_CONCURRENCY },
105
+ );
106
+ }
107
+
108
+ /**
109
+ * Read native blocked_by edges for every Story in the set.
110
+ *
111
+ * @returns {Promise<Map<number, number[]>>}
112
+ */
113
+ export async function readNativeEdges({ provider, stories, owner, repo }) {
114
+ const entries = await concurrentMap(
115
+ stories,
116
+ async (story) => [
117
+ story.id,
118
+ await readNativeBlockedBy({
119
+ gh: provider._gh,
120
+ owner,
121
+ repo,
122
+ issueNumber: story.id,
123
+ parseJson: parseApiJson,
124
+ }),
125
+ ],
126
+ { concurrency: FETCH_CONCURRENCY },
127
+ );
128
+ return new Map(entries);
129
+ }
130
+
131
+ /**
132
+ * Resolve dependency ids that are NOT in the requested set against live issue
133
+ * state. A foreign blocker that already landed must enter `done[]`, or the
134
+ * scheduler withholds its dependent forever — the exact wedge that made
135
+ * cross-run delivery impossible.
136
+ *
137
+ * A foreign id that cannot be read is left OUT of `done[]`: unknown means
138
+ * "still gating", which withholds the dependent rather than dispatching it
139
+ * against a possibly-unlanded blocker.
140
+ *
141
+ * @returns {Promise<number[]>}
142
+ */
143
+ export async function resolveForeignDone({ provider, dag, inSetIds }) {
144
+ const foreign = [
145
+ ...new Set(
146
+ dag.flatMap((node) => node.dependsOn).filter((dep) => !inSetIds.has(dep)),
147
+ ),
148
+ ];
149
+ if (foreign.length === 0) return [];
150
+ const resolved = await concurrentMap(
151
+ foreign,
152
+ async (id) => {
153
+ try {
154
+ const issue = await provider.getTicket(id);
155
+ return isSatisfiedBlocker(issue) ? id : null;
156
+ } catch (err) {
157
+ Logger.warn(
158
+ `[resolve-stories] Could not read foreign blocker #${id} (${err?.message ?? err}) — ` +
159
+ `treating it as still gating.`,
160
+ );
161
+ return null;
162
+ }
163
+ },
164
+ { concurrency: FETCH_CONCURRENCY },
165
+ );
166
+ return resolved.filter((id) => id !== null);
167
+ }
168
+
169
+ async function main() {
170
+ const { values } = parseArgs({
171
+ options: {
172
+ ids: { type: 'string' },
173
+ pretty: { type: 'boolean', default: false },
174
+ native: { type: 'boolean', default: true },
175
+ help: { type: 'boolean', default: false },
176
+ },
177
+ // The documented opt-out is `--no-native`; without allowNegative,
178
+ // parseArgs rejects it as an unknown option and the CLI has no working
179
+ // way to skip the dependencies API.
180
+ allowNegative: true,
181
+ allowPositionals: false,
182
+ });
183
+
184
+ if (values.help) {
185
+ process.stdout.write(HELP);
186
+ return 0;
187
+ }
188
+ if (!values.ids) {
189
+ process.stderr.write(HELP);
190
+ throw new Error('[resolve-stories] --ids <n,n,...> is required');
191
+ }
192
+
193
+ // stdout is a JSON stream — keep human-readable output on stderr so a
194
+ // headless caller can pipe this straight into stories-wave-tick.js.
195
+ routeAllOutputToStderr();
196
+
197
+ const ids = parseIds(values.ids);
198
+ const { provider, config } = resolveStoriesProvider();
199
+ const owner = config.github?.owner;
200
+ const repo = config.github?.repo;
201
+
202
+ const stories = await fetchStories(provider, ids);
203
+ const nativeEdges = values.native
204
+ ? await readNativeEdges({ provider, stories, owner, repo })
205
+ : new Map();
206
+
207
+ const inSetIds = new Set(stories.map((s) => s.id));
208
+ const provisional = buildStoriesEnvelope({
209
+ stories,
210
+ nativeEdges,
211
+ warn: (m) => Logger.warn(m),
212
+ });
213
+ const foreignDone = await resolveForeignDone({
214
+ provider,
215
+ dag: provisional.dag,
216
+ inSetIds,
217
+ });
218
+ const envelope = buildStoriesEnvelope({
219
+ stories,
220
+ nativeEdges,
221
+ foreignDone,
222
+ warn: () => {},
223
+ });
224
+
225
+ process.stdout.write(
226
+ values.pretty
227
+ ? `${JSON.stringify(envelope, null, 2)}\n`
228
+ : `${JSON.stringify(envelope)}\n`,
229
+ );
230
+ return 0;
231
+ }
232
+
233
+ runAsCli(import.meta.url, main, {
234
+ source: 'resolve-stories',
235
+ propagateExitCode: true,
236
+ });
@@ -45,6 +45,7 @@ import { fileURLToPath } from 'node:url';
45
45
 
46
46
  import { cleanupRepoTestTempArtifacts } from './cleanup-repo-test-temp.js';
47
47
  import { C8_CLI } from './lib/c8-cli-path.js';
48
+ import { buildWebhookSafeTestEnv } from './lib/test-env.js';
48
49
  import { TEST_RUNNER_FLAGS } from './run-tests.js';
49
50
 
50
51
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -89,7 +90,9 @@ function runCoveragePipeline() {
89
90
  const testRun = spawnSync(process.execPath, buildCoverageTestArgs(), {
90
91
  cwd: ROOT,
91
92
  stdio: 'inherit',
92
- env: { ...process.env, NODE_V8_COVERAGE: V8_TMP },
93
+ // GIT_*-scrubbed: under a husky pre-push from a linked worktree the
94
+ // inherited GIT_DIR poisons fixture `git init` runs (#4580).
95
+ env: { ...buildWebhookSafeTestEnv(process.env), NODE_V8_COVERAGE: V8_TMP },
93
96
  });
94
97
 
95
98
  cleanupRepoTestTempArtifacts({ repoRoot: ROOT });
@@ -73,8 +73,8 @@ const tasks = [
73
73
  // spans for axis-shaped tokens (`type/epic`, etc.) and asserts
74
74
  // only the canonical `<axis>::<value>` separator from
75
75
  // `lib/label-constants.js` appears. Closes the drift gap that
76
- // let the original `type/epic` typo land at
77
- // `.agents/workflows/helpers/plan-epic.md:49`.
76
+ // let the original `type/epic` typo land in a since-retired
77
+ // planning workflow helper.
78
78
  name: 'label-vocabulary',
79
79
  cmd: 'node',
80
80
  args: ['.agents/scripts/lint-label-vocabulary.js'],
@@ -5,14 +5,28 @@
5
5
  * Local full verification — a true CI mirror for the gates that CAN be proven
6
6
  * locally, without epic-scoped MI projection or push semantics.
7
7
  *
8
- * Order: audit (SCA) → lint (includes docs:check) full test suite
9
- * unified baselines.
8
+ * Order: audit (SCA) → lint (includes docs:check + the arch-cycles ratchet)
9
+ * full test suite → unified baselines → the dead-exports and context-budget
10
+ * ratchets.
10
11
  *
11
12
  * The `audit` step runs `npm audit --audit-level=high`, matching CI's
12
13
  * "Dependency Vulnerability Audit (SCA)" gate so a local green no longer hides
13
14
  * a high-severity advisory that CI would fail on. It is independent of the
14
15
  * pre-push `PREPUSH_AUDIT` opt-in, which stays unchanged.
15
16
  *
17
+ * The trailing ratchets complete the mirror of CI's "Architecture Cycle Check"
18
+ * step in the `baselines` job (Story #4549). That step runs three checks;
19
+ * `check-arch-cycles.js` is deliberately absent from STEPS because the `lint`
20
+ * step above already runs it (see run-lint.js) — re-running it here would
21
+ * double-pay a gate verify already covers. `check-dead-exports.js` and
22
+ * `check-context-budget.js` had no such cover: they were reachable locally only
23
+ * via the diff-scoped `npm run quality:preview` or a direct invocation, so a
24
+ * clean `verify` could still hide a CI-red — the failure Story #4531 / PR #4548
25
+ * paid for with a full push → CI → fix → push round-trip. Both are pure-Node
26
+ * and baseline-aware, adding ~15s on a cold cache (dominated by knip's
27
+ * full-tree scan in check-dead-exports.js) to a command that already carries
28
+ * the full test suite.
29
+ *
16
30
  * A handful of CI gates cannot be reproduced by this command (action pinning,
17
31
  * TruffleHog secret scan, the BASELINE_SCOPE=full push-scoped maintainability
18
32
  * run) — those are catalogued in docs/ci-contract.md.
@@ -34,6 +48,21 @@ const STEPS = [
34
48
  cmd: 'node',
35
49
  args: ['.agents/scripts/check-baselines.js'],
36
50
  },
51
+ {
52
+ label: 'dead-exports',
53
+ cmd: 'node',
54
+ args: ['.agents/scripts/check-dead-exports.js'],
55
+ },
56
+ {
57
+ label: 'dead-exports-production',
58
+ cmd: 'node',
59
+ args: ['.agents/scripts/check-dead-exports.js', '--production'],
60
+ },
61
+ {
62
+ label: 'context-budget',
63
+ cmd: 'node',
64
+ args: ['.agents/scripts/check-context-budget.js'],
65
+ },
37
66
  ];
38
67
 
39
68
  export function runVerifySteps({