mandrel 1.93.0 → 2.0.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 (463) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/acceptance-critic.md +129 -0
  3. package/.agents/agents/story-worker.md +161 -0
  4. package/.agents/docs/SDLC.md +489 -1285
  5. package/.agents/docs/agentrc-reference.json +177 -67
  6. package/.agents/docs/configuration.md +108 -136
  7. package/.agents/docs/execution-reference.md +44 -22
  8. package/.agents/docs/quality-gates.md +13 -19
  9. package/.agents/docs/workflows.md +3 -3
  10. package/.agents/instructions.md +107 -108
  11. package/.agents/rules/ci-remediation.md +8 -12
  12. package/.agents/rules/git-conventions-reference.md +224 -0
  13. package/.agents/rules/git-conventions.md +42 -223
  14. package/.agents/rules/security-baseline.md +5 -0
  15. package/.agents/rules/testing-standards.md +106 -13
  16. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  17. package/.agents/schemas/agentrc.schema.json +71 -201
  18. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  20. package/.agents/schemas/risk-verdict.schema.json +0 -13
  21. package/.agents/scripts/acceptance-eval.js +62 -18
  22. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  23. package/.agents/scripts/analyze-execution.js +1 -1
  24. package/.agents/scripts/audit-to-stories.js +7 -7
  25. package/.agents/scripts/boot-sweep.js +1 -1
  26. package/.agents/scripts/check-context-budget.js +62 -5
  27. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  28. package/.agents/scripts/check-prepush-recovery.js +1 -1
  29. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  30. package/.agents/scripts/diagnose-friction.js +0 -6
  31. package/.agents/scripts/lib/Logger.js +6 -10
  32. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  33. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  34. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  35. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  36. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  37. package/.agents/scripts/lib/baselines/reader.js +1 -6
  38. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  39. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  40. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
  41. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  42. package/.agents/scripts/lib/checks/index.js +2 -1
  43. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  44. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  45. package/.agents/scripts/lib/cli-args.js +16 -7
  46. package/.agents/scripts/lib/close-validation/gates.js +160 -22
  47. package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
  48. package/.agents/scripts/lib/config/ci.js +6 -31
  49. package/.agents/scripts/lib/config/delivery-routing.js +103 -0
  50. package/.agents/scripts/lib/config/explain.js +57 -36
  51. package/.agents/scripts/lib/config/limits.js +17 -58
  52. package/.agents/scripts/lib/config/paths.js +0 -2
  53. package/.agents/scripts/lib/config/quality.js +1 -1
  54. package/.agents/scripts/lib/config/runners.js +17 -50
  55. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  56. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  57. package/.agents/scripts/lib/config-resolver.js +3 -8
  58. package/.agents/scripts/lib/config-settings-schema-delivery.js +46 -136
  59. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -14
  60. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  61. package/.agents/scripts/lib/dependency-parser.js +3 -2
  62. package/.agents/scripts/lib/doc-tiers.js +39 -4
  63. package/.agents/scripts/lib/duplicate-search.js +211 -41
  64. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  65. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  66. package/.agents/scripts/lib/framework-version.js +2 -3
  67. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  68. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  69. package/.agents/scripts/lib/git-utils.js +32 -6
  70. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  71. package/.agents/scripts/lib/label-constants.js +10 -23
  72. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  73. package/.agents/scripts/lib/observability/active-story-env.js +112 -3
  74. package/.agents/scripts/lib/observability/hook-heartbeat.js +187 -0
  75. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  76. package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
  77. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  78. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
  79. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
  80. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  81. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +273 -0
  82. package/.agents/scripts/lib/orchestration/ceremony-routing.js +204 -0
  83. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  84. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  85. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  86. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  87. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  88. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  89. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  90. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  91. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  92. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  93. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  94. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  95. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  96. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  97. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  98. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
  99. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  100. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  101. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  102. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  103. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  104. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  105. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  106. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  107. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  108. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +14 -14
  109. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  110. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  111. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  112. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  113. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  114. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  115. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  116. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  117. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  118. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  119. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  120. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  121. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  122. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  123. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  124. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  125. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  126. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
  127. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  128. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  129. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  130. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  131. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  132. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  133. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  134. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  135. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  136. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  137. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  138. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  139. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  140. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  141. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  142. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  143. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  144. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  145. package/.agents/scripts/lib/orchestration/ticket-validator.js +3 -8
  146. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  147. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  148. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  149. package/.agents/scripts/lib/planning-corpus.js +16 -11
  150. package/.agents/scripts/lib/preflight-runner.js +2 -2
  151. package/.agents/scripts/lib/provider-factory.js +1 -1
  152. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  153. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  154. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  155. package/.agents/scripts/lib/story-adjacency.js +11 -14
  156. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  157. package/.agents/scripts/lib/story-plan.js +2 -4
  158. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  159. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  160. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  161. package/.agents/scripts/lib/validation-evidence.js +1 -1
  162. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  163. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  164. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  165. package/.agents/scripts/lint-issue-body.js +71 -40
  166. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  167. package/.agents/scripts/notify.js +4 -3
  168. package/.agents/scripts/plan-context.js +64 -74
  169. package/.agents/scripts/plan-persist.js +121 -280
  170. package/.agents/scripts/plan-run-epilogue.js +97 -0
  171. package/.agents/scripts/post-structured-comment.js +38 -0
  172. package/.agents/scripts/providers/github/issues.js +17 -33
  173. package/.agents/scripts/providers/github/mappers.js +0 -12
  174. package/.agents/scripts/providers/github/tickets.js +2 -5
  175. package/.agents/scripts/resolve-plan-run.js +117 -0
  176. package/.agents/scripts/signals-view.js +24 -19
  177. package/.agents/scripts/single-story-close.js +11 -14
  178. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  179. package/.agents/scripts/single-story-init.js +29 -20
  180. package/.agents/scripts/stories-wave-tick.js +6 -6
  181. package/.agents/scripts/story-plan.js +26 -47
  182. package/.agents/scripts/sync-claude-agents.js +165 -0
  183. package/.agents/scripts/update-ticket-state.js +37 -15
  184. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  185. package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
  186. package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
  187. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
  188. package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
  189. package/.agents/skills/core/idea-refinement/SKILL.md +8 -14
  190. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
  191. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  192. package/.agents/skills/skills.index.json +8 -418
  193. package/.agents/starter-agentrc.json +0 -5
  194. package/.agents/templates/agent-protocol.md +9 -10
  195. package/.agents/workflows/audit-architecture.md +3 -3
  196. package/.agents/workflows/audit-clean-code.md +3 -3
  197. package/.agents/workflows/audit-dependencies.md +3 -3
  198. package/.agents/workflows/audit-devops.md +3 -3
  199. package/.agents/workflows/audit-documentation.md +5 -5
  200. package/.agents/workflows/audit-lighthouse.md +3 -3
  201. package/.agents/workflows/audit-navigability.md +3 -2
  202. package/.agents/workflows/audit-performance.md +3 -3
  203. package/.agents/workflows/audit-privacy.md +3 -3
  204. package/.agents/workflows/audit-quality.md +3 -3
  205. package/.agents/workflows/audit-security.md +3 -3
  206. package/.agents/workflows/audit-seo.md +3 -3
  207. package/.agents/workflows/audit-sre.md +3 -3
  208. package/.agents/workflows/audit-to-stories.md +20 -20
  209. package/.agents/workflows/audit-ux-ui.md +3 -3
  210. package/.agents/workflows/deliver.md +122 -131
  211. package/.agents/workflows/git-cleanup.md +3 -4
  212. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  213. package/.agents/workflows/helpers/acceptance-self-eval.md +52 -40
  214. package/.agents/workflows/helpers/code-review.md +70 -193
  215. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  216. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  217. package/.agents/workflows/helpers/diagnose.md +10 -10
  218. package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
  219. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  220. package/.agents/workflows/helpers/signals.md +16 -16
  221. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  222. package/.agents/workflows/mandrel-update.md +3 -2
  223. package/.agents/workflows/plan.md +112 -145
  224. package/.agents/workflows/qa-assist.md +24 -30
  225. package/.agents/workflows/qa-explore.md +29 -38
  226. package/.agents/workflows/qa-run.md +2 -2
  227. package/README.md +9 -8
  228. package/docs/CHANGELOG.md +46 -0
  229. package/lib/cli/registry.js +95 -0
  230. package/lib/migrations/index.js +6 -5
  231. package/package.json +5 -3
  232. package/.agents/personas/architect.md +0 -113
  233. package/.agents/personas/devops-engineer.md +0 -38
  234. package/.agents/personas/engineer-mobile.md +0 -120
  235. package/.agents/personas/engineer-web.md +0 -111
  236. package/.agents/personas/engineer.md +0 -119
  237. package/.agents/personas/product.md +0 -94
  238. package/.agents/personas/project-manager.md +0 -114
  239. package/.agents/personas/qa-engineer.md +0 -95
  240. package/.agents/personas/refactorer.md +0 -113
  241. package/.agents/personas/security-engineer.md +0 -112
  242. package/.agents/personas/sre.md +0 -86
  243. package/.agents/personas/technical-writer.md +0 -101
  244. package/.agents/personas/ux-designer.md +0 -95
  245. package/.agents/schemas/dispatch-manifest.json +0 -232
  246. package/.agents/schemas/epic-spec.schema.json +0 -153
  247. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  248. package/.agents/scripts/dispatcher.js +0 -295
  249. package/.agents/scripts/epic-audit-prepare.js +0 -497
  250. package/.agents/scripts/epic-audit-recheck.js +0 -274
  251. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  252. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  253. package/.agents/scripts/epic-deliver-prepare.js +0 -590
  254. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  255. package/.agents/scripts/epic-plan-clarity.js +0 -211
  256. package/.agents/scripts/epic-plan-decompose.js +0 -54
  257. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  258. package/.agents/scripts/epic-plan-spec.js +0 -64
  259. package/.agents/scripts/epic-reconcile.js +0 -625
  260. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  261. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  262. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  263. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  264. package/.agents/scripts/lib/config/preflight.js +0 -58
  265. package/.agents/scripts/lib/config/retro.js +0 -77
  266. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  267. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  268. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  269. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -660
  270. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  271. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  272. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  273. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  274. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  275. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  276. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  277. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  278. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  279. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  280. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  281. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  282. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  283. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  284. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  285. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  286. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  287. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  288. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -388
  289. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  290. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  291. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  292. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  293. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  294. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  295. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  296. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  297. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  298. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  299. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  300. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  301. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  302. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  303. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  304. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  305. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  306. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  307. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  308. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  309. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  310. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  311. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  313. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -384
  314. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  315. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  316. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  317. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -278
  318. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  319. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  320. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  321. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  322. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  323. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  324. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  325. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  326. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  327. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  328. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  329. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  330. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  331. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  332. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  333. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  334. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  335. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
  336. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  337. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  338. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  339. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  340. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  341. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  342. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  343. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  344. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  345. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  346. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  347. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  348. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  349. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  350. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  351. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  352. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  353. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  354. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  355. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  356. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  357. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  358. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  359. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  360. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  361. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -301
  362. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  363. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  364. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  365. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  366. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  367. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  368. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  369. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  370. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  371. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  372. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  373. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  374. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  375. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  376. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  377. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  378. package/.agents/scripts/lib/spec/index.js +0 -36
  379. package/.agents/scripts/lib/spec/loader.js +0 -425
  380. package/.agents/scripts/lib/spec/state.js +0 -208
  381. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  382. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  383. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  384. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  385. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  386. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  387. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  388. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  389. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  390. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  391. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  392. package/.agents/scripts/lifecycle-emit.js +0 -510
  393. package/.agents/scripts/plan-critics.js +0 -199
  394. package/.agents/scripts/retro-run.js +0 -218
  395. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  396. package/.agents/scripts/story-close.js +0 -294
  397. package/.agents/scripts/story-init.js +0 -599
  398. package/.agents/scripts/story-phase.js +0 -369
  399. package/.agents/scripts/wave-tick.js +0 -335
  400. package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
  401. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
  402. package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
  403. package/.agents/skills/core/code-simplification/SKILL.md +0 -389
  404. package/.agents/skills/core/context-engineering/SKILL.md +0 -309
  405. package/.agents/skills/core/context-engineering/examples.md +0 -58
  406. package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
  407. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  408. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  409. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  410. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  411. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  412. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  413. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -413
  414. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  415. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
  416. package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
  417. package/.agents/skills/core/idea-refinement/examples.md +0 -437
  418. package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
  419. package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
  420. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
  421. package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
  422. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
  423. package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
  424. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
  425. package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
  426. package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
  427. package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
  428. package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
  429. package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
  430. package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
  431. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
  432. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
  433. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
  434. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
  435. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
  436. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
  437. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
  438. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
  439. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
  440. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
  441. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
  442. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
  443. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
  444. package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
  445. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
  446. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
  447. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
  448. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
  449. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
  450. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
  451. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
  452. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
  453. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -534
  454. package/.agents/workflows/helpers/deliver-epic.md +0 -955
  455. package/.agents/workflows/helpers/deliver-stories.md +0 -440
  456. package/.agents/workflows/helpers/epic-audit.md +0 -189
  457. package/.agents/workflows/helpers/epic-deliver-story.md +0 -427
  458. package/.agents/workflows/helpers/epic-testing.md +0 -125
  459. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  460. package/.agents/workflows/helpers/plan-epic.md +0 -351
  461. package/.agents/workflows/helpers/plan-story.md +0 -251
  462. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  463. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,310 +0,0 @@
