mandrel 1.57.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 (843) hide show
  1. package/.agents/README.md +954 -0
  2. package/.agents/docs/SDLC.md +1420 -0
  3. package/.agents/docs/agentrc-reference.json +278 -0
  4. package/.agents/docs/configuration.md +1040 -0
  5. package/.agents/docs/workflows.md +59 -0
  6. package/.agents/instructions.md +384 -0
  7. package/.agents/personas/architect.md +107 -0
  8. package/.agents/personas/devops-engineer.md +36 -0
  9. package/.agents/personas/engineer-mobile.md +119 -0
  10. package/.agents/personas/engineer-web.md +110 -0
  11. package/.agents/personas/engineer.md +90 -0
  12. package/.agents/personas/product.md +88 -0
  13. package/.agents/personas/project-manager.md +110 -0
  14. package/.agents/personas/qa-engineer.md +91 -0
  15. package/.agents/personas/refactorer.md +110 -0
  16. package/.agents/personas/security-engineer.md +112 -0
  17. package/.agents/personas/sre.md +86 -0
  18. package/.agents/personas/technical-writer.md +100 -0
  19. package/.agents/personas/ux-designer.md +95 -0
  20. package/.agents/rules/api-conventions.md +75 -0
  21. package/.agents/rules/changelog-style.md +238 -0
  22. package/.agents/rules/gherkin-standards.md +146 -0
  23. package/.agents/rules/git-conventions.md +146 -0
  24. package/.agents/rules/orchestration-error-handling.md +35 -0
  25. package/.agents/rules/security-baseline.md +92 -0
  26. package/.agents/rules/shell-conventions.md +70 -0
  27. package/.agents/rules/test-seams.md +59 -0
  28. package/.agents/rules/testing-standards.md +177 -0
  29. package/.agents/runtime-deps.json +18 -0
  30. package/.agents/schemas/acceptance-eval-verdict.schema.json +93 -0
  31. package/.agents/schemas/agentrc.schema.json +1583 -0
  32. package/.agents/schemas/audit-results.schema.json +69 -0
  33. package/.agents/schemas/audit-rules.json +134 -0
  34. package/.agents/schemas/audit-rules.schema.json +69 -0
  35. package/.agents/schemas/baselines/baseline-envelope.schema.json +44 -0
  36. package/.agents/schemas/baselines/bundle-size.schema.json +47 -0
  37. package/.agents/schemas/baselines/coverage.schema.json +50 -0
  38. package/.agents/schemas/baselines/crap.schema.json +52 -0
  39. package/.agents/schemas/baselines/duplication.schema.json +62 -0
  40. package/.agents/schemas/baselines/lighthouse.schema.json +59 -0
  41. package/.agents/schemas/baselines/lint.schema.json +47 -0
  42. package/.agents/schemas/baselines/maintainability.schema.json +71 -0
  43. package/.agents/schemas/baselines/mutation.schema.json +52 -0
  44. package/.agents/schemas/crap-baseline.schema.json +57 -0
  45. package/.agents/schemas/crap-report.schema.json +102 -0
  46. package/.agents/schemas/dispatch-manifest.json +232 -0
  47. package/.agents/schemas/epic-perf-report.schema.json +89 -0
  48. package/.agents/schemas/epic-spec.schema.json +183 -0
  49. package/.agents/schemas/friction-event.schema.json +56 -0
  50. package/.agents/schemas/lifecycle/README.md +18 -0
  51. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +13 -0
  52. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +13 -0
  53. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +13 -0
  54. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +12 -0
  55. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +13 -0
  56. package/.agents/schemas/lifecycle/checkpoint.written.schema.json +13 -0
  57. package/.agents/schemas/lifecycle/close-validate.end.schema.json +18 -0
  58. package/.agents/schemas/lifecycle/close-validate.start.schema.json +13 -0
  59. package/.agents/schemas/lifecycle/code-review.end.schema.json +30 -0
  60. package/.agents/schemas/lifecycle/code-review.start.schema.json +12 -0
  61. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +14 -0
  62. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +13 -0
  63. package/.agents/schemas/lifecycle/epic.blocked.schema.json +13 -0
  64. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +12 -0
  65. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +12 -0
  66. package/.agents/schemas/lifecycle/epic.close.end.schema.json +12 -0
  67. package/.agents/schemas/lifecycle/epic.complete.schema.json +13 -0
  68. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +13 -0
  69. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +12 -0
  70. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +13 -0
  71. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +14 -0
  72. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +17 -0
  73. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +15 -0
  74. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +18 -0
  75. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +12 -0
  76. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +16 -0
  77. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +12 -0
  78. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +28 -0
  79. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +16 -0
  80. package/.agents/schemas/lifecycle/intervention.recorded.schema.json +15 -0
  81. package/.agents/schemas/lifecycle/ledger-record.schema.json +59 -0
  82. package/.agents/schemas/lifecycle/notification.emitted.schema.json +18 -0
  83. package/.agents/schemas/lifecycle/pr.created.schema.json +14 -0
  84. package/.agents/schemas/lifecycle/retro.end.schema.json +16 -0
  85. package/.agents/schemas/lifecycle/retro.start.schema.json +12 -0
  86. package/.agents/schemas/lifecycle/story.blocked.schema.json +13 -0
  87. package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +17 -0
  88. package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +15 -0
  89. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +20 -0
  90. package/.agents/schemas/lifecycle/story.merged.schema.json +13 -0
  91. package/.agents/schemas/mi-report.schema.json +58 -0
  92. package/.agents/schemas/model-attribution.schema.json +49 -0
  93. package/.agents/schemas/qa-finding.schema.json +133 -0
  94. package/.agents/schemas/qa-ledger.schema.json +89 -0
  95. package/.agents/schemas/risk-verdict.schema.json +53 -0
  96. package/.agents/schemas/signal-event.schema.json +58 -0
  97. package/.agents/schemas/skill.schema.json +31 -0
  98. package/.agents/schemas/skills-index.schema.json +81 -0
  99. package/.agents/schemas/story-perf-summary.schema.json +73 -0
  100. package/.agents/schemas/validation-evidence.schema.json +78 -0
  101. package/.agents/scripts/README.md +93 -0
  102. package/.agents/scripts/acceptance-eval.js +284 -0
  103. package/.agents/scripts/acceptance-spec-reconciler.js +556 -0
  104. package/.agents/scripts/agents-bootstrap-github.js +634 -0
  105. package/.agents/scripts/analyze-execution.js +369 -0
  106. package/.agents/scripts/assert-branch.js +83 -0
  107. package/.agents/scripts/audit-labels-bootstrap.js +253 -0
  108. package/.agents/scripts/audit-to-stories.js +257 -0
  109. package/.agents/scripts/bootstrap.js +1378 -0
  110. package/.agents/scripts/check-baselines.js +81 -0
  111. package/.agents/scripts/check-dead-exports.js +311 -0
  112. package/.agents/scripts/check-doc-links.js +401 -0
  113. package/.agents/scripts/check-gherkin-placeholders.js +663 -0
  114. package/.agents/scripts/check-lifecycle-doc-drift.js +402 -0
  115. package/.agents/scripts/check-lifecycle-lint.js +379 -0
  116. package/.agents/scripts/check-prepush-recovery.js +90 -0
  117. package/.agents/scripts/check-windows-git-perf.js +138 -0
  118. package/.agents/scripts/cleanup-repo-test-temp.js +67 -0
  119. package/.agents/scripts/coverage-capture.js +112 -0
  120. package/.agents/scripts/detect-merges.js +111 -0
  121. package/.agents/scripts/diagnose-friction.js +257 -0
  122. package/.agents/scripts/diagnose.js +240 -0
  123. package/.agents/scripts/dispatcher.js +295 -0
  124. package/.agents/scripts/drain-pending-cleanup.js +147 -0
  125. package/.agents/scripts/epic-audit-prepare.js +419 -0
  126. package/.agents/scripts/epic-audit-recheck.js +241 -0
  127. package/.agents/scripts/epic-deliver-note-intervention.js +192 -0
  128. package/.agents/scripts/epic-deliver-preflight.js +407 -0
  129. package/.agents/scripts/epic-deliver-prepare.js +383 -0
  130. package/.agents/scripts/epic-execute-record-wave.js +463 -0
  131. package/.agents/scripts/epic-plan-clarity.js +201 -0
  132. package/.agents/scripts/epic-plan-decompose.js +79 -0
  133. package/.agents/scripts/epic-plan-healthcheck.js +363 -0
  134. package/.agents/scripts/epic-plan-spec-validate.js +111 -0
  135. package/.agents/scripts/epic-plan-spec.js +198 -0
  136. package/.agents/scripts/epic-reconcile.js +637 -0
  137. package/.agents/scripts/evidence-gate.js +235 -0
  138. package/.agents/scripts/generate-config-docs.js +516 -0
  139. package/.agents/scripts/generate-lifecycle-docs.js +224 -0
  140. package/.agents/scripts/generate-skills-index.js +252 -0
  141. package/.agents/scripts/generate-workflows-doc.js +168 -0
  142. package/.agents/scripts/git-cleanup.js +124 -0
  143. package/.agents/scripts/git-pr-quality-gate.js +203 -0
  144. package/.agents/scripts/git-rebase-and-resolve.js +234 -0
  145. package/.agents/scripts/hierarchy-gate.js +176 -0
  146. package/.agents/scripts/hydrate-context.js +179 -0
  147. package/.agents/scripts/install-matrix-assert.js +282 -0
  148. package/.agents/scripts/lib/Graph.js +326 -0
  149. package/.agents/scripts/lib/ITicketingProvider.js +349 -0
  150. package/.agents/scripts/lib/Logger.js +194 -0
  151. package/.agents/scripts/lib/audit-suite/cli.js +64 -0
  152. package/.agents/scripts/lib/audit-suite/findings.js +164 -0
  153. package/.agents/scripts/lib/audit-suite/frontmatter-lint.js +32 -0
  154. package/.agents/scripts/lib/audit-suite/frontmatter.js +110 -0
  155. package/.agents/scripts/lib/audit-suite/index.js +22 -0
  156. package/.agents/scripts/lib/audit-suite/runner.js +233 -0
  157. package/.agents/scripts/lib/audit-suite/selector.js +235 -0
  158. package/.agents/scripts/lib/audit-suite/substitutions.js +124 -0
  159. package/.agents/scripts/lib/audit-suite/workflow-loader.js +49 -0
  160. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +130 -0
  161. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +114 -0
  162. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +93 -0
  163. package/.agents/scripts/lib/audit-to-stories/group-findings.js +265 -0
  164. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +246 -0
  165. package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +160 -0
  166. package/.agents/scripts/lib/auto-refresh-baselines.js +308 -0
  167. package/.agents/scripts/lib/baseline-loader.js +0 -0
  168. package/.agents/scripts/lib/baseline-schema-registry.js +69 -0
  169. package/.agents/scripts/lib/baseline-snapshot.js +716 -0
  170. package/.agents/scripts/lib/baselines/component-matcher.js +21 -0
  171. package/.agents/scripts/lib/baselines/components.js +126 -0
  172. package/.agents/scripts/lib/baselines/diff-scope-cli.js +203 -0
  173. package/.agents/scripts/lib/baselines/duplication-scanner.js +220 -0
  174. package/.agents/scripts/lib/baselines/env-overrides.js +129 -0
  175. package/.agents/scripts/lib/baselines/envelope.js +368 -0
  176. package/.agents/scripts/lib/baselines/exit-codes.js +89 -0
  177. package/.agents/scripts/lib/baselines/git-base.js +0 -0
  178. package/.agents/scripts/lib/baselines/kernel.js +111 -0
  179. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +220 -0
  180. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +157 -0
  181. package/.agents/scripts/lib/baselines/kinds/coverage.js +194 -0
  182. package/.agents/scripts/lib/baselines/kinds/crap.js +555 -0
  183. package/.agents/scripts/lib/baselines/kinds/duplication.js +197 -0
  184. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +185 -0
  185. package/.agents/scripts/lib/baselines/kinds/lint.js +172 -0
  186. package/.agents/scripts/lib/baselines/kinds/maintainability.js +340 -0
  187. package/.agents/scripts/lib/baselines/kinds/mutation.js +153 -0
  188. package/.agents/scripts/lib/baselines/path-canon.js +279 -0
  189. package/.agents/scripts/lib/baselines/preview-gates.js +298 -0
  190. package/.agents/scripts/lib/baselines/reader.js +321 -0
  191. package/.agents/scripts/lib/baselines/refresh-service.js +733 -0
  192. package/.agents/scripts/lib/baselines/scope.js +291 -0
  193. package/.agents/scripts/lib/baselines/writer.js +312 -0
  194. package/.agents/scripts/lib/bdd-runner-detect.js +417 -0
  195. package/.agents/scripts/lib/bdd-scenario-scanner.js +310 -0
  196. package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +202 -0
  197. package/.agents/scripts/lib/bootstrap/branch-protection.js +222 -0
  198. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +171 -0
  199. package/.agents/scripts/lib/bootstrap/commit-push.js +146 -0
  200. package/.agents/scripts/lib/bootstrap/gh-list.js +153 -0
  201. package/.agents/scripts/lib/bootstrap/gh-preflight.js +306 -0
  202. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +89 -0
  203. package/.agents/scripts/lib/bootstrap/install-ledger.js +174 -0
  204. package/.agents/scripts/lib/bootstrap/manifest.js +272 -0
  205. package/.agents/scripts/lib/bootstrap/merge-methods.js +108 -0
  206. package/.agents/scripts/lib/bootstrap/preflight.js +195 -0
  207. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +801 -0
  208. package/.agents/scripts/lib/bootstrap/prompt.js +480 -0
  209. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +370 -0
  210. package/.agents/scripts/lib/bootstrap/summary.js +75 -0
  211. package/.agents/scripts/lib/bootstrap/workflow-audit.js +256 -0
  212. package/.agents/scripts/lib/branch-name-guard.js +98 -0
  213. package/.agents/scripts/lib/c8-cli-path.js +21 -0
  214. package/.agents/scripts/lib/changed-files.js +184 -0
  215. package/.agents/scripts/lib/checks/baseline-drift-main-checkout.js +104 -0
  216. package/.agents/scripts/lib/checks/core-bare-clean.js +48 -0
  217. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +54 -0
  218. package/.agents/scripts/lib/checks/index.js +288 -0
  219. package/.agents/scripts/lib/checks/push-hook-parity.js +106 -0
  220. package/.agents/scripts/lib/checks/stale-origin-epic.js +49 -0
  221. package/.agents/scripts/lib/checks/state.js +558 -0
  222. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +186 -0
  223. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +182 -0
  224. package/.agents/scripts/lib/checks/windows-coverage-noise-floor.js +92 -0
  225. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +81 -0
  226. package/.agents/scripts/lib/checks/worktree-residue-biome.js +55 -0
  227. package/.agents/scripts/lib/cli/parse-numeric.js +60 -0
  228. package/.agents/scripts/lib/cli/standard-args.js +351 -0
  229. package/.agents/scripts/lib/cli-args.js +286 -0
  230. package/.agents/scripts/lib/cli-utils.js +69 -0
  231. package/.agents/scripts/lib/close-validation/projections/head-sha.js +44 -0
  232. package/.agents/scripts/lib/close-validation/projections/inputs.js +86 -0
  233. package/.agents/scripts/lib/close-validation/projections/maintainability.js +286 -0
  234. package/.agents/scripts/lib/close-validation.js +897 -0
  235. package/.agents/scripts/lib/codebase-snapshot.js +513 -0
  236. package/.agents/scripts/lib/command-header.js +33 -0
  237. package/.agents/scripts/lib/config/acceptance-eval.js +95 -0
  238. package/.agents/scripts/lib/config/baselines.js +60 -0
  239. package/.agents/scripts/lib/config/ci.js +30 -0
  240. package/.agents/scripts/lib/config/commands.js +36 -0
  241. package/.agents/scripts/lib/config/defaults.js +119 -0
  242. package/.agents/scripts/lib/config/explain.js +348 -0
  243. package/.agents/scripts/lib/config/gates/bundle-size.schema.js +23 -0
  244. package/.agents/scripts/lib/config/gates/coverage.schema.js +18 -0
  245. package/.agents/scripts/lib/config/gates/crap.schema.js +33 -0
  246. package/.agents/scripts/lib/config/gates/duplication.schema.js +26 -0
  247. package/.agents/scripts/lib/config/gates/index.js +36 -0
  248. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +23 -0
  249. package/.agents/scripts/lib/config/gates/lint.schema.js +9 -0
  250. package/.agents/scripts/lib/config/gates/maintainability.schema.js +20 -0
  251. package/.agents/scripts/lib/config/gates/mutation.schema.js +12 -0
  252. package/.agents/scripts/lib/config/gates/shared.js +117 -0
  253. package/.agents/scripts/lib/config/github.js +122 -0
  254. package/.agents/scripts/lib/config/lifecycle.js +40 -0
  255. package/.agents/scripts/lib/config/limits.js +211 -0
  256. package/.agents/scripts/lib/config/paths.js +73 -0
  257. package/.agents/scripts/lib/config/preflight.js +58 -0
  258. package/.agents/scripts/lib/config/quality.js +665 -0
  259. package/.agents/scripts/lib/config/retro.js +77 -0
  260. package/.agents/scripts/lib/config/runners.js +105 -0
  261. package/.agents/scripts/lib/config/runtime.js +167 -0
  262. package/.agents/scripts/lib/config/shared.js +46 -0
  263. package/.agents/scripts/lib/config/sync-agentrc.js +243 -0
  264. package/.agents/scripts/lib/config/temp-paths.js +373 -0
  265. package/.agents/scripts/lib/config/validate-orchestration.js +81 -0
  266. package/.agents/scripts/lib/config/worktree-isolation.js +80 -0
  267. package/.agents/scripts/lib/config-resolver.js +298 -0
  268. package/.agents/scripts/lib/config-schema-shared.js +32 -0
  269. package/.agents/scripts/lib/config-schema.js +20 -0
  270. package/.agents/scripts/lib/config-settings-schema-delivery.js +332 -0
  271. package/.agents/scripts/lib/config-settings-schema-quality.js +165 -0
  272. package/.agents/scripts/lib/config-settings-schema.js +420 -0
  273. package/.agents/scripts/lib/coverage-baseline.js +352 -0
  274. package/.agents/scripts/lib/coverage-capture.js +195 -0
  275. package/.agents/scripts/lib/coverage-utils.js +239 -0
  276. package/.agents/scripts/lib/cpu-pool.js +223 -0
  277. package/.agents/scripts/lib/crap-engine.js +119 -0
  278. package/.agents/scripts/lib/crap-utils.js +479 -0
  279. package/.agents/scripts/lib/degraded-mode.js +69 -0
  280. package/.agents/scripts/lib/dependency-parser.js +129 -0
  281. package/.agents/scripts/lib/duplicate-search.js +189 -0
  282. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +70 -0
  283. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +197 -0
  284. package/.agents/scripts/lib/dynamic-workflow/capability.js +396 -0
  285. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +80 -0
  286. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +72 -0
  287. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +90 -0
  288. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +43 -0
  289. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +83 -0
  290. package/.agents/scripts/lib/env-loader.js +52 -0
  291. package/.agents/scripts/lib/epic-merge-lock.js +239 -0
  292. package/.agents/scripts/lib/epic-plan-clarity.js +142 -0
  293. package/.agents/scripts/lib/epic-plan-ideation.js +228 -0
  294. package/.agents/scripts/lib/error-redactor.js +125 -0
  295. package/.agents/scripts/lib/errors/index.js +67 -0
  296. package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +230 -0
  297. package/.agents/scripts/lib/feedback-loop/code-review-graduator.js +207 -0
  298. package/.agents/scripts/lib/feedback-loop/graduator-core.js +421 -0
  299. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +480 -0
  300. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +229 -0
  301. package/.agents/scripts/lib/findings/classify-finding.js +195 -0
  302. package/.agents/scripts/lib/findings/promote-finding.js +353 -0
  303. package/.agents/scripts/lib/findings/route-finding.js +283 -0
  304. package/.agents/scripts/lib/findings/semantic-issue-search.js +179 -0
  305. package/.agents/scripts/lib/findings/severity.js +102 -0
  306. package/.agents/scripts/lib/gates/baseline-store.js +106 -0
  307. package/.agents/scripts/lib/gates/friction.js +43 -0
  308. package/.agents/scripts/lib/gh-exec.js +553 -0
  309. package/.agents/scripts/lib/git/cached-fetch.js +0 -0
  310. package/.agents/scripts/lib/git/sync-from-base.js +162 -0
  311. package/.agents/scripts/lib/git-branch-cleanup.js +213 -0
  312. package/.agents/scripts/lib/git-branch-lifecycle.js +353 -0
  313. package/.agents/scripts/lib/git-merge-orchestrator.js +261 -0
  314. package/.agents/scripts/lib/git-utils.js +363 -0
  315. package/.agents/scripts/lib/github-url.js +29 -0
  316. package/.agents/scripts/lib/install-cmd-parser.js +51 -0
  317. package/.agents/scripts/lib/issue-link-parser.js +74 -0
  318. package/.agents/scripts/lib/json-utils.js +60 -0
  319. package/.agents/scripts/lib/label-constants.js +169 -0
  320. package/.agents/scripts/lib/label-taxonomy.js +200 -0
  321. package/.agents/scripts/lib/maintainability-engine.js +164 -0
  322. package/.agents/scripts/lib/maintainability-utils.js +343 -0
  323. package/.agents/scripts/lib/mandrel-catalog.js +170 -0
  324. package/.agents/scripts/lib/mutation/baseline-snapshot.js +238 -0
  325. package/.agents/scripts/lib/mutation/config-detector.js +119 -0
  326. package/.agents/scripts/lib/mutation/stryker-runner.js +306 -0
  327. package/.agents/scripts/lib/mutation/survivor-report.js +160 -0
  328. package/.agents/scripts/lib/notifications/notifier.js +75 -0
  329. package/.agents/scripts/lib/observability/active-story-env.js +182 -0
  330. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +221 -0
  331. package/.agents/scripts/lib/observability/perf-aggregator.js +887 -0
  332. package/.agents/scripts/lib/observability/perf-report-readers.js +319 -0
  333. package/.agents/scripts/lib/observability/perf-report-render.js +182 -0
  334. package/.agents/scripts/lib/observability/signals-writer.js +296 -0
  335. package/.agents/scripts/lib/observability/source-classifier.js +103 -0
  336. package/.agents/scripts/lib/observability/tool-trace-hook.js +417 -0
  337. package/.agents/scripts/lib/onboard/detect-stack.js +300 -0
  338. package/.agents/scripts/lib/onboard/scaffold-docs.js +128 -0
  339. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +173 -0
  340. package/.agents/scripts/lib/orchestration/cascade-grouping.js +275 -0
  341. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +131 -0
  342. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +80 -0
  343. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +132 -0
  344. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +142 -0
  345. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +149 -0
  346. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +158 -0
  347. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +56 -0
  348. package/.agents/scripts/lib/orchestration/code-review.js +652 -0
  349. package/.agents/scripts/lib/orchestration/column-sync.js +286 -0
  350. package/.agents/scripts/lib/orchestration/context-envelope.js +280 -0
  351. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +581 -0
  352. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +88 -0
  353. package/.agents/scripts/lib/orchestration/detectors-phase.js +188 -0
  354. package/.agents/scripts/lib/orchestration/dispatch-engine.js +144 -0
  355. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +206 -0
  356. package/.agents/scripts/lib/orchestration/doc-reader.js +94 -0
  357. package/.agents/scripts/lib/orchestration/epic-cleanup.js +473 -0
  358. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +310 -0
  359. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/cli.js +167 -0
  360. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +151 -0
  361. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +74 -0
  362. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +78 -0
  363. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +72 -0
  364. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +155 -0
  365. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +321 -0
  366. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +75 -0
  367. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +86 -0
  368. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +235 -0
  369. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +197 -0
  370. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +48 -0
  371. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +94 -0
  372. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +414 -0
  373. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +55 -0
  374. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +105 -0
  375. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +235 -0
  376. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +120 -0
  377. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +118 -0
  378. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +295 -0
  379. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +186 -0
  380. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +50 -0
  381. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +146 -0
  382. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +110 -0
  383. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +392 -0
  384. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +217 -0
  385. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +235 -0
  386. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +69 -0
  387. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +32 -0
  388. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +291 -0
  389. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +175 -0
  390. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +37 -0
  391. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +127 -0
  392. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +400 -0
  393. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +285 -0
  394. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +66 -0
  395. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +797 -0
  396. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +619 -0
  397. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +335 -0
  398. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +230 -0
  399. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +363 -0
  400. package/.agents/scripts/lib/orchestration/error-journal.js +139 -0
  401. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +31 -0
  402. package/.agents/scripts/lib/orchestration/file-assumptions.js +506 -0
  403. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +116 -0
  404. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +241 -0
  405. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +489 -0
  406. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +88 -0
  407. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +219 -0
  408. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +309 -0
  409. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +99 -0
  410. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +123 -0
  411. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +57 -0
  412. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +114 -0
  413. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +426 -0
  414. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +84 -0
  415. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +365 -0
  416. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +72 -0
  417. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +69 -0
  418. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +214 -0
  419. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +137 -0
  420. package/.agents/scripts/lib/orchestration/label-transitions.js +43 -0
  421. package/.agents/scripts/lib/orchestration/lifecycle/bus.js +309 -0
  422. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +147 -0
  423. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +155 -0
  424. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +226 -0
  425. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +69 -0
  426. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +378 -0
  427. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +248 -0
  428. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +527 -0
  429. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +259 -0
  430. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +278 -0
  431. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +355 -0
  432. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +647 -0
  433. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +331 -0
  434. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +140 -0
  435. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +421 -0
  436. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +168 -0
  437. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +668 -0
  438. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +322 -0
  439. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +114 -0
  440. package/.agents/scripts/lib/orchestration/manifest-builder.js +216 -0
  441. package/.agents/scripts/lib/orchestration/model-attribution.js +390 -0
  442. package/.agents/scripts/lib/orchestration/parked-follow-ons.js +147 -0
  443. package/.agents/scripts/lib/orchestration/phase-runner.js +87 -0
  444. package/.agents/scripts/lib/orchestration/plan-review-routing.js +63 -0
  445. package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +86 -0
  446. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +212 -0
  447. package/.agents/scripts/lib/orchestration/planning-context-budget.js +213 -0
  448. package/.agents/scripts/lib/orchestration/planning-risk.js +155 -0
  449. package/.agents/scripts/lib/orchestration/planning-state-manager.js +318 -0
  450. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +56 -0
  451. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +33 -0
  452. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +78 -0
  453. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +68 -0
  454. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +118 -0
  455. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +396 -0
  456. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +205 -0
  457. package/.agents/scripts/lib/orchestration/pr-base-guard.js +47 -0
  458. package/.agents/scripts/lib/orchestration/preflight-cache.js +164 -0
  459. package/.agents/scripts/lib/orchestration/reassert-status-column.js +202 -0
  460. package/.agents/scripts/lib/orchestration/reconciler.js +137 -0
  461. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +152 -0
  462. package/.agents/scripts/lib/orchestration/recut.js +56 -0
  463. package/.agents/scripts/lib/orchestration/resolves-token.js +127 -0
  464. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +94 -0
  465. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +448 -0
  466. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +335 -0
  467. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +133 -0
  468. package/.agents/scripts/lib/orchestration/retro-heuristics.js +57 -0
  469. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +275 -0
  470. package/.agents/scripts/lib/orchestration/retro-proposals.js +395 -0
  471. package/.agents/scripts/lib/orchestration/retro-runner.js +171 -0
  472. package/.agents/scripts/lib/orchestration/review-depth.js +93 -0
  473. package/.agents/scripts/lib/orchestration/review-providers/codex.js +363 -0
  474. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +205 -0
  475. package/.agents/scripts/lib/orchestration/review-providers/native.js +805 -0
  476. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +73 -0
  477. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +396 -0
  478. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +373 -0
  479. package/.agents/scripts/lib/orchestration/review-providers/types.js +89 -0
  480. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +107 -0
  481. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +159 -0
  482. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +194 -0
  483. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +81 -0
  484. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +190 -0
  485. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +70 -0
  486. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +106 -0
  487. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +42 -0
  488. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +73 -0
  489. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +225 -0
  490. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +315 -0
  491. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +149 -0
  492. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +110 -0
  493. package/.agents/scripts/lib/orchestration/spec-freshness.js +320 -0
  494. package/.agents/scripts/lib/orchestration/spec-renderer.js +456 -0
  495. package/.agents/scripts/lib/orchestration/spec-section-validator.js +80 -0
  496. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +797 -0
  497. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +163 -0
  498. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +152 -0
  499. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +387 -0
  500. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +266 -0
  501. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +48 -0
  502. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +67 -0
  503. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +161 -0
  504. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +117 -0
  505. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +86 -0
  506. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +147 -0
  507. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +142 -0
  508. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +62 -0
  509. package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +221 -0
  510. package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +123 -0
  511. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +216 -0
  512. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +636 -0
  513. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +198 -0
  514. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +105 -0
  515. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +222 -0
  516. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +220 -0
  517. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +291 -0
  518. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +234 -0
  519. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +110 -0
  520. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +86 -0
  521. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +112 -0
  522. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +157 -0
  523. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +434 -0
  524. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +290 -0
  525. package/.agents/scripts/lib/orchestration/story-close-recovery.js +643 -0
  526. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +67 -0
  527. package/.agents/scripts/lib/orchestration/task-body-validator.js +391 -0
  528. package/.agents/scripts/lib/orchestration/ticket-lease.js +358 -0
  529. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +783 -0
  530. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +367 -0
  531. package/.agents/scripts/lib/orchestration/ticket-validator.js +691 -0
  532. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +723 -0
  533. package/.agents/scripts/lib/orchestration/ticketing/reads.js +474 -0
  534. package/.agents/scripts/lib/orchestration/ticketing/state.js +559 -0
  535. package/.agents/scripts/lib/orchestration/ticketing.js +55 -0
  536. package/.agents/scripts/lib/orchestration/wave-marker.js +28 -0
  537. package/.agents/scripts/lib/orchestration/wave-record-io.js +277 -0
  538. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +189 -0
  539. package/.agents/scripts/lib/orchestration/wave-record-projection.js +423 -0
  540. package/.agents/scripts/lib/path-security.js +25 -0
  541. package/.agents/scripts/lib/plan-phase-cleanup.js +125 -0
  542. package/.agents/scripts/lib/preflight-runner.js +196 -0
  543. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +95 -0
  544. package/.agents/scripts/lib/presentation/manifest-builder.js +245 -0
  545. package/.agents/scripts/lib/presentation/manifest-formatter.js +243 -0
  546. package/.agents/scripts/lib/presentation/manifest-helpers.js +213 -0
  547. package/.agents/scripts/lib/presentation/manifest-persistence.js +262 -0
  548. package/.agents/scripts/lib/presentation/manifest-procedures.js +55 -0
  549. package/.agents/scripts/lib/presentation/manifest-render-waves.js +252 -0
  550. package/.agents/scripts/lib/presentation/manifest-renderer.js +188 -0
  551. package/.agents/scripts/lib/presentation/manifest-story-views.js +119 -0
  552. package/.agents/scripts/lib/provider-factory.js +80 -0
  553. package/.agents/scripts/lib/push-epic-retry.js +209 -0
  554. package/.agents/scripts/lib/qa/console-allowlist.js +151 -0
  555. package/.agents/scripts/lib/qa/coverage-report.js +181 -0
  556. package/.agents/scripts/lib/qa/coverage-verdict.js +296 -0
  557. package/.agents/scripts/lib/qa/propose-missing-test.js +95 -0
  558. package/.agents/scripts/lib/qa/qa-context-hydrator.js +296 -0
  559. package/.agents/scripts/lib/qa/qa-session.js +197 -0
  560. package/.agents/scripts/lib/qa/redact-evidence.js +245 -0
  561. package/.agents/scripts/lib/qa/resolve-qa-contract.js +190 -0
  562. package/.agents/scripts/lib/qa/resolve-selection.js +373 -0
  563. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +100 -0
  564. package/.agents/scripts/lib/runtime-deps/manifest.js +96 -0
  565. package/.agents/scripts/lib/runtime-deps/preflight.js +78 -0
  566. package/.agents/scripts/lib/runtime-deps/scan-imports.js +202 -0
  567. package/.agents/scripts/lib/signals/detectors/common.js +36 -0
  568. package/.agents/scripts/lib/signals/detectors/hotspot.js +298 -0
  569. package/.agents/scripts/lib/signals/detectors/index.js +14 -0
  570. package/.agents/scripts/lib/signals/detectors/retry.js +289 -0
  571. package/.agents/scripts/lib/signals/detectors/rework.js +204 -0
  572. package/.agents/scripts/lib/signals/index.js +39 -0
  573. package/.agents/scripts/lib/signals/read.js +268 -0
  574. package/.agents/scripts/lib/signals/schema.js +225 -0
  575. package/.agents/scripts/lib/signals/span-tree.js +290 -0
  576. package/.agents/scripts/lib/signals/write.js +19 -0
  577. package/.agents/scripts/lib/single-story/confirm-merge.js +201 -0
  578. package/.agents/scripts/lib/single-story/story-merged-notify.js +126 -0
  579. package/.agents/scripts/lib/single-story-sweep/protection.js +274 -0
  580. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +169 -0
  581. package/.agents/scripts/lib/single-story-sweep.js +329 -0
  582. package/.agents/scripts/lib/skills/parse-skill.js +202 -0
  583. package/.agents/scripts/lib/skills/walk-skill-files.js +56 -0
  584. package/.agents/scripts/lib/spec/index.js +36 -0
  585. package/.agents/scripts/lib/spec/loader.js +425 -0
  586. package/.agents/scripts/lib/spec/state.js +217 -0
  587. package/.agents/scripts/lib/story-body/story-body.js +743 -0
  588. package/.agents/scripts/lib/story-init/blocker-validator.js +68 -0
  589. package/.agents/scripts/lib/story-init/branch-initializer.js +422 -0
  590. package/.agents/scripts/lib/story-init/context-resolver.js +92 -0
  591. package/.agents/scripts/lib/story-init/donor-precheck.js +207 -0
  592. package/.agents/scripts/lib/story-init/hierarchy-tracer.js +36 -0
  593. package/.agents/scripts/lib/story-init/state-transitioner.js +80 -0
  594. package/.agents/scripts/lib/story-init/task-graph-builder.js +114 -0
  595. package/.agents/scripts/lib/story-init/transition-summary.js +34 -0
  596. package/.agents/scripts/lib/story-lifecycle.js +186 -0
  597. package/.agents/scripts/lib/story-plan.js +246 -0
  598. package/.agents/scripts/lib/task-utils.js +26 -0
  599. package/.agents/scripts/lib/templates/decomposer-prompts.js +168 -0
  600. package/.agents/scripts/lib/test-env.js +30 -0
  601. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +52 -0
  602. package/.agents/scripts/lib/test-isolate/list-files.js +90 -0
  603. package/.agents/scripts/lib/test-isolate/parse-tap.js +75 -0
  604. package/.agents/scripts/lib/test-isolate/runner.js +483 -0
  605. package/.agents/scripts/lib/test-profile/parse-tap.js +136 -0
  606. package/.agents/scripts/lib/test-profile/render-report.js +45 -0
  607. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +35 -0
  608. package/.agents/scripts/lib/test-tiers.js +94 -0
  609. package/.agents/scripts/lib/util/concurrent-map.js +59 -0
  610. package/.agents/scripts/lib/util/phase-timer-state.js +72 -0
  611. package/.agents/scripts/lib/util/phase-timer.js +163 -0
  612. package/.agents/scripts/lib/util/poll-loop.js +86 -0
  613. package/.agents/scripts/lib/util/with-timeout.js +32 -0
  614. package/.agents/scripts/lib/validation-evidence.js +323 -0
  615. package/.agents/scripts/lib/wave-runner/tick.js +665 -0
  616. package/.agents/scripts/lib/wave-runner/wave-checkpoint.js +91 -0
  617. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +19 -0
  618. package/.agents/scripts/lib/workers/crap-worker.js +197 -0
  619. package/.agents/scripts/lib/workers/maintainability-report-worker.js +137 -0
  620. package/.agents/scripts/lib/workers/maintainability-worker.js +79 -0
  621. package/.agents/scripts/lib/workspace-provisioner.js +189 -0
  622. package/.agents/scripts/lib/worktree/bootstrapper.js +48 -0
  623. package/.agents/scripts/lib/worktree/inspector.js +140 -0
  624. package/.agents/scripts/lib/worktree/lifecycle/creation.js +118 -0
  625. package/.agents/scripts/lib/worktree/lifecycle/drift-detection.js +62 -0
  626. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +276 -0
  627. package/.agents/scripts/lib/worktree/lifecycle/gc.js +49 -0
  628. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +178 -0
  629. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +264 -0
  630. package/.agents/scripts/lib/worktree/lifecycle/precheck.js +100 -0
  631. package/.agents/scripts/lib/worktree/lifecycle/reap.js +588 -0
  632. package/.agents/scripts/lib/worktree/lifecycle/registry-sync.js +124 -0
  633. package/.agents/scripts/lib/worktree/lifecycle/shared.js +26 -0
  634. package/.agents/scripts/lib/worktree/lifecycle-manager.js +40 -0
  635. package/.agents/scripts/lib/worktree/node-modules-strategy.js +349 -0
  636. package/.agents/scripts/lib/worktree-manager.js +243 -0
  637. package/.agents/scripts/lifecycle-diff.js +206 -0
  638. package/.agents/scripts/lifecycle-emit-story-dispatch.js +194 -0
  639. package/.agents/scripts/lifecycle-emit.js +479 -0
  640. package/.agents/scripts/lint-baseline.js +507 -0
  641. package/.agents/scripts/lint-label-vocabulary.js +237 -0
  642. package/.agents/scripts/loc-delta.js +205 -0
  643. package/.agents/scripts/notify.js +307 -0
  644. package/.agents/scripts/package.json +3 -0
  645. package/.agents/scripts/post-structured-comment.js +127 -0
  646. package/.agents/scripts/pr-watch-with-update.js +152 -0
  647. package/.agents/scripts/providers/github/auth.js +65 -0
  648. package/.agents/scripts/providers/github/board-add.js +63 -0
  649. package/.agents/scripts/providers/github/branch-protection.js +186 -0
  650. package/.agents/scripts/providers/github/cache.js +72 -0
  651. package/.agents/scripts/providers/github/comments.js +131 -0
  652. package/.agents/scripts/providers/github/compose.js +111 -0
  653. package/.agents/scripts/providers/github/errors.js +242 -0
  654. package/.agents/scripts/providers/github/issues.js +242 -0
  655. package/.agents/scripts/providers/github/labels.js +179 -0
  656. package/.agents/scripts/providers/github/mappers.js +126 -0
  657. package/.agents/scripts/providers/github/merge-methods.js +82 -0
  658. package/.agents/scripts/providers/github/project-board.js +47 -0
  659. package/.agents/scripts/providers/github/projects-v2-graphql.js +472 -0
  660. package/.agents/scripts/providers/github/prs.js +103 -0
  661. package/.agents/scripts/providers/github/request-helpers.js +110 -0
  662. package/.agents/scripts/providers/github/sub-issues.js +369 -0
  663. package/.agents/scripts/providers/github/tickets.js +381 -0
  664. package/.agents/scripts/providers/github/transient-retry.js +62 -0
  665. package/.agents/scripts/providers/github.js +157 -0
  666. package/.agents/scripts/quality-preview.js +327 -0
  667. package/.agents/scripts/quality-watch.js +223 -0
  668. package/.agents/scripts/render-manifest.js +143 -0
  669. package/.agents/scripts/resync-status-column.js +176 -0
  670. package/.agents/scripts/retro-run.js +167 -0
  671. package/.agents/scripts/run-audit-suite.js +97 -0
  672. package/.agents/scripts/run-coverage.js +103 -0
  673. package/.agents/scripts/run-lint.js +94 -0
  674. package/.agents/scripts/run-test-profile.js +126 -0
  675. package/.agents/scripts/run-tests.js +185 -0
  676. package/.agents/scripts/run-verify.js +56 -0
  677. package/.agents/scripts/select-audits.js +155 -0
  678. package/.agents/scripts/signals-view.js +294 -0
  679. package/.agents/scripts/single-story-close.js +83 -0
  680. package/.agents/scripts/single-story-confirm-merge.js +183 -0
  681. package/.agents/scripts/single-story-init.js +692 -0
  682. package/.agents/scripts/stories-wave-tick.js +415 -0
  683. package/.agents/scripts/story-close.js +246 -0
  684. package/.agents/scripts/story-deliver-prepare.js +267 -0
  685. package/.agents/scripts/story-init.js +516 -0
  686. package/.agents/scripts/story-phase.js +327 -0
  687. package/.agents/scripts/story-plan.js +284 -0
  688. package/.agents/scripts/sync-agentrc.js +71 -0
  689. package/.agents/scripts/sync-branch-from-base.js +138 -0
  690. package/.agents/scripts/sync-claude-commands.js +151 -0
  691. package/.agents/scripts/test-isolate.js +222 -0
  692. package/.agents/scripts/test-wrapper.js +108 -0
  693. package/.agents/scripts/update-coverage-baseline.js +129 -0
  694. package/.agents/scripts/update-crap-baseline.js +177 -0
  695. package/.agents/scripts/update-duplication-baseline.js +134 -0
  696. package/.agents/scripts/update-maintainability-baseline.js +183 -0
  697. package/.agents/scripts/update-mutation-baseline.js +189 -0
  698. package/.agents/scripts/update-ticket-state.js +107 -0
  699. package/.agents/scripts/validate-docs-freshness.js +259 -0
  700. package/.agents/scripts/validate-skills.js +278 -0
  701. package/.agents/scripts/wave-tick.js +335 -0
  702. package/.agents/skills/core/analyze-execution/SKILL.md +98 -0
  703. package/.agents/skills/core/api-and-interface-design/SKILL.md +327 -0
  704. package/.agents/skills/core/baseline-refresh/SKILL.md +181 -0
  705. package/.agents/skills/core/browser-testing-with-devtools/SKILL.md +352 -0
  706. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +274 -0
  707. package/.agents/skills/core/ci-cd-and-automation/examples.md +211 -0
  708. package/.agents/skills/core/code-review-and-quality/SKILL.md +421 -0
  709. package/.agents/skills/core/code-simplification/SKILL.md +389 -0
  710. package/.agents/skills/core/context-engineering/SKILL.md +309 -0
  711. package/.agents/skills/core/context-engineering/examples.md +58 -0
  712. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +338 -0
  713. package/.agents/skills/core/deprecation-and-migration/SKILL.md +250 -0
  714. package/.agents/skills/core/diagnose-friction/SKILL.md +79 -0
  715. package/.agents/skills/core/documentation-and-adrs/SKILL.md +323 -0
  716. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +145 -0
  717. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +425 -0
  718. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +393 -0
  719. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +357 -0
  720. package/.agents/skills/core/git-workflow-and-versioning/SKILL.md +352 -0
  721. package/.agents/skills/core/hydrate-context/SKILL.md +118 -0
  722. package/.agents/skills/core/idea-refinement/SKILL.md +317 -0
  723. package/.agents/skills/core/idea-refinement/examples.md +437 -0
  724. package/.agents/skills/core/idea-refinement/frameworks.md +135 -0
  725. package/.agents/skills/core/idea-refinement/refinement-criteria.md +155 -0
  726. package/.agents/skills/core/idea-refinement/scripts/idea-refine.sh +15 -0
  727. package/.agents/skills/core/incremental-implementation/SKILL.md +271 -0
  728. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +213 -0
  729. package/.agents/skills/core/knowledge-transfer/SKILL.md +175 -0
  730. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +117 -0
  731. package/.agents/skills/core/performance-optimization/SKILL.md +314 -0
  732. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +277 -0
  733. package/.agents/skills/core/property-based-testing/SKILL.md +148 -0
  734. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +105 -0
  735. package/.agents/skills/core/refactoring-discipline/SKILL.md +111 -0
  736. package/.agents/skills/core/scope-triage/SKILL.md +127 -0
  737. package/.agents/skills/core/security-and-hardening/SKILL.md +400 -0
  738. package/.agents/skills/core/shipping-and-launch/SKILL.md +328 -0
  739. package/.agents/skills/core/spec-driven-development/SKILL.md +252 -0
  740. package/.agents/skills/core/test-driven-development/SKILL.md +475 -0
  741. package/.agents/skills/core/using-agent-skills/SKILL.md +232 -0
  742. package/.agents/skills/skills.index.json +596 -0
  743. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +31 -0
  744. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +51 -0
  745. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +48 -0
  746. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +31 -0
  747. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +33 -0
  748. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +31 -0
  749. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +51 -0
  750. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +54 -0
  751. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +29 -0
  752. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +30 -0
  753. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +57 -0
  754. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +9 -0
  755. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +48 -0
  756. package/.agents/skills/stack/frontend/astro/SKILL.md +62 -0
  757. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +30 -0
  758. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +29 -0
  759. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +50 -0
  760. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +58 -0
  761. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +34 -0
  762. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +51 -0
  763. package/.agents/skills/stack/qa/gherkin-authoring/SKILL.md +257 -0
  764. package/.agents/skills/stack/qa/gherkin-authoring/examples/invoice-issue.feature +41 -0
  765. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +199 -0
  766. package/.agents/skills/stack/qa/playwright/SKILL.md +50 -0
  767. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +188 -0
  768. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +142 -0
  769. package/.agents/skills/stack/qa/qa-harness/SKILL.md +220 -0
  770. package/.agents/skills/stack/qa/vitest/SKILL.md +51 -0
  771. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +68 -0
  772. package/.agents/starter-agentrc.json +22 -0
  773. package/.agents/templates/agent-protocol.md +72 -0
  774. package/.agents/templates/docs/architecture.md +30 -0
  775. package/.agents/templates/docs/decisions.md +24 -0
  776. package/.agents/templates/epic-from-idea.md +21 -0
  777. package/.agents/templates/single-story-body.md +17 -0
  778. package/.agents/workflows/agents-update.md +415 -0
  779. package/.agents/workflows/audit-architecture.md +312 -0
  780. package/.agents/workflows/audit-clean-code.md +179 -0
  781. package/.agents/workflows/audit-dependencies.md +91 -0
  782. package/.agents/workflows/audit-devops.md +110 -0
  783. package/.agents/workflows/audit-lighthouse.md +260 -0
  784. package/.agents/workflows/audit-performance.md +161 -0
  785. package/.agents/workflows/audit-privacy.md +104 -0
  786. package/.agents/workflows/audit-quality.md +191 -0
  787. package/.agents/workflows/audit-security.md +156 -0
  788. package/.agents/workflows/audit-seo.md +118 -0
  789. package/.agents/workflows/audit-sre.md +139 -0
  790. package/.agents/workflows/audit-to-stories.md +257 -0
  791. package/.agents/workflows/audit-ux-ui.md +102 -0
  792. package/.agents/workflows/epic-deliver.md +864 -0
  793. package/.agents/workflows/epic-plan.md +998 -0
  794. package/.agents/workflows/explain.md +118 -0
  795. package/.agents/workflows/git-cleanup.md +250 -0
  796. package/.agents/workflows/git-commit-all.md +15 -0
  797. package/.agents/workflows/git-merge-pr.md +377 -0
  798. package/.agents/workflows/git-pr-all.md +278 -0
  799. package/.agents/workflows/git-push.md +60 -0
  800. package/.agents/workflows/helpers/_merge-conflict-template.md +54 -0
  801. package/.agents/workflows/helpers/acceptance-self-eval.md +74 -0
  802. package/.agents/workflows/helpers/agents-sync-config.md +129 -0
  803. package/.agents/workflows/helpers/code-quality-guardrails.md +101 -0
  804. package/.agents/workflows/helpers/code-review.md +370 -0
  805. package/.agents/workflows/helpers/diagnose.md +117 -0
  806. package/.agents/workflows/helpers/epic-audit.md +295 -0
  807. package/.agents/workflows/helpers/epic-deliver-story.md +370 -0
  808. package/.agents/workflows/helpers/epic-plan-decompose.md +199 -0
  809. package/.agents/workflows/helpers/epic-plan-spec.md +184 -0
  810. package/.agents/workflows/helpers/epic-testing.md +125 -0
  811. package/.agents/workflows/helpers/parallel-tooling.md +88 -0
  812. package/.agents/workflows/helpers/signals.md +112 -0
  813. package/.agents/workflows/helpers/single-story-deliver.md +636 -0
  814. package/.agents/workflows/helpers/worktree-lifecycle.md +317 -0
  815. package/.agents/workflows/onboard.md +207 -0
  816. package/.agents/workflows/qa-assist.md +293 -0
  817. package/.agents/workflows/qa-explore.md +350 -0
  818. package/.agents/workflows/qa-run-harness.md +288 -0
  819. package/.agents/workflows/story-deliver.md +327 -0
  820. package/.agents/workflows/story-plan.md +233 -0
  821. package/LICENSE +21 -0
  822. package/README.md +193 -0
  823. package/bin/mandrel.js +56 -0
  824. package/bin/postinstall.js +195 -0
  825. package/lib/cli/__tests__/migrate.test.js +268 -0
  826. package/lib/cli/__tests__/sync-local-zone.test.js +247 -0
  827. package/lib/cli/__tests__/sync.test.js +372 -0
  828. package/lib/cli/__tests__/update-major.test.js +217 -0
  829. package/lib/cli/__tests__/update.test.js +696 -0
  830. package/lib/cli/__tests__/version-check.test.js +398 -0
  831. package/lib/cli/doctor.js +124 -0
  832. package/lib/cli/explain.js +107 -0
  833. package/lib/cli/migrate.js +260 -0
  834. package/lib/cli/registry.js +830 -0
  835. package/lib/cli/sync-commands.js +50 -0
  836. package/lib/cli/sync.js +200 -0
  837. package/lib/cli/uninstall.js +795 -0
  838. package/lib/cli/update.js +854 -0
  839. package/lib/cli/version-check.js +206 -0
  840. package/lib/migrations/README.md +69 -0
  841. package/lib/migrations/__tests__/index.test.js +216 -0
  842. package/lib/migrations/index.js +164 -0
  843. package/package.json +105 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * planning-artifacts.js — Phase 1 of the epic-plan-decompose pipeline
3
+ * (Story #2466). Owns the `## Planning Artifacts` body shim and the
4
+ * cross-Story conflict-policy resolver.
5
+ *
6
+ * Extracted verbatim from `epic-plan-decompose.js` so the named exports
7
+ * the existing unit tests import (`ensurePlanningArtifacts`) keep their
8
+ * public surface byte-identical.
9
+ *
10
+ * @module lib/orchestration/epic-plan-decompose/phases/planning-artifacts
11
+ */
12
+
13
+ import { resolveListValue } from '../../../config/shared.js';
14
+ import { _internal as conflictInternal } from '../../ticket-validator-conflicts.js';
15
+
16
+ /**
17
+ * Ensure the supplied Epic body carries a `## Planning Artifacts` section.
18
+ * Idempotent — when the section already exists the body is returned
19
+ * verbatim; when it's missing and `linkedIssues` carries resolved ids
20
+ * the section is appended exactly once using the canonical
21
+ * `- [ ] PRD: #N` / `Tech Spec: #N` / `Acceptance Spec: #N` lines that
22
+ * `issue-link-parser.js` recognises (so cascade-close still resolves the
23
+ * linked tickets).
24
+ *
25
+ * Story #2283.
26
+ *
27
+ * @param {string} body
28
+ * @param {{ prd: number|null, techSpec: number|null, acceptanceSpec: number|null } | undefined | null} linkedIssues
29
+ * @returns {string}
30
+ */
31
+ export function ensurePlanningArtifacts(body, linkedIssues) {
32
+ const safeBody = typeof body === 'string' ? body : '';
33
+ if (safeBody.includes('## Planning Artifacts')) return safeBody;
34
+ if (!linkedIssues) return safeBody;
35
+ const lines = [];
36
+ if (Number.isInteger(linkedIssues.prd)) {
37
+ lines.push(`- [ ] PRD: #${linkedIssues.prd}`);
38
+ }
39
+ if (Number.isInteger(linkedIssues.techSpec)) {
40
+ lines.push(`- [ ] Tech Spec: #${linkedIssues.techSpec}`);
41
+ }
42
+ if (Number.isInteger(linkedIssues.acceptanceSpec)) {
43
+ lines.push(`- [ ] Acceptance Spec: #${linkedIssues.acceptanceSpec}`);
44
+ }
45
+ if (lines.length === 0) return safeBody;
46
+ return `${safeBody}\n\n## Planning Artifacts\n${lines.join('\n')}\n`;
47
+ }
48
+
49
+ /**
50
+ * Resolve the cross-Story conflict-finding policy from `_config.planning`.
51
+ * Both flags default to `false` so existing repos keep the advisory-only
52
+ * behaviour; setting either to `true` upgrades the matching finding class
53
+ * to `'hard'`, which routes it through the validator's `errors[]` channel
54
+ * and (when called inside the bounded decompose loop) triggers a re-prompt.
55
+ */
56
+ export function resolveConflictPolicy(cfg) {
57
+ const planning = cfg?.planning;
58
+ const policy = {
59
+ failOnSharedEditors: planning?.failOnSharedEditors === true,
60
+ requireExplicitCrossStoryDeps:
61
+ planning?.requireExplicitCrossStoryDeps === true,
62
+ failOnRegistryConflicts: planning?.failOnRegistryConflicts === true,
63
+ failOnLargeFanOut: planning?.failOnLargeFanOut === true,
64
+ };
65
+ if (Number.isFinite(planning?.largeFanOutThreshold)) {
66
+ policy.largeFanOutThreshold = planning.largeFanOutThreshold;
67
+ }
68
+ if (planning?.crossCuttingRegistries !== undefined) {
69
+ policy.registries = resolveListValue(
70
+ conflictInternal.DEFAULT_REGISTRY_PATTERNS,
71
+ planning.crossCuttingRegistries,
72
+ );
73
+ }
74
+ return policy;
75
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * reconcile-spawn.js — helper for `persist.js` (Story #2466).
3
+ *
4
+ * Owns the bridge between the decomposer pipeline and the structural
5
+ * reconciler entry script (`epic-reconcile.js`). Two pieces are split
6
+ * out so `persist.js` stays under Story #2466's 200-LOC ceiling:
7
+ *
8
+ * - `RECONCILE_CLI` — the canonical path to `epic-reconcile.js` resolved
9
+ * against the phases-module location (this file lives four levels
10
+ * below `.agents/scripts/`).
11
+ * - `spawnReconcilerApply({ spawnSync, reconcileCli, epicId, cwd,
12
+ * explicitDelete })` — invokes the reconciler in `--apply --yes` mode
13
+ * (appending `--explicit-delete` when `explicitDelete` is true),
14
+ * surfaces stdout + stderr to the parent stream, and throws when the
15
+ * child exits non-zero. Returns the same `{ status, stdout, stderr }`
16
+ * envelope the legacy in-line invocation produced.
17
+ *
18
+ * Story #3905 — a `--force` re-plan with a changed ticket set produces a
19
+ * plan that carries close ops (the slugs the new plan drops). The
20
+ * reconciler hard-exits 2 on close ops unless `--explicit-delete` is
21
+ * passed. The persist phase therefore threads `--force` through to this
22
+ * helper as `explicitDelete` so a force re-decompose can actually close
23
+ * the dropped children instead of failing after the spec was already
24
+ * overwritten.
25
+ *
26
+ * @module lib/orchestration/epic-plan-decompose/phases/reconcile-spawn
27
+ */
28
+
29
+ import path from 'node:path';
30
+ import { fileURLToPath } from 'node:url';
31
+
32
+ const __filename = fileURLToPath(import.meta.url);
33
+ const __dirname = path.dirname(__filename);
34
+
35
+ // phases/ → epic-plan-decompose/ → orchestration/ → lib/ → scripts/ →
36
+ // repo-relative `epic-reconcile.js` entry point.
37
+ export const RECONCILE_CLI = path.resolve(
38
+ __dirname,
39
+ '..',
40
+ '..',
41
+ '..',
42
+ '..',
43
+ 'epic-reconcile.js',
44
+ );
45
+
46
+ /**
47
+ * Run `epic-reconcile.js --apply --yes` against `epicId`, surface stdout
48
+ * and stderr to the parent stream, and throw when the child exits
49
+ * non-zero. Returns the `{ status, stdout, stderr }` envelope used by
50
+ * the persist phase's return contract.
51
+ *
52
+ * When `explicitDelete` is true, `--explicit-delete` is appended so a
53
+ * plan carrying close ops (the common shape of a `--force` re-plan that
54
+ * dropped slugs) applies instead of hard-exiting 2 (Story #3905).
55
+ *
56
+ * @param {{ spawnSync: Function, reconcileCli: string, epicId: number, cwd: string, explicitDelete?: boolean }} args
57
+ */
58
+ export function spawnReconcilerApply({
59
+ spawnSync,
60
+ reconcileCli,
61
+ epicId,
62
+ cwd,
63
+ explicitDelete = false,
64
+ }) {
65
+ const reconcileArgs = [reconcileCli, String(epicId), '--apply', '--yes'];
66
+ if (explicitDelete) reconcileArgs.push('--explicit-delete');
67
+ const reconcileResult = spawnSync(process.execPath, reconcileArgs, {
68
+ cwd,
69
+ stdio: 'pipe',
70
+ encoding: 'utf-8',
71
+ env: { ...process.env, EPIC_RECONCILE_INVOKER: 'epic-plan-decompose' },
72
+ });
73
+ const reconcile = {
74
+ status: reconcileResult.status ?? 1,
75
+ stdout: reconcileResult.stdout ?? '',
76
+ stderr: reconcileResult.stderr ?? '',
77
+ };
78
+ if (reconcile.stdout) process.stdout.write(reconcile.stdout);
79
+ if (reconcile.stderr) process.stderr.write(reconcile.stderr);
80
+ if (reconcile.status !== 0) {
81
+ throw new Error(
82
+ `[epic-plan-decompose] epic-reconcile.js exited with status ${reconcile.status}. See stderr above.`,
83
+ );
84
+ }
85
+ return reconcile;
86
+ }
@@ -0,0 +1,235 @@
1
+ /**
2
+ * epic-plan-lease-guard.js — `/epic-plan` workflow guards (Story #3481,
3
+ * Epic #3457).
4
+ *
5
+ * Wires the assignee-as-lease primitive (`ticket-lease.js`, Story #3480) and a
6
+ * decompose-idempotency guard into the split planning flow so two concurrent
7
+ * `/epic-plan` runs cannot both drive the same Epic, and so a re-run does not
8
+ * silently duplicate the Feature/Story tree:
9
+ *
10
+ * - `acquireEpicPlanLease` — claim the Epic before Phase 7 (spec). Refuses
11
+ * (throws, exit non-zero) when a foreign claim
12
+ * already holds the Epic, naming the current
13
+ * owner. **Fail-closed (audit #3513):**
14
+ * `/epic-plan` emits no `story.heartbeat` during
15
+ * its run (heartbeats are a delivery-time
16
+ * signal), so there is no live-heartbeat source
17
+ * to judge a concurrent plan's liveness from.
18
+ * Defaulting liveness to "stale" made every
19
+ * foreign claim look reclaimable, leaving the
20
+ * guard inert. We therefore treat ANY foreign
21
+ * assignee as a live claim and refuse the take
22
+ * unless `--steal` forcibly transfers it. An
23
+ * unassigned or self-held Epic still proceeds.
24
+ * - `releaseEpicPlanLease` — release the claim after Phase 8 (decompose).
25
+ * Best-effort and self-scoped: a no-op once the
26
+ * Epic was reassigned elsewhere.
27
+ * - `assertNoOpenPlanChildren` — refuse Phase 8 persist when the Epic already
28
+ * has open Feature/Story children, unless the
29
+ * operator passed `--force` (a deliberate
30
+ * re-decompose that closes the old tree).
31
+ *
32
+ * The PRD / Tech Spec find-or-create idempotency already lives in
33
+ * `phases/plan-epic.js` (keyed on `epic.linkedIssues`); these guards add the
34
+ * cross-run mutual exclusion and the child-duplication refusal around it.
35
+ */
36
+
37
+ import { getGitHub } from '../config/github.js';
38
+ import { Logger } from '../Logger.js';
39
+ import { TYPE_LABELS } from '../label-constants.js';
40
+ import {
41
+ acquireLease,
42
+ normalizeOperatorHandle,
43
+ releaseLease,
44
+ } from './ticket-lease.js';
45
+
46
+ /**
47
+ * Resolve the operator handle that owns this `/epic-plan` run from
48
+ * `github.operatorHandle`. The assignee-as-lease primitive is single-holder
49
+ * keyed on a non-empty string; when no operator is configured (unset, or the
50
+ * shipped `@[USERNAME]` placeholder, both of which `normalizeOperatorHandle`
51
+ * maps to `null`) the lease cannot be keyed. This returns `null`; the caller
52
+ * (`acquireEpicPlanLease`) then fails closed by throwing rather than running an
53
+ * ownerless, unguarded plan.
54
+ *
55
+ * The `@`-prefix some operators carry on `operatorHandle` is stripped so the
56
+ * value matches the bare login GitHub writes to (and returns from) a ticket's
57
+ * `assignees` — otherwise the assignee PATCH is rejected (HTTP 422, invalid
58
+ * assignee) and the self-held-claim comparison (`owner === operator`) never
59
+ * matches. This mirrors the sibling lease guards
60
+ * (`single-story-lease-guard.js`, `epic-deliver-lease-guard.js`).
61
+ *
62
+ * @param {object} config Resolved config bag.
63
+ * @returns {string|null}
64
+ */
65
+ export function resolveOperator(config) {
66
+ return normalizeOperatorHandle(getGitHub(config).operatorHandle);
67
+ }
68
+
69
+ /**
70
+ * Acquire the Epic-lease before Phase 7.
71
+ *
72
+ * **Fail-closed (audit #3513).** `/epic-plan` emits no `story.heartbeat`
73
+ * during its run, so there is no live-heartbeat source to judge a concurrent
74
+ * plan's liveness from. Rather than default liveness to "stale" (which made
75
+ * every foreign claim look reclaimable and left this guard inert), we anchor
76
+ * `heartbeatAt` to the same `now` the lease primitive evaluates against. That
77
+ * makes `isClaimLive` return true for ANY foreign owner, so `acquireLease`
78
+ * refuses a foreign assignee unless `steal` is set — naming the current owner.
79
+ * An unassigned Epic (`unclaimed`) or a self-held claim (`already-held`) still
80
+ * proceeds without a write. This mirrors `single-story-lease-guard.js`.
81
+ *
82
+ * A refused claim throws (caught at the CLI boundary → exit non-zero).
83
+ *
84
+ * @param {object} args
85
+ * @param {import('../ITicketingProvider.js').ITicketingProvider} args.provider
86
+ * @param {number} args.epicId
87
+ * @param {object} [args.config]
88
+ * @param {boolean} [args.steal=false] Force-transfer a foreign claim.
89
+ * @param {number} [args.now] Injectable clock (epoch ms; tests).
90
+ * @returns {Promise<{ acquired: boolean, owner: string|null, previousOwner: string|null, reason: string }>}
91
+ */
92
+ export async function acquireEpicPlanLease({
93
+ provider,
94
+ epicId,
95
+ config,
96
+ steal = false,
97
+ now,
98
+ }) {
99
+ const operator = resolveOperator(config);
100
+ if (operator === null) {
101
+ throw new Error(
102
+ `[epic-plan] Refusing to plan Epic #${epicId}: no operator identity is ` +
103
+ 'configured. github.operatorHandle is unset or still the shipped ' +
104
+ '`@[USERNAME]` placeholder, so the Epic-lease has no owner and ' +
105
+ 'concurrent /epic-plan runs cannot be serialised. Set your own handle ' +
106
+ 'in .agentrc.local.json (e.g. { "github": { "operatorHandle": ' +
107
+ '"@your-login" } }) and re-run.',
108
+ );
109
+ }
110
+
111
+ // Fail closed: with no live-heartbeat source on the plan path, treat any
112
+ // foreign assignee as a live claim by anchoring `heartbeatAt` to the same
113
+ // `now` the primitive evaluates against (`isClaimLive` → true for any owner).
114
+ // `acquireLease` then refuses a foreign claim unless `steal` is set; an
115
+ // unassigned or self-held Epic proceeds without a write.
116
+ const resolvedNow =
117
+ typeof now === 'number' && Number.isFinite(now) ? now : Date.now();
118
+ const result = await acquireLease({
119
+ provider,
120
+ ticketId: epicId,
121
+ operator,
122
+ heartbeatAt: resolvedNow,
123
+ steal,
124
+ config,
125
+ now: resolvedNow,
126
+ });
127
+
128
+ if (!result.acquired) {
129
+ throw new Error(
130
+ `[epic-plan] Epic #${epicId} is currently claimed by '${result.owner}'. ` +
131
+ `Refusing to plan concurrently — another /epic-plan run owns this Epic ` +
132
+ `(the plan path has no heartbeat ledger, so a foreign assignee always ` +
133
+ `blocks unless stolen). Wait for that run to finish, or re-run with ` +
134
+ `--steal to forcibly transfer the claim once you have confirmed the ` +
135
+ `other run is dead.`,
136
+ );
137
+ }
138
+
139
+ Logger.info(
140
+ `[epic-plan] Acquired Epic-lease on #${epicId} for '${operator}' ` +
141
+ `(reason: ${result.reason}).`,
142
+ );
143
+ return result;
144
+ }
145
+
146
+ /**
147
+ * Release the Epic-lease after Phase 8. Best-effort: a release failure (or a
148
+ * lease already reassigned elsewhere) MUST NOT fail the decompose phase, which
149
+ * has already persisted the plan by the time release runs.
150
+ *
151
+ * @param {object} args
152
+ * @param {import('../ITicketingProvider.js').ITicketingProvider} args.provider
153
+ * @param {number} args.epicId
154
+ * @param {object} [args.config]
155
+ * @returns {Promise<{ released: boolean, owner: string|null, reason: string }>}
156
+ */
157
+ export async function releaseEpicPlanLease({ provider, epicId, config }) {
158
+ const operator = resolveOperator(config);
159
+ if (operator === null) {
160
+ return { released: false, owner: null, reason: 'no-operator' };
161
+ }
162
+ try {
163
+ const result = await releaseLease({
164
+ provider,
165
+ ticketId: epicId,
166
+ operator,
167
+ config,
168
+ });
169
+ if (result.released) {
170
+ Logger.info(`[epic-plan] Released Epic-lease on #${epicId}.`);
171
+ } else {
172
+ Logger.info(
173
+ `[epic-plan] Epic-lease on #${epicId} not released (${result.reason}).`,
174
+ );
175
+ }
176
+ return result;
177
+ } catch (err) {
178
+ Logger.warn(
179
+ `[epic-plan] Lease release on #${epicId} failed (non-fatal): ${err.message}`,
180
+ );
181
+ return { released: false, owner: null, reason: 'release-error' };
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Refuse a Phase 8 decompose-persist when the Epic already has open
187
+ * Feature/Story children, unless `force` is set. This is the idempotency guard
188
+ * that prevents a re-run from stacking a duplicate Feature/Story tree on top of
189
+ * an existing one. Under `--force` the decomposer closes and recreates the
190
+ * tree, so the guard steps aside.
191
+ *
192
+ * @param {object} args
193
+ * @param {import('../ITicketingProvider.js').ITicketingProvider} args.provider
194
+ * @param {number} args.epicId
195
+ * @param {boolean} [args.force=false]
196
+ * @returns {Promise<{ openChildren: Array<{ id: number, title: string }> }>}
197
+ */
198
+ export async function assertNoOpenPlanChildren({
199
+ provider,
200
+ epicId,
201
+ force = false,
202
+ }) {
203
+ if (force) return { openChildren: [] };
204
+
205
+ const children = await provider.getSubTickets(epicId);
206
+ const openChildren = (children ?? []).filter((t) => {
207
+ const labels = Array.isArray(t.labels) ? t.labels : [];
208
+ const isOpen = t.state === undefined || t.state === 'open';
209
+ return (
210
+ isOpen &&
211
+ (labels.includes(TYPE_LABELS.FEATURE) ||
212
+ labels.includes(TYPE_LABELS.STORY))
213
+ );
214
+ });
215
+
216
+ if (openChildren.length > 0) {
217
+ const summary = openChildren
218
+ .slice(0, 10)
219
+ .map((t) => ` - #${t.id} ${t.title}`)
220
+ .join('\n');
221
+ const more =
222
+ openChildren.length > 10
223
+ ? `\n …and ${openChildren.length - 10} more`
224
+ : '';
225
+ throw new Error(
226
+ `[epic-plan-decompose] Epic #${epicId} already has ` +
227
+ `${openChildren.length} open Feature/Story child ticket(s):\n${summary}${more}\n\n` +
228
+ `Persisting now would duplicate the breakdown. Re-run with --force to ` +
229
+ `close the existing tree and re-decompose, or close the stale children ` +
230
+ `by hand first.`,
231
+ );
232
+ }
233
+
234
+ return { openChildren: [] };
235
+ }
@@ -0,0 +1,197 @@
1
+ /**
2
+ * phases/authoring-context.js — emit-context phase.
3
+ *
4
+ * Builds the authoring context the host LLM (or the
5
+ * `epic-plan-spec-author` Skill) needs to write the PRD and Tech Spec.
6
+ * Returns a plain JSON-serialisable object; never hits the network beyond
7
+ * the provider call needed to load the Epic.
8
+ */
9
+
10
+ import * as os from 'node:os';
11
+ import path from 'node:path';
12
+ import {
13
+ resolveFeatureRoots,
14
+ verifyBddRunnerPendingTag,
15
+ } from '../../../bdd-runner-detect.js';
16
+ import { scanBddScenarios } from '../../../bdd-scenario-scanner.js';
17
+ import { buildCodebaseSnapshot } from '../../../codebase-snapshot.js';
18
+ import { getLimits, PROJECT_ROOT } from '../../../config-resolver.js';
19
+ import { scanMemoryFreshness } from '../../../feedback-loop/memory-freshness.js';
20
+ import { fetchPriorFeedback } from '../../../feedback-loop/prior-feedback-fetcher.js';
21
+ import { Logger } from '../../../Logger.js';
22
+ import { buildDocsContext } from '../../doc-reader.js';
23
+ import { applyBudget } from '../../planning-context-budget.js';
24
+ import {
25
+ ACCEPTANCE_SPEC_SYSTEM_PROMPT,
26
+ PRD_SYSTEM_PROMPT,
27
+ TECH_SPEC_SYSTEM_PROMPT,
28
+ } from './prompts.js';
29
+
30
+ /**
31
+ * Resolve the per-project memory directory used by the memory-freshness
32
+ * pre-flight (Story #2557 / Epic #2547).
33
+ *
34
+ * Resolution order:
35
+ * 1. `MANDREL_MEMORY_DIR` environment variable (test seam and operator
36
+ * override).
37
+ * 2. `~/.claude/projects/<repo>/memory/` — the standard Claude Code
38
+ * memory substrate path, scoped by the configured GitHub repo so each
39
+ * consumer project gets its own memory pool.
40
+ * 3. `null` when neither is resolvable. The scanner tolerates a missing
41
+ * `memoryDir` and surfaces a single `errors[]` entry.
42
+ *
43
+ * @param {{ github?: { owner?: string, repo?: string }|null }} opts
44
+ * @returns {string|null}
45
+ */
46
+ export function resolveMemoryDir({ github } = {}) {
47
+ if (
48
+ typeof process.env.MANDREL_MEMORY_DIR === 'string' &&
49
+ process.env.MANDREL_MEMORY_DIR.length > 0
50
+ ) {
51
+ return process.env.MANDREL_MEMORY_DIR;
52
+ }
53
+ const repo = github?.repo;
54
+ if (typeof repo !== 'string' || repo.length === 0) return null;
55
+ return path.join(os.homedir(), '.claude', 'projects', repo, 'memory');
56
+ }
57
+
58
+ /**
59
+ * Build the authoring context the host LLM (or the
60
+ * `epic-plan-spec-author` Skill) needs to write the PRD and Tech Spec.
61
+ *
62
+ * `docsContext` is bounded by the planning-context budget (Epic #817 Story 9):
63
+ * over-budget payloads downgrade to a summary representation with headings +
64
+ * bounded excerpts. Pass `{ fullContext: true }` (CLI: `--full-context`) to
65
+ * restore the unbounded full-body envelope. The Epic body itself is always
66
+ * subject to the same budget so a sprawling Epic narrative cannot bypass the
67
+ * cap by riding on top of `docsContext`.
68
+ */
69
+ export async function buildAuthoringContext(
70
+ epicId,
71
+ provider,
72
+ settings = {},
73
+ opts = {},
74
+ ) {
75
+ const epic = await provider.getEpic(epicId);
76
+ if (!epic) {
77
+ throw new Error(`Epic #${epicId} not found.`);
78
+ }
79
+
80
+ const planningLimits = getLimits(settings).planningContext;
81
+ const { fullContext = false } = opts;
82
+
83
+ const docsContext = await buildDocsContext(settings, planningLimits, {
84
+ fullContext,
85
+ });
86
+
87
+ const epicBody = applyBudget(
88
+ [{ path: `epic-${epic.id}.md`, content: epic.body ?? '' }],
89
+ planningLimits,
90
+ { fullContext },
91
+ );
92
+
93
+ // Story #2094 Task #2103 — verify the project's BDD runner pending-tag
94
+ // support so the acceptance-spec body can record either the verified tag
95
+ // (features-first ordering) or "fallback: dependencies-first ordering"
96
+ // when no supported runner is present.
97
+ const bddRunner = await verifyBddRunnerPendingTag({ cwd: PROJECT_ROOT });
98
+
99
+ // Story #2637 — index existing BDD scenarios so the Acceptance Engineer
100
+ // step can annotate planned ACs with matches from the project's
101
+ // `.feature` files. Empty array when the project has not adopted BDD;
102
+ // the scanner is best-effort and never throws on filesystem errors.
103
+ let bddScenarios = [];
104
+ try {
105
+ const featureRoots = resolveFeatureRoots({ cwd: PROJECT_ROOT });
106
+ bddScenarios = scanBddScenarios({ featureRoots });
107
+ } catch (err) {
108
+ Logger.warn(`[epic-plan-spec] BDD scenario scan skipped: ${err.message}`);
109
+ }
110
+
111
+ // Story #2557 — memory-freshness pre-flight runs BEFORE the prior-feedback
112
+ // fetch so the planner sees a deduplicated, currently-actionable memory
113
+ // store. The scanner is best-effort: missing memory dir or gh-CLI failures
114
+ // land in `memoryFreshness.errors[]` and never throw.
115
+ const githubCfg = opts.github ?? null;
116
+ const memoryDir = resolveMemoryDir({ github: githubCfg });
117
+ const memoryFreshness = await scanMemoryFreshness({
118
+ memoryDir,
119
+ owner: githubCfg?.owner,
120
+ repo: githubCfg?.repo,
121
+ projectRoot: PROJECT_ROOT,
122
+ });
123
+
124
+ // Story #2554 — surface open meta feedback issues to the planner so retro
125
+ // signals are routed into durable substrates rather than lost in chat.
126
+ // The fetcher is best-effort: missing owner/repo or gh-CLI failures land
127
+ // in `errors[]` and never throw.
128
+ const priorFeedback = await fetchPriorFeedback({
129
+ owner: githubCfg?.owner,
130
+ repo: githubCfg?.repo,
131
+ });
132
+
133
+ // Story #2634 — codebase snapshot. Generates a bounded structural view
134
+ // of the consumer repo (file tree + package surface + recent activity
135
+ // + optional export signatures at the `medium` tier) so the Architect
136
+ // can prefer real module names over doc-only ones. The check is
137
+ // best-effort: any git/filesystem error degrades to an empty snapshot
138
+ // so Phase 7 stays non-blocking.
139
+ let codebaseSnapshot = null;
140
+ try {
141
+ codebaseSnapshot = buildCodebaseSnapshot({
142
+ cwd: PROJECT_ROOT,
143
+ tier: settings?.planning?.codebaseSnapshot?.tier,
144
+ include: settings?.planning?.codebaseSnapshot?.include,
145
+ exclude: settings?.planning?.codebaseSnapshot?.exclude,
146
+ recentCommitWindow:
147
+ settings?.planning?.codebaseSnapshot?.recentCommitWindow,
148
+ });
149
+ // Story #3959 — when the skinny-tier cap drops files, the degradation
150
+ // used to be silent (only `truncated: true` on the envelope). Surface
151
+ // an operator-visible warning naming the dropped count and the two
152
+ // remedies so the spec author knows the snapshot is partial and can
153
+ // either opt into the richer `medium` tier or narrow `include`.
154
+ if (codebaseSnapshot?.truncated) {
155
+ const dropped = Math.max(
156
+ 0,
157
+ (codebaseSnapshot.fileCount ?? 0) -
158
+ (codebaseSnapshot.files?.length ?? 0),
159
+ );
160
+ Logger.warn(
161
+ `[epic-plan-spec] codebase snapshot truncated: ${dropped} of ` +
162
+ `${codebaseSnapshot.fileCount} matched file(s) dropped from the ` +
163
+ `skinny-tier view. The spec-author context is partial. To restore ` +
164
+ `full grounding, set planning.codebaseSnapshot.tier: "medium" ` +
165
+ `and/or narrow planning.codebaseSnapshot.include in .agentrc.json.`,
166
+ );
167
+ }
168
+ } catch (err) {
169
+ Logger.warn(`[epic-plan-spec] codebase snapshot skipped: ${err.message}`);
170
+ }
171
+
172
+ // Epic #3865 — planning risk is no longer classified at emit-context
173
+ // time. The `epic-plan-spec-author` Skill authors the risk verdict
174
+ // (`risk-verdict.json`) as the fourth planning artifact, and the persist
175
+ // half derives the planningRisk envelope from it via deriveRiskEnvelope.
176
+
177
+ return {
178
+ epic: {
179
+ id: epic.id,
180
+ title: epic.title,
181
+ body: epicBody.mode === 'full' ? epic.body : null,
182
+ bodySummary: epicBody.mode === 'summary' ? epicBody.items[0] : null,
183
+ linkedIssues: epic.linkedIssues ?? { prd: null, techSpec: null },
184
+ },
185
+ docsContext,
186
+ codebaseSnapshot,
187
+ systemPrompts: {
188
+ prd: PRD_SYSTEM_PROMPT,
189
+ techSpec: TECH_SPEC_SYSTEM_PROMPT,
190
+ acceptanceSpec: ACCEPTANCE_SPEC_SYSTEM_PROMPT,
191
+ },
192
+ bddRunner,
193
+ bddScenarios,
194
+ memoryFreshness,
195
+ priorFeedback,
196
+ };
197
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * cli-args.js — argv parsing + validation for the `epic-plan-spec` CLI.
3
+ *
4
+ * Extracted from `epic-plan-spec.js` (refs #3685) so the top-level entry
5
+ * stays a thin wire-up that scores at or above the maintainability floor;
6
+ * the option schema and the epic-id guards live here.
7
+ */
8
+
9
+ import { parseArgs } from 'node:util';
10
+
11
+ /**
12
+ * Parse and validate the `epic-plan-spec` CLI arguments.
13
+ *
14
+ * @param {string[]} [argv] Defaults to `process.argv.slice(2)`.
15
+ * @returns {{ values: Record<string, unknown>, epicId: number }}
16
+ * @throws {Error} when `--epic` is missing or not a number.
17
+ */
18
+ export function parseEpicPlanSpecArgs(argv = process.argv.slice(2)) {
19
+ const { values } = parseArgs({
20
+ args: argv,
21
+ options: {
22
+ epic: { type: 'string' },
23
+ prd: { type: 'string' },
24
+ techspec: { type: 'string' },
25
+ 'acceptance-spec': { type: 'string' },
26
+ 'risk-verdict': { type: 'string' },
27
+ force: { type: 'boolean', default: false },
28
+ 'force-review': { type: 'boolean', default: false },
29
+ steal: { type: 'boolean', default: false },
30
+ 'emit-context': { type: 'boolean', default: false },
31
+ pretty: { type: 'boolean', default: false },
32
+ 'full-context': { type: 'boolean', default: false },
33
+ },
34
+ });
35
+
36
+ if (!values.epic) {
37
+ throw new Error(
38
+ 'Usage: epic-plan-spec.js --epic <EpicId> (--emit-context [--pretty] [--full-context] | --prd <file> --techspec <file> --risk-verdict <file> [--acceptance-spec <file>]) [--force]',
39
+ );
40
+ }
41
+
42
+ const epicId = Number.parseInt(values.epic, 10);
43
+ if (Number.isNaN(epicId)) {
44
+ throw new Error(`Invalid epic ID: "${values.epic}" — must be a number.`);
45
+ }
46
+
47
+ return { values, epicId };
48
+ }