1
- /**
2
- * epic-deliver-lease-guard.js — preflight guards for `/deliver`
3
- * (Story #3482, Epic #3457).
4
- *
5
- * `/deliver`'s prepare phase used to checkout `epic/<id>` over whatever
6
- * the operator had checked out, yanking HEAD and resetting baselines under a
7
- * live working session (the documented "epic-deliver shares the main checkout"
8
- * footgun). This module supplies the two preflight guards the Tech Spec
9
- * (#3476) wires into `epic-deliver-prepare.js` *before* any mutating git work:
10
- *
11
- * 1. **Epic-lease preflight.** Acquire the assignee-as-lease on the Epic
12
- * ticket via `ticket-lease.acquireLease`. On a live foreign claim the
13
- * guard **fails closed** — it throws a clear, operator-facing error that
14
- * names the current owner (the `critical-workflow` risk axis demands
15
- * refuse-and-exit, never warn-and-continue). `--steal` is the only
16
- * override.
17
- * 2. **Checkout-safety preflight.** Refuse to start when the working tree is
18
- * dirty or HEAD is on a branch other than the expected one, instead of
19
- * checking `epic/<id>` out over the operator's work.
20
- *
21
- * Both guards are pure over injected seams (a `git` shim with
22
- * `statusPorcelain` / `currentBranch`, and the lease provider) so the unit
23
- * suite exercises them without standing up a real repo or hitting GitHub.
24
- * Liveness is threaded in via `heartbeatAt` exactly as `ticket-lease.js`
25
- * documents — this module does not read the lifecycle ledger itself.
26
- *
27
- * Per `.agents/rules/orchestration-error-handling.md`, the composed guard
28
- * surfaces unrecoverable failures with `throw new Error(...)` (mapped to
29
- * `process.exit(1)` by the `runAsCli` boundary), never `Logger.fatal`.
30
- */
31
-
32
- import {
33
- acquireLeaseFailClosed,
34
- resolveOperatorFromCandidates,
35
- } from './lease-guard-shared.js';
36
-
37
- /**
38
- * Resolve the acquiring operator's identity. Precedence (Tech Spec #3476):
39
- * 1. An explicit `--as <handle>` flag.
40
- * 2. `github.operatorHandle` in `.agentrc.json`.
41
- * 3. The local `git config user.email`.
42
- *
43
- * The `@`-prefix some operators carry on `operatorHandle` is stripped (via
44
- * the shared lease-guard kernel) so the value matches the bare login written
45
- * to a ticket's `assignees`. This surface's missing-handle policy is `'null'`
46
- * — `runPrepareGuards` fails closed on a null operator with deliver-specific
47
- * wording after the (cheap, local) checkout-safety guard has run.
48
- *
49
- * @param {object} args
50
- * @param {string} [args.asFlag] Explicit `--as` value.
51
- * @param {object} [args.config] Resolved config (reads github.operatorHandle).
52
- * @param {string} [args.gitUserEmail] Fallback `git config user.email`.
53
- * @returns {string|null} The resolved operator handle, or null when none could
54
- * be determined.
55
- */
56
- export function resolveOperator({ asFlag, config, gitUserEmail } = {}) {
57
- return resolveOperatorFromCandidates({
58
- candidates: [asFlag, config?.github?.operatorHandle, gitUserEmail],
59
- });
60
- }
61
-
62
- /**
63
- * Normalise the expected-branch argument into a non-empty list. `/deliver`
64
- * may legitimately start from either the Epic integration branch (`epic/<id>`,
65
- * on a resume) or the project base branch (`main`, on a fresh run), so the
66
- * guard accepts a set rather than a single name.
67
- *
68
- * @param {string|string[]} expectedBranch
69
- * @returns {string[]}
70
- */
71
- function normaliseExpectedBranches(expectedBranch) {
72
- const list = (
73
- Array.isArray(expectedBranch) ? expectedBranch : [expectedBranch]
74
- ).filter((b) => typeof b === 'string' && b.length > 0);
75
- if (list.length === 0) {
76
- throw new Error('checkCheckoutSafety: expectedBranch is required');
77
- }
78
- return list;
79
- }
80
-
81
- /**
82
- * Pure checkout-safety classifier. The working tree must be clean and HEAD
83
- * must sit on one of `expectedBranch` before prepare moves anything.
84
- *
85
- * @param {object} args
86
- * @param {object} args.git Injected git shim.
87
- * @param {() => { dirty: boolean, entries?: string }} args.git.statusPorcelain
88
- * Returns whether the tree has uncommitted/untracked changes.
89
- * @param {() => string|null} args.git.currentBranch Returns HEAD's branch (or
90
- * null in detached-HEAD state).
91
- * @param {string|string[]} args.expectedBranch The branch (or branches)
92
- * prepare expects HEAD on (typically `epic/<id>` or the project base branch).
93
- * @returns {{
94
- * safe: boolean,
95
- * reason: 'clean'|'dirty'|'wrong-branch'|'detached-head',
96
- * currentBranch: string|null,
97
- * expectedBranches: string[],
98
- * dirtyEntries?: string,
99
- * }}
100
- */
101
- export function checkCheckoutSafety({ git, expectedBranch }) {
102
- if (!git || typeof git.statusPorcelain !== 'function') {
103
- throw new Error(
104
- 'checkCheckoutSafety: git shim with statusPorcelain/currentBranch is required',
105
- );
106
- }
107
- const expectedBranches = normaliseExpectedBranches(expectedBranch);
108
-
109
- const status = git.statusPorcelain();
110
- if (status?.dirty) {
111
- return {
112
- safe: false,
113
- reason: 'dirty',
114
- currentBranch: git.currentBranch(),
115
- expectedBranches,
116
- dirtyEntries: status.entries,
117
- };
118
- }
119
-
120
- const branch = git.currentBranch();
121
- if (branch === null || branch === undefined || branch === '') {
122
- return {
123
- safe: false,
124
- reason: 'detached-head',
125
- currentBranch: null,
126
- expectedBranches,
127
- };
128
- }
129
- if (!expectedBranches.includes(branch)) {
130
- return {
131
- safe: false,
132
- reason: 'wrong-branch',
133
- currentBranch: branch,
134
- expectedBranches,
135
- };
136
- }
137
- return {
138
- safe: true,
139
- reason: 'clean',
140
- currentBranch: branch,
141
- expectedBranches,
142
- };
143
- }
144
-
145
- /**
146
- * Render the operator-facing message for a failed checkout-safety guard.
147
- *
148
- * @param {ReturnType<typeof checkCheckoutSafety>} result
149
- * @returns {string}
150
- */
151
- export function renderCheckoutRefusal(result) {
152
- const expected = result.expectedBranches.map((b) => `'${b}'`).join(' or ');
153
- if (result.reason === 'dirty') {
154
- return (
155
- `[epic-deliver] Refusing to start: the working tree is dirty. ` +
156
- `/deliver will not check out ${expected} over uncommitted ` +
157
- `or untracked changes — commit, stash, or clean them, then re-run.\n` +
158
- `--- dirty entries ---\n${result.dirtyEntries ?? '(unavailable)'}`
159
- );
160
- }
161
- if (result.reason === 'detached-head') {
162
- return (
163
- `[epic-deliver] Refusing to start: HEAD is detached. /deliver ` +
164
- `expects HEAD on ${expected}. Check one out before re-running.`
165
- );
166
- }
167
- return (
168
- `[epic-deliver] Refusing to start: HEAD is on '${result.currentBranch}', ` +
169
- `not the expected ${expected}. /deliver will not yank HEAD ` +
170
- `away from your branch — switch to ${expected} yourself before re-running.`
171
- );
172
- }
173
-
174
- /**
175
- * Render the operator-facing message for a refused (live foreign) lease.
176
- *
177
- * @param {{ owner: string|null }} lease
178
- * @param {number} epicId
179
- * @returns {string}
180
- */
181
- export function renderLeaseRefusal(lease, epicId) {
182
- return (
183
- `[epic-deliver] Refusing to start: Epic #${epicId} is already claimed by ` +
184
- `'${lease.owner}' with a live lease (recent heartbeat within the TTL). ` +
185
- `Another /deliver run is driving this Epic. Wait for it to finish, ` +
186
- `or pass --steal to forcibly transfer the claim.`
187
- );
188
- }
189
-
190
- /**
191
- * Acquire the Epic lease for `operator`, failing closed on a live foreign
192
- * claim. Returns the `acquireLease` result on success.
193
- *
194
- * @param {object} args
195
- * @param {object} args.provider Ticketing provider.
196
- * @param {number} args.epicId Epic ticket id.
197
- * @param {string} args.operator Resolved operator handle.
198
- * @param {number|null} [args.heartbeatAt] Current owner's last heartbeat (epoch ms).
199
- * @param {boolean} [args.steal=false] Transfer a live foreign claim.
200
- * @param {object} [args.config] Resolved config (TTL default).
201
- * @param {number} [args.now] Injectable clock.
202
- * @returns {Promise<{ acquired: boolean, owner: string, previousOwner: string|null, reason: string }>}
203
- * @throws {Error} when the Epic carries a live foreign claim and `steal` is false.
204
- */
205
- export async function acquireEpicLease({
206
- provider,
207
- epicId,
208
- operator,
209
- heartbeatAt = null,
210
- steal = false,
211
- config,
212
- now,
213
- }) {
214
- return acquireLeaseFailClosed({
215
- provider,
216
- ticketId: epicId,
217
- operator,
218
- heartbeatAt,
219
- steal,
220
- config,
221
- now,
222
- renderRefusal: renderLeaseRefusal,
223
- });
224
- }
225
-
226
- /**
227
- * Compose the two preflight guards in the order prepare needs them: the
228
- * checkout-safety check first (cheap, local, no network), then the Epic-lease
229
- * acquisition (a GitHub round-trip). Both fail closed by throwing.
230
- *
231
- * The checkout-safety guard runs first (cheap, local) and always executes. The
232
- * Epic-lease step then **fails closed**: when `operator` cannot be resolved
233
- * (null — `--as`, `github.operatorHandle`, and `git user.email` all empty, with
234
- * the shipped `@[USERNAME]` placeholder normalised to null), this throws rather
235
- * than running an ownerless, unguarded delivery. The lease is the cross-clone
236
- * coordination layer; without an identity it cannot serialise concurrent runs,
237
- * so silently skipping it would defeat the guard.
238
- *
239
- * @param {object} args
240
- * @param {number} args.epicId
241
- * @param {string|string[]} args.expectedBranch Branch(es) prepare expects HEAD on.
242
- * @param {object} args.git Injected git shim (statusPorcelain/currentBranch).
243
- * @param {object} args.provider Ticketing provider for the lease.
244
- * @param {string|null} args.operator Resolved operator handle (null fails closed → throw).
245
- * @param {number|null} [args.heartbeatAt] Current owner's last heartbeat (epoch ms).
246
- * @param {boolean} [args.steal=false] Transfer a live foreign claim.
247
- * @param {object} [args.config] Resolved config.
248
- * @param {number} [args.now] Injectable clock.
249
- * @param {object} [args.logger] Logger with info/warn.
250
- * @returns {Promise<{
251
- * checkout: ReturnType<typeof checkCheckoutSafety>,
252
- * lease: { acquired: boolean, owner: string, reason: string },
253
- * }>}
254
- * @throws {Error} on a dirty/wrong-branch tree, an unresolvable operator
255
- * identity, or a refused live foreign lease.
256
- */
257
- export async function runPrepareGuards({
258
- epicId,
259
- expectedBranch,
260
- git,
261
- provider,
262
- operator,
263
- heartbeatAt = null,
264
- steal = false,
265
- config,
266
- now,
267
- logger,
268
- }) {
269
- const log = logger ?? { info: () => {}, warn: () => {} };
270
-
271
- const checkout = checkCheckoutSafety({ git, expectedBranch });
272
- if (!checkout.safe) {
273
- throw new Error(renderCheckoutRefusal(checkout));
274
- }
275
- log.info?.(
276
- `[epic-deliver] ✅ Checkout-safety guard passed (clean tree on '${checkout.currentBranch}').`,
277
- );
278
-
279
- if (!operator) {
280
- throw new Error(
281
- '[epic-deliver] Refusing to start: no operator identity could be ' +
282
- 'resolved. --as, github.operatorHandle (unset or still the shipped ' +
283
- '`@[USERNAME]` placeholder), and git user.email are all empty, so the ' +
284
- 'Epic-lease has no owner and concurrent /deliver runs cannot be ' +
285
- 'serialised. Set your own handle in .agentrc.local.json (e.g. ' +
286
- '{ "github": { "operatorHandle": "@your-login" } }), pass --as <handle>, ' +
287
- 'or configure git user.email, then re-run.',
288
- );
289
- }
290
-
291
- const lease = await acquireEpicLease({
292
- provider,
293
- epicId,
294
- operator,
295
- heartbeatAt,
296
- steal,
297
- config,
298
- now,
299
- });
300
- if (lease.reason === 'stolen') {
301
- log.warn?.(
302
- `[epic-deliver] ⚠️ Stole the Epic #${epicId} lease from '${lease.previousOwner}' via --steal (live claim forcibly transferred).`,
303
- );
304
- } else {
305
- log.info?.(
306
- `[epic-deliver] ✅ Acquired Epic #${epicId} lease for '${operator}' (reason=${lease.reason}).`,
307
- );
308
- }
309
- return { checkout, lease };
310
- }
@@ -1,163 +0,0 @@
1
- /**
2
- * context.js — Phase 3 of the epic-plan-decompose pipeline (Story #2466).
3
- *
4
- * Builds the authoring context (the Epic body — which carries the folded
5
- * Tech Spec sections and Acceptance Table per Story #4324 — plus
6
- * heuristics, system prompt, ticket cap) the host LLM /
7
- * `epic-plan-decompose-author` Skill consumes when producing the ticket
8
- * JSON array.
9
- *
10
- * Extracted verbatim from `epic-plan-decompose.js`; both
11
- * `buildDecomposerSystemPrompt` and `buildDecompositionContext` retain
12
- * their public-export contract for the existing unit tests.
13
- *
14
- * @module lib/orchestration/epic-plan-decompose/phases/context
15
- */
16
-
17
- import {
18
- getLimits,
19
- resolvePreflightCeilings,
20
- } from '../../../config-resolver.js';
21
- import { hasTechSpecContent } from '../../../epic-body-sections.js';
22
- import { renderDecomposerSystemPrompt } from '../../../templates/decomposer-prompts.js';
23
- import { read as readPlanState } from '../../epic-plan-state-store.js';
24
- import { applyBudget } from '../../planning-context-budget.js';
25
-
26
- export function buildDecomposerSystemPrompt(
27
- heuristics = [],
28
- { maxTickets, maxTokenBudget, epicId } = {},
29
- ) {
30
- const base = renderDecomposerSystemPrompt({
31
- maxTickets,
32
- maxTokenBudget,
33
- epicId,
34
- });
35
- const heuristicsStr =
36
- heuristics.length > 0
37
- ? `### RISK HEURISTICS (planning metadata if any apply):\n- ${heuristics.join('\n- ')}`
38
- : '';
39
- return `${base}${heuristicsStr ? `\n\n${heuristicsStr}` : ''}`;
40
- }
41
-
42
- function resolveHeuristics(config) {
43
- if (Array.isArray(config.planning?.riskHeuristics)) {
44
- return config.planning.riskHeuristics;
45
- }
46
- return config.agentSettings?.planning?.riskHeuristics || [];
47
- }
48
-
49
- function projectBudgetedEntry(item, ticket, mode) {
50
- if (mode === 'full') return { id: ticket.id, body: ticket.body };
51
- return { id: ticket.id, body: null, bodySummary: item };
52
- }
53
-
54
- /**
55
- * Read the persisted planning decision for the Epic so the decomposition
56
- * authoring step (Phase 8) can cite the same risk classification the
57
- * gate routing used in Phase 7. The decision lives in the `epic-plan-state`
58
- * structured comment written by `epic-plan-spec.js`.
59
- *
60
- * Returns `{ planningRisk: null, reviewRouting: null }` when the comment
61
- * is missing (older plans planned before Story #2801 landed) or when the
62
- * payload predates the fields. The null sentinels are part of the
63
- * decomposition context contract — callers MUST be able to JSON.stringify
64
- * the result without losing the keys.
65
- *
66
- * @param {import('../../../ITicketingProvider.js').ITicketingProvider} provider
67
- * @param {number} epicId
68
- * @returns {Promise<{ planningRisk: object | null, reviewRouting: object | null }>}
69
- */
70
- async function readPlanningDecision(provider, epicId) {
71
- let state = null;
72
- try {
73
- state = await readPlanState({ provider, epicId });
74
- } catch (_err) {
75
- // `read` already swallows JSON parse errors; a thrown error here
76
- // means the provider couldn't fetch comments. Treat as null state —
77
- // the decomposer can still author tickets without the risk envelope.
78
- state = null;
79
- }
80
- if (!state || typeof state !== 'object') {
81
- return { planningRisk: null, reviewRouting: null };
82
- }
83
- return {
84
- planningRisk: state.planningRisk ?? null,
85
- reviewRouting: state.reviewRouting ?? null,
86
- };
87
- }
88
-
89
- async function fetchPlanningEpic(provider, epicId) {
90
- const epic = await provider.getEpic(epicId);
91
- if (!epic || !hasTechSpecContent(epic.body ?? '')) {
92
- throw new Error(
93
- `[Decomposer] Epic #${epicId} body carries no Tech Spec sections (no ## Delivery Slicing). Run the Epic Planner (Phase 7) first.`,
94
- );
95
- }
96
- return { epic };
97
- }
98
-
99
- /**
100
- * Build the authoring context the host LLM (or the
101
- * `epic-plan-decompose-author` Skill) needs to produce the ticket JSON.
102
- *
103
- * The Epic body (ideation sections + folded Tech Spec sections +
104
- * Acceptance Table — the AC-ID source for wave-0 BDD scaffold tags) is
105
- * bounded by the planning-context budget (Epic #817 Story 9). Pass
106
- * `{ fullContext: true }` (CLI: `--full-context`) to restore the
107
- * unbounded full body.
108
- */
109
- export async function buildDecompositionContext(
110
- epicId,
111
- provider,
112
- config = {},
113
- opts = {},
114
- ) {
115
- const { epic } = await fetchPlanningEpic(provider, epicId);
116
- const { planningRisk, reviewRouting } = await readPlanningDecision(
117
- provider,
118
- epicId,
119
- );
120
- const heuristics = resolveHeuristics(config);
121
- const limits = getLimits(config);
122
- const maxTickets = limits.maxTickets;
123
- const maxTokenBudget = limits.maxTokenBudget;
124
- const planningLimits = limits.planningContext;
125
- const { fullContext = false } = opts;
126
- const systemPrompt = buildDecomposerSystemPrompt(heuristics, {
127
- maxTickets,
128
- maxTokenBudget,
129
- epicId,
130
- });
131
-
132
- const budgeted = applyBudget(
133
- [{ path: `epic-${epic.id}.md`, content: epic.body ?? '' }],
134
- planningLimits,
135
- { fullContext },
136
- );
137
- const [epicItem] = budgeted.items;
138
- return {
139
- epic: { id: epic.id, title: epic.title },
140
- // Story #4324 — the Epic body is the single planning document: it
141
- // carries the ideation sections, the folded Tech Spec sections
142
- // (## Delivery Slicing first), and the ## Acceptance Table the wave-0
143
- // BDD scaffold reads its AC IDs from.
144
- epicBody: projectBudgetedEntry(epicItem, epic, budgeted.mode),
145
- heuristics,
146
- systemPrompt,
147
- maxTickets,
148
- // Story #3875 — surface the real delivery envelope to the decomposer
149
- // so Stories are sized against the hydration budget and the
150
- // configured preflight ceilings rather than guessed. Story #4162 also
151
- // threads this value into the rendered systemPrompt above as a sizing
152
- // input so the prompt itself names the budget.
153
- maxTokenBudget,
154
- preflightCeilings: resolvePreflightCeilings(config),
155
- contextMode: budgeted.mode,
156
- // Story #2801 — surface the Phase 7 planning decision so the
157
- // decomposition authoring step can cite the same risk
158
- // classification used by gate routing. Both fields are `null`
159
- // when the Epic was planned before the decision contract existed.
160
- planningRisk,
161
- reviewRouting,
162
- };
163
- }
@@ -1,140 +0,0 @@
1
- /**
2
- * creation.js — sub-issue link reconciliation, Epic label transitions,
3
- * the advisory ticket-cap warning, and the blocked-by dependency wiring
4
- * used by the reconciler-based persist flow (`persist.js`).
5
- *
6
- * Exports: `reconcileSubIssueLinks`, `setBlockedByDependencies`,
7
- * `setEpicLabel`, `warnTicketCapNearLimit`.
8
- *
9
- * @module lib/orchestration/epic-plan-decompose/phases/creation
10
- */
11
-
12
- import { applyBlockedByDependencies } from '../../../../providers/github/blocked-by-add.js';
13
- import { Logger } from '../../../Logger.js';
14
- import { AGENT_LABELS } from '../../../label-constants.js';
15
-
16
- export async function reconcileSubIssueLinks(epicId, provider) {
17
- if (typeof provider.reconcileSubIssueLinks !== 'function') return;
18
- Logger.info(
19
- `[Decomposer] Reconciling sub-issue API links for Epic #${epicId}...`,
20
- );
21
- const result = await provider.reconcileSubIssueLinks(epicId);
22
- const { totalExpected, alreadyLinked, reconciled, failed, failures } = result;
23
- if (failed === 0) {
24
- const reconciledNote = reconciled > 0 ? ` (${reconciled} reconciled)` : '';
25
- Logger.info(
26
- `[Decomposer] linked ${alreadyLinked + reconciled}/${totalExpected} sub-issues${reconciledNote}`,
27
- );
28
- return;
29
- }
30
- for (const failure of failures) {
31
- Logger.error(
32
- `[Decomposer] sub-issue link gap: parent #${failure.parentId} ← child #${failure.childId}: ${failure.reason}`,
33
- );
34
- }
35
- throw new Error(
36
- `[Decomposer] Sub-issue reconciliation incomplete: ${failed}/${totalExpected} links could not be established (linked=${alreadyLinked}, reconciled=${reconciled}). See log for per-child reasons.`,
37
- );
38
- }
39
-
40
- /**
41
- * Translate each Story's `dependsOn` slug list into native GitHub "blocked
42
- * by" dependency edges. Best-effort and non-fatal: individual edge failures
43
- * are logged as warnings and do not abort the decompose phase.
44
- *
45
- * Requires the provider to expose `owner`, `repo`, `_gh`, and `getTicket`.
46
- * No-ops silently when any required surface is absent so callers remain
47
- * safe across provider stubs.
48
- *
49
- * @param {number} epicId
50
- * @param {import('../../../ITicketingProvider.js').ITicketingProvider} provider
51
- * @param {object} spec — the parsed YAML spec (has `.stories[*].dependsOn`).
52
- * @param {object} stateMapping — slug → `{ issueNumber }` from the reconciler state.
53
- */
54
- export async function setBlockedByDependencies(
55
- epicId,
56
- provider,
57
- spec,
58
- stateMapping,
59
- ) {
60
- const stories = Array.isArray(spec?.stories) ? spec.stories : [];
61
- const hasDeps = stories.some(
62
- (s) => Array.isArray(s.dependsOn) && s.dependsOn.length > 0,
63
- );
64
- if (!hasDeps) return;
65
-
66
- if (
67
- !provider?.owner ||
68
- !provider?.repo ||
69
- !provider?._gh ||
70
- typeof provider.getTicket !== 'function'
71
- ) {
72
- Logger.warn(
73
- `[Decomposer] setBlockedByDependencies: provider missing required surface (owner/repo/_gh/getTicket); skipping.`,
74
- );
75
- return;
76
- }
77
-
78
- Logger.info(
79
- `[Decomposer] Setting native blocked-by dependency edges for Epic #${epicId}...`,
80
- );
81
-
82
- // Build a slug → issueNumber map from the reconciler state mapping.
83
- const slugToIssueNumber = {};
84
- for (const [slug, entry] of Object.entries(stateMapping ?? {})) {
85
- if (typeof entry?.issueNumber === 'number') {
86
- slugToIssueNumber[slug] = entry.issueNumber;
87
- }
88
- }
89
-
90
- const result = await applyBlockedByDependencies({
91
- stories,
92
- slugToIssueNumber,
93
- getTicket: (n) => provider.getTicket(n),
94
- owner: provider.owner,
95
- repo: provider.repo,
96
- gh: provider._gh,
97
- });
98
-
99
- const { edgesAdded, edgesSkipped, edgesFailed, storiesProcessed } = result;
100
- Logger.info(
101
- `[Decomposer] blocked-by edges: ${edgesAdded} added, ${edgesSkipped} already present, ${edgesFailed} failed (${storiesProcessed} stories with deps processed).`,
102
- );
103
- }
104
-
105
- export async function setEpicLabel(provider, epicId, targetLabel) {
106
- const planningLabels = [AGENT_LABELS.REVIEW_SPEC, AGENT_LABELS.READY];
107
- await provider.updateTicket(epicId, {
108
- labels: {
109
- add: [targetLabel],
110
- remove: planningLabels.filter((l) => l !== targetLabel),
111
- },
112
- });
113
- }
114
-
115
- /**
116
- * Advisory-only ticket-count check (Story #2798).
117
- *
118
- * `maxTickets` is a **reviewability budget**, not a hard authoring cap.
119
- * This helper emits a non-destructive warning when a decomposition meets
120
- * or exceeds the budget so the operator can spot over-budget plans early
121
- * in the persist flow. It never blocks — the hard gate lives in the
122
- * `runDecomposePhase` over-budget check, which requires an explicit
123
- * `allowOverBudget` (CLI: `--allow-over-budget`) override.
124
- *
125
- * @param {Array} tickets
126
- * @param {number} maxTickets — the reviewability budget
127
- * @param {string} [tag] — log prefix
128
- * @param {{ logger?: Pick<typeof Logger, 'warn'> }} [opts]
129
- */
130
- export function warnTicketCapNearLimit(
131
- tickets,
132
- maxTickets,
133
- tag = 'epic-plan-decompose',
134
- { logger = Logger } = {},
135
- ) {
136
- if (tickets.length < maxTickets) return;
137
- logger.warn(
138
- `[${tag}] ⚠️ Received ${tickets.length} tickets against a reviewability budget of ${maxTickets}. Review the Story decomposition before persisting; over-budget persistence requires --allow-over-budget.`,
139
- );
140
- }
@@ -1,64 +0,0 @@
1
- /**
2
- * dag.js — Phase 2 of the epic-plan-decompose pipeline (Story #2466).
3
- *
4
- * Owns the deterministic DAG helpers used by the reconciler pipeline:
5
- * - `resolveDependencies(ticket, slugMap)`
6
- * - `orderTicketsForCreation(validated)` (topological sort of the
7
- * Story set so dependency producers are created before consumers)
8
- *
9
- * Extracted verbatim from `epic-plan-decompose.js` so the named exports
10
- * (`resolveDependencies`, `orderTicketsForCreation`) that the
11
- * `tests/ticket-decomposer.test.js` suite imports keep their contract.
12
- *
13
- * @module lib/orchestration/epic-plan-decompose/phases/dag
14
- */
15
-
16
- export function resolveDependencies(ticket, slugMap) {
17
- const resolved = [];
18
- for (const dep of ticket.depends_on || []) {
19
- const depId = slugMap.get(dep);
20
- if (depId === undefined) {
21
- // Unreachable through normal flow: validateAndNormalizeTickets
22
- // already rejects unknown slugs and the topological sort guarantees
23
- // creation order. A throw here turns a future regression (e.g.
24
- // someone bypassing the validator) into a loud failure instead of a
25
- // silently-dropped DAG edge.
26
- throw new Error(
27
- `[Decomposer] ${ticket.type.toUpperCase()} "${ticket.title}" (${ticket.slug}) depends on unresolved slug "${dep}". This indicates a planner bug or out-of-order ticket creation.`,
28
- );
29
- }
30
- resolved.push(depId);
31
- }
32
- return resolved;
33
- }
34
-
35
- function topoSortGroup(group) {
36
- const slugToTicket = new Map(group.map((t) => [t.slug, t]));
37
- const visited = new Set();
38
- const sorted = [];
39
-
40
- function visit(t) {
41
- if (visited.has(t.slug)) return;
42
- visited.add(t.slug);
43
- for (const dep of t.depends_on ?? []) {
44
- const depTicket = slugToTicket.get(dep);
45
- if (depTicket) visit(depTicket);
46
- }
47
- sorted.push(t);
48
- }
49
-
50
- for (const t of group) visit(t);
51
- return sorted;
52
- }
53
-
54
- /**
55
- * Topologically sort the Story set so intra-set dep chains resolve
56
- * before their dependents are created. The 2-tier hierarchy has a
57
- * single ticket type (story) attached directly to the Epic, so there
58
- * is no parent-type ordering to interleave.
59
- */
60
- export function orderTicketsForCreation(validated) {
61
- const result = [];
62
- for (const t of topoSortGroup([...validated])) result.push(t);
63
- return result;
64
- }