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,378 @@
1
+ // .agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js
2
+ /**
3
+ * AcceptanceReconciler — lifecycle listener that gates Finalize on the
4
+ * close-time acceptance-spec reconciliation. Story #2253 (Epic #2172):
5
+ * the reconciliation moves *ahead* of the push + `gh pr create` call so
6
+ * that AC coverage gaps block PR creation (review High-2).
7
+ *
8
+ * Subscribes to:
9
+ * - `epic.close.end` → emit `acceptance.reconcile.start`, run the
10
+ * `reconcileAcceptanceSpec` helper, emit one of
11
+ * `acceptance.reconcile.ok | .waived | .skipped | .failed`, and on
12
+ * `.failed` also emit `epic.blocked` so the LabelTransitioner /
13
+ * StructuredCommentPoster / NotifyDispatcher trio fire the blocker
14
+ * side effects exactly as a `story.blocked` cascade would.
15
+ *
16
+ * The Finalizer listener subscribes ONLY to `acceptance.reconcile.ok`,
17
+ * so this listener is the authoritative safety gate ahead of any push
18
+ * or PR-create work. The legacy `epic-deliver-finalize.js` shim still
19
+ * exists for backwards compatibility, but its in-line reconciliation
20
+ * call is replaced by the event-driven path.
21
+ *
22
+ * Idempotency contract (Acceptance Spec AC-10):
23
+ * - Per-instance `Set<string>` of `${event}:${seqId}` keys. A repeat
24
+ * `(event, seqId)` short-circuits without re-running reconciliation
25
+ * and emits no events.
26
+ * - The reconciler helper itself is read-only with respect to runtime
27
+ * state, so the seqId guard is the only defence the listener needs.
28
+ *
29
+ * Side-effect firewall: the listener owns the reconciliation call and
30
+ * the four outcome emits. It does NOT mutate labels, post comments, or
31
+ * call `notify` directly — those are downstream listener concerns.
32
+ */
33
+
34
+ import { reconcileAcceptanceSpec as defaultReconcileAcceptanceSpec } from '../../../../acceptance-spec-reconciler.js';
35
+
36
+ /**
37
+ * Classify a `reconcileAcceptanceSpec` result envelope into the typed
38
+ * outcome event the listener should emit. Pure function — exported so
39
+ * unit tests can drive every branch without a bus instance.
40
+ *
41
+ * The reconciler exposes a four-value `status` discriminant:
42
+ * - `'waived'` → the Epic carries `acceptance::n-a` (or no linked
43
+ * spec under `--skip-when-waived`). Emit
44
+ * `acceptance.reconcile.waived` with reason
45
+ * `'waiver'`. Story #2893 split this out from
46
+ * `.skipped` so the Finalizer can subscribe to
47
+ * `.waived` and route waived Epics through to PR
48
+ * creation, while empty-spec Epics still
49
+ * terminate without a PR via `.skipped`.
50
+ * - `'empty-spec'` → the linked spec exists but declares zero AC IDs.
51
+ * Treated as "no work to do"; emit `.skipped` with
52
+ * reason `'empty-spec'` so operators see the
53
+ * outcome explicitly (no silent skip).
54
+ * - `'ok'` → the spec has AC IDs and every one is covered by
55
+ * a non-pending scenario. Emit `.ok`.
56
+ * - `'gap'` → at least one AC is pending or missing. Emit
57
+ * `.failed` carrying a compact reason summary;
58
+ * the listener then emits `epic.blocked` to flip
59
+ * the Epic ticket.
60
+ *
61
+ * @param {object|undefined|null} result reconciler envelope.
62
+ * @returns {{ outcome: 'ok'|'waived'|'skipped'|'failed', reason?: string }}
63
+ */
64
+ export function classifyReconcileResult(result) {
65
+ if (!result || typeof result !== 'object') {
66
+ return { outcome: 'failed', reason: 'reconciler-no-result' };
67
+ }
68
+ const status = result.status;
69
+ if (status === 'waived') {
70
+ return { outcome: 'waived', reason: 'waiver' };
71
+ }
72
+ if (status === 'empty-spec') {
73
+ return { outcome: 'skipped', reason: 'empty-spec' };
74
+ }
75
+ if (status === 'ok') {
76
+ return { outcome: 'ok' };
77
+ }
78
+ if (status === 'gap') {
79
+ const missing = Array.isArray(result.missing) ? result.missing : [];
80
+ const pending = Array.isArray(result.pending) ? result.pending : [];
81
+ const parts = [];
82
+ if (missing.length > 0) parts.push(`missing=${missing.join(',')}`);
83
+ if (pending.length > 0) parts.push(`pending=${pending.join(',')}`);
84
+ const reason =
85
+ parts.length > 0 ? `gap:${parts.join(';')}` : 'gap:unspecified';
86
+ return { outcome: 'failed', reason };
87
+ }
88
+ // Unknown status — fail closed so the operator sees the surprise.
89
+ return { outcome: 'failed', reason: `unknown-status:${String(status)}` };
90
+ }
91
+
92
+ /**
93
+ * AcceptanceReconciler — instantiate one per Epic run and call
94
+ * `register()` to wire it onto the bus. Stateless w.r.t. the system
95
+ * under orchestration; per-run state is the `(event, seqId)`
96
+ * idempotency cache + the classification log.
97
+ */
98
+ export class AcceptanceReconciler {
99
+ /**
100
+ * @param {object} opts
101
+ * @param {object} opts.bus Lifecycle bus instance (must expose
102
+ * `on()` and `emit()`).
103
+ * @param {number} opts.epicId Epic ticket id.
104
+ * @param {string} [opts.cwd] Working directory passed through to the
105
+ * reconciler helper. Defaults to `process.cwd()`.
106
+ * @param {object} [opts.provider] Ticketing provider — injected into
107
+ * the reconciler call so the lifecycle bus does not need to
108
+ * construct one itself.
109
+ * @param {object} [opts.config] Resolved orchestration config —
110
+ * injected for the same reason.
111
+ * @param {Function} [opts.reconcileAcceptanceSpecFn] Override of the
112
+ * helper for tests; defaults to the production export.
113
+ * @param {{ info?: Function, warn?: Function, debug?: Function }} [opts.logger]
114
+ */
115
+ constructor(opts = {}) {
116
+ if (
117
+ !opts.bus ||
118
+ typeof opts.bus.on !== 'function' ||
119
+ typeof opts.bus.emit !== 'function'
120
+ ) {
121
+ throw new TypeError(
122
+ 'AcceptanceReconciler requires a bus with on() and emit()',
123
+ );
124
+ }
125
+ if (!Number.isInteger(opts.epicId) || opts.epicId < 1) {
126
+ throw new TypeError('AcceptanceReconciler requires a numeric epicId');
127
+ }
128
+ this.bus = opts.bus;
129
+ this.epicId = opts.epicId;
130
+ this.cwd = opts.cwd ?? process.cwd();
131
+ this.provider = opts.provider ?? null;
132
+ this.config = opts.config ?? null;
133
+ this.reconcileAcceptanceSpecFn =
134
+ opts.reconcileAcceptanceSpecFn ?? defaultReconcileAcceptanceSpec;
135
+ this.logger = opts.logger ?? console;
136
+ /** @type {Set<string>} `${event}:${seqId}` keys we've handled. */
137
+ this._seen = new Set();
138
+ /**
139
+ * Classification log — mirrors the BlockerHandler "no silent skip"
140
+ * surface so tests can confirm every `epic.close.end` we observed
141
+ * was classified into exactly one outcome.
142
+ *
143
+ * @type {Array<{ event: string, seqId: number, outcome: string, reason?: string }>}
144
+ */
145
+ this.classifications = [];
146
+ this.events = Object.freeze(['epic.close.end']);
147
+ }
148
+
149
+ /**
150
+ * Register this listener on the bus. Returns an array of unsubscribe
151
+ * functions (one per event) for test teardown.
152
+ */
153
+ register() {
154
+ return this.events.map((event) =>
155
+ this.bus.on(event, async (ctx) => this.handle(ctx)),
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Bus listener body. The bus passes `{ event, seqId, payload }`. The
161
+ * listener:
162
+ * 1. Idempotently short-circuits a repeat `(event, seqId)`.
163
+ * 2. Emits `acceptance.reconcile.start`.
164
+ * 3. Runs `reconcileAcceptanceSpec` with injected provider/config.
165
+ * 4. Emits exactly one of `.ok` / `.skipped` / `.failed`.
166
+ * 5. On `.failed`, additionally emits `epic.blocked` so the
167
+ * downstream listener trio (label flip + structured comment +
168
+ * notify) fires the operator-visible blocker side effects.
169
+ *
170
+ * The listener does NOT throw on reconciler failures: the bus's
171
+ * `onFailed` boundary already persists the originating
172
+ * `epic.close.end` record; surfacing a throw here would short-circuit
173
+ * other `epic.close.end` listeners (e.g. trace logger) and is not
174
+ * needed for correctness — the `acceptance.reconcile.failed` +
175
+ * `epic.blocked` emits are the cascade contract.
176
+ *
177
+ * @param {{ event: string, seqId: number, payload: object }} ctx
178
+ */
179
+ async handle({ event, seqId, payload }) {
180
+ const key = `${event}:${seqId}`;
181
+ if (this._seen.has(key)) {
182
+ this.classifications.push({
183
+ event,
184
+ seqId,
185
+ outcome: 'skipped',
186
+ reason: 'duplicate-seqId',
187
+ });
188
+ this.logger.debug?.(
189
+ `[AcceptanceReconciler] skip duplicate ${key} (idempotent)`,
190
+ );
191
+ return;
192
+ }
193
+ this._seen.add(key);
194
+
195
+ const epicIdFromPayload = Number(payload?.epicId);
196
+ const epicId = Number.isInteger(epicIdFromPayload)
197
+ ? epicIdFromPayload
198
+ : this.epicId;
199
+
200
+ // 1. Start emit. The downstream lifecycle-diff `reconcile-ordering`
201
+ // assert checks for `acceptance.reconcile.ok` before `pr.created`,
202
+ // but operators want to see the `.start` marker in the trace too.
203
+ try {
204
+ await this.bus.emit('acceptance.reconcile.start', { epicId });
205
+ } catch (err) {
206
+ // Schema validation against a known-good payload should never
207
+ // throw; if it does, surface and bail — there's no point running
208
+ // the reconciler when we cannot announce its outcome.
209
+ this.classifications.push({
210
+ event,
211
+ seqId,
212
+ outcome: 'failed',
213
+ reason: `start-emit-failed:${err?.message ?? err}`,
214
+ });
215
+ this.logger.warn?.(
216
+ `[AcceptanceReconciler] acceptance.reconcile.start emit failed: ${err?.message ?? err}`,
217
+ );
218
+ return;
219
+ }
220
+
221
+ // 2. Run the reconciler. The helper itself throws on hard errors
222
+ // (no linked spec + no waiver, etc.); convert those into
223
+ // `.failed` emits rather than re-propagating, so the cascade
224
+ // contract holds even when the spec is malformed.
225
+ let result;
226
+ let thrown = null;
227
+ try {
228
+ result = await this.reconcileAcceptanceSpecFn({
229
+ epicId,
230
+ cwd: this.cwd,
231
+ injectedProvider: this.provider ?? undefined,
232
+ injectedConfig: this.config ?? undefined,
233
+ loggerImpl: this.logger,
234
+ // Honour `acceptance::n-a` — the helper already returns
235
+ // `status: 'waived'` for that label, but `skipWhenWaived: true`
236
+ // additionally tolerates a missing spec link under the waiver
237
+ // (we want the same forgiving stance the inline finalize call
238
+ // had).
239
+ skipWhenWaived: true,
240
+ });
241
+ } catch (err) {
242
+ thrown = err;
243
+ }
244
+
245
+ const baseRead = thrown == null && result != null;
246
+
247
+ if (thrown != null) {
248
+ const reason = `reconcile-threw:${thrown?.message ?? thrown}`;
249
+ await this._emitFailure({ event, seqId, baseRead, reason });
250
+ return;
251
+ }
252
+
253
+ const classification = classifyReconcileResult(result);
254
+ if (classification.outcome === 'ok') {
255
+ await this._emitOk({ event, seqId, baseRead });
256
+ return;
257
+ }
258
+ if (classification.outcome === 'waived') {
259
+ await this._emitWaived({
260
+ event,
261
+ seqId,
262
+ baseRead,
263
+ reason: classification.reason ?? 'waiver',
264
+ });
265
+ return;
266
+ }
267
+ if (classification.outcome === 'skipped') {
268
+ await this._emitSkipped({
269
+ event,
270
+ seqId,
271
+ baseRead,
272
+ reason: classification.reason ?? 'skipped',
273
+ });
274
+ return;
275
+ }
276
+ await this._emitFailure({
277
+ event,
278
+ seqId,
279
+ baseRead,
280
+ reason: classification.reason ?? 'gap',
281
+ });
282
+ }
283
+
284
+ /**
285
+ * Emit `acceptance.reconcile.ok` and record the classification.
286
+ * Helper carved out so each branch in `handle()` reads as a single
287
+ * decision.
288
+ */
289
+ async _emitOk({ event, seqId, baseRead }) {
290
+ this.classifications.push({ event, seqId, outcome: 'ok' });
291
+ try {
292
+ await this.bus.emit('acceptance.reconcile.ok', { baseRead });
293
+ } catch (err) {
294
+ this.logger.warn?.(
295
+ `[AcceptanceReconciler] acceptance.reconcile.ok emit failed (swallowed): ${err?.message ?? err}`,
296
+ );
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Emit `acceptance.reconcile.waived` for the `acceptance::n-a` path.
302
+ * Story #2893 split this out of `.skipped` so the Finalizer can
303
+ * subscribe to `.waived` and route waived Epics through to PR
304
+ * creation. The schema pins `reason` to `'waiver'`.
305
+ */
306
+ async _emitWaived({ event, seqId, baseRead, reason }) {
307
+ this.classifications.push({ event, seqId, outcome: 'waived', reason });
308
+ try {
309
+ await this.bus.emit('acceptance.reconcile.waived', {
310
+ baseRead,
311
+ reason,
312
+ });
313
+ } catch (err) {
314
+ this.logger.warn?.(
315
+ `[AcceptanceReconciler] acceptance.reconcile.waived emit failed (swallowed): ${err?.message ?? err}`,
316
+ );
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Emit `acceptance.reconcile.skipped` carrying a typed `reason`. The
322
+ * schema requires `reason` to be non-empty so callers always pass one
323
+ * (no silent skip).
324
+ */
325
+ async _emitSkipped({ event, seqId, baseRead, reason }) {
326
+ this.classifications.push({ event, seqId, outcome: 'skipped', reason });
327
+ try {
328
+ await this.bus.emit('acceptance.reconcile.skipped', {
329
+ baseRead,
330
+ reason,
331
+ });
332
+ } catch (err) {
333
+ this.logger.warn?.(
334
+ `[AcceptanceReconciler] acceptance.reconcile.skipped emit failed (swallowed): ${err?.message ?? err}`,
335
+ );
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Emit `acceptance.reconcile.failed` and then `epic.blocked`, in that
341
+ * order. The `epic.blocked` emit drives the LabelTransitioner /
342
+ * StructuredCommentPoster / NotifyDispatcher trio so the operator
343
+ * sees the blocker label flip + structured comment + webhook,
344
+ * exactly as a `story.blocked` cascade would.
345
+ *
346
+ * Failures inside the `epic.blocked` emit are swallowed (the
347
+ * `.failed` record is already on the ledger; double-throwing here
348
+ * would mask the original reason).
349
+ */
350
+ async _emitFailure({ event, seqId, baseRead, reason }) {
351
+ this.classifications.push({ event, seqId, outcome: 'failed', reason });
352
+ try {
353
+ await this.bus.emit('acceptance.reconcile.failed', {
354
+ baseRead,
355
+ reason,
356
+ });
357
+ } catch (err) {
358
+ this.logger.warn?.(
359
+ `[AcceptanceReconciler] acceptance.reconcile.failed emit failed (swallowed): ${err?.message ?? err}`,
360
+ );
361
+ }
362
+ try {
363
+ await this.bus.emit('epic.blocked', {
364
+ reason: `acceptance-reconcile:${reason}`,
365
+ });
366
+ } catch (err) {
367
+ this.logger.warn?.(
368
+ `[AcceptanceReconciler] epic.blocked emit failed (swallowed): ${err?.message ?? err}`,
369
+ );
370
+ }
371
+ }
372
+
373
+ /** Test helper — wipe the idempotency cache. */
374
+ reset() {
375
+ this._seen.clear();
376
+ this.classifications = [];
377
+ }
378
+ }
@@ -0,0 +1,248 @@
1
+ // .agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js
2
+ /**
3
+ * AutomergeArmer — lifecycle listener that arms GitHub's native
4
+ * auto-merge after the AutomergePredicate signals a clean run.
5
+ * Story #2256 / Task #2262 (Epic #2172).
6
+ *
7
+ * Subscribes to:
8
+ * - `epic.merge.ready` → and ONLY this event.
9
+ *
10
+ * Side effects executed inside `handle()`:
11
+ * 1. Probe `gh pr view <pr> --json autoMergeRequest` — if auto-merge
12
+ * is already armed on the PR, short-circuit to a single
13
+ * `epic.merge.armed` emit without re-issuing the merge command.
14
+ * This is AC-10 (idempotency) for the second non-trivial
15
+ * idempotency case (cross-process re-arm after a crash between
16
+ * `gh pr merge --auto` and the `epic.merge.armed` emit).
17
+ * 2. Otherwise call `gh pr merge --auto --squash --delete-branch`.
18
+ * `--auto` queues the merge with GitHub; the actual merge happens
19
+ * asynchronously after every required check goes green and every
20
+ * required approval lands.
21
+ * 3. Emit `epic.merge.armed` once the merge call succeeds (or the
22
+ * probe established that a prior arm is already in place).
23
+ *
24
+ * Critical contract — sole `gh pr merge` caller:
25
+ * - This file is the ONLY production code path authorized to invoke
26
+ * `gh pr merge`. The merge-lockout ESLint rule in
27
+ * `.agents/scripts/check-lifecycle-lint.js` enforces this by
28
+ * allow-listing only this file's suffix. Maintainers: any future
29
+ * `gh pr merge` call site is a safety regression unless the lockout
30
+ * rule is updated AT THE SAME TIME with an architectural review.
31
+ *
32
+ * - The listener subscribes to `epic.merge.ready` and NOTHING ELSE.
33
+ * The merge-gate-ordering invariant test asserts that
34
+ * `epic.merge.armed` is preceded by `epic.merge.ready` from the
35
+ * same run; if a future refactor wires a second event into this
36
+ * listener, the invariant test catches it.
37
+ *
38
+ * Idempotency contract (AC-10): two-layer defence.
39
+ * 1. Per-instance `Set<string>` of `${event}:${seqId}` keys — repeat
40
+ * `(event, seqId)` invocation short-circuits and emits nothing.
41
+ * This is the bus-level replay defence.
42
+ * 2. The `gh pr view` probe — short-circuits across process
43
+ * boundaries when a prior run already armed auto-merge. This is
44
+ * the recovery defence: `/epic-deliver` restarted on the same PR
45
+ * will see the existing arm and emit `epic.merge.armed` exactly
46
+ * once.
47
+ *
48
+ * Side-effect firewall: the listener emits on the bus and shells out
49
+ * to `gh`. It does NOT mutate ticket labels, post comments, or call
50
+ * `notify`. Downstream listeners (LabelTransitioner /
51
+ * StructuredCommentPoster on `epic.merge.armed`) own those side
52
+ * effects.
53
+ */
54
+
55
+ import { spawnSync } from 'node:child_process';
56
+
57
+ /**
58
+ * Default `gh pr view --json autoMergeRequest` probe. Pure-spawn helper
59
+ * — exported so tests can stub the shell-out without touching the
60
+ * spawn wrapper.
61
+ */
62
+ export function ghPrViewAutoMerge({ prUrl, cwd, spawnFn = spawnSync }) {
63
+ const result = spawnFn(
64
+ 'gh',
65
+ ['pr', 'view', prUrl, '--json', 'autoMergeRequest'],
66
+ { cwd, encoding: 'utf-8', shell: false },
67
+ );
68
+ return {
69
+ status: result.status ?? 1,
70
+ stdout: result.stdout ?? '',
71
+ stderr: result.stderr ?? '',
72
+ };
73
+ }
74
+
75
+ /**
76
+ * Default `gh pr merge --auto --squash --delete-branch` arm. Pure-spawn
77
+ * helper. Exported so tests can stub. The arg list is captured in a
78
+ * single helper so the merge-lockout lint allow-list narrows to one
79
+ * literal site.
80
+ */
81
+ export function ghPrMergeAuto({ prUrl, cwd, spawnFn = spawnSync }) {
82
+ const result = spawnFn(
83
+ 'gh',
84
+ ['pr', 'merge', prUrl, '--auto', '--squash', '--delete-branch'],
85
+ { cwd, encoding: 'utf-8', shell: false },
86
+ );
87
+ return {
88
+ status: result.status ?? 1,
89
+ stdout: result.stdout ?? '',
90
+ stderr: result.stderr ?? '',
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Pure: parse `gh pr view --json autoMergeRequest` output. The field
96
+ * is `null` when auto-merge is NOT armed; a non-null object means a
97
+ * prior arm is in place. Returns `true` iff already armed.
98
+ *
99
+ * Exported for tests so the JSON shape pin is reviewable.
100
+ */
101
+ export function parseAutoMergeArmed(stdout) {
102
+ const trimmed = String(stdout ?? '').trim();
103
+ if (trimmed.length === 0) return false;
104
+ try {
105
+ const parsed = JSON.parse(trimmed);
106
+ if (!parsed || typeof parsed !== 'object') return false;
107
+ // `autoMergeRequest: null` → not armed.
108
+ // `autoMergeRequest: { mergeMethod, enabledBy, … }` → armed.
109
+ return (
110
+ parsed.autoMergeRequest !== null &&
111
+ parsed.autoMergeRequest !== undefined &&
112
+ typeof parsed.autoMergeRequest === 'object'
113
+ );
114
+ } catch {
115
+ return false;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * AutomergeArmer listener.
121
+ */
122
+ export class AutomergeArmer {
123
+ /**
124
+ * @param {object} opts
125
+ * @param {object} opts.bus
126
+ * @param {string} [opts.cwd]
127
+ * @param {Function} [opts.ghPrViewAutoMergeFn] override for tests.
128
+ * @param {Function} [opts.ghPrMergeAutoFn] override for tests.
129
+ * @param {{ info?: Function, warn?: Function, debug?: Function }} [opts.logger]
130
+ */
131
+ constructor(opts = {}) {
132
+ if (
133
+ !opts.bus ||
134
+ typeof opts.bus.on !== 'function' ||
135
+ typeof opts.bus.emit !== 'function'
136
+ ) {
137
+ throw new TypeError('AutomergeArmer requires a bus with on() and emit()');
138
+ }
139
+ this.bus = opts.bus;
140
+ this.cwd = opts.cwd ?? process.cwd();
141
+ this.ghPrViewAutoMergeFn = opts.ghPrViewAutoMergeFn ?? ghPrViewAutoMerge;
142
+ this.ghPrMergeAutoFn = opts.ghPrMergeAutoFn ?? ghPrMergeAuto;
143
+ this.logger = opts.logger ?? console;
144
+ /** @type {Set<string>} `${event}:${seqId}` idempotency cache. */
145
+ this._seen = new Set();
146
+ /**
147
+ * Classification log — every `epic.merge.ready` observed lands here
148
+ * with the outcome (`armed`, `existing`, `skipped-duplicate`,
149
+ * `failed`). Mirrors the Finalizer / Reconciler "no silent skip"
150
+ * surface.
151
+ */
152
+ this.classifications = [];
153
+ // Frozen tuple — the merge-gate-ordering invariant depends on this
154
+ // listener listening for EXACTLY one event. A test asserts the
155
+ // length of this array.
156
+ this.events = Object.freeze(['epic.merge.ready']);
157
+ }
158
+
159
+ register() {
160
+ return this.events.map((event) =>
161
+ this.bus.on(event, async (ctx) => this.handle(ctx)),
162
+ );
163
+ }
164
+
165
+ async handle({ event, seqId, payload }) {
166
+ const key = `${event}:${seqId}`;
167
+ if (this._seen.has(key)) {
168
+ this.classifications.push({
169
+ event,
170
+ seqId,
171
+ outcome: 'skipped',
172
+ reason: 'duplicate-seqId',
173
+ });
174
+ this.logger.debug?.(
175
+ `[AutomergeArmer] skip duplicate ${key} (idempotent)`,
176
+ );
177
+ return;
178
+ }
179
+ this._seen.add(key);
180
+
181
+ const prUrl = payload?.prUrl;
182
+ if (typeof prUrl !== 'string' || prUrl.length === 0) {
183
+ this.classifications.push({
184
+ event,
185
+ seqId,
186
+ outcome: 'failed',
187
+ reason: 'no-pr-url',
188
+ });
189
+ return;
190
+ }
191
+
192
+ // Layer 2 idempotency — cross-process probe. If auto-merge is
193
+ // already armed on the PR, emit `epic.merge.armed` and bail
194
+ // without re-issuing the merge command.
195
+ const probe = this.ghPrViewAutoMergeFn({ prUrl, cwd: this.cwd });
196
+ if (probe.status === 0 && parseAutoMergeArmed(probe.stdout)) {
197
+ this.classifications.push({ event, seqId, outcome: 'existing', prUrl });
198
+ this.logger.info?.(
199
+ `[AutomergeArmer] auto-merge already armed on ${prUrl} — short-circuiting.`,
200
+ );
201
+ await this._emitArmed(prUrl);
202
+ return;
203
+ }
204
+ if (probe.status !== 0) {
205
+ // The probe itself failed; degrade to "no probe" rather than
206
+ // throwing — the arm call will surface its own error if it
207
+ // genuinely cannot proceed. We log the probe failure for audit.
208
+ this.logger.warn?.(
209
+ `[AutomergeArmer] gh pr view probe failed (status=${probe.status}): ${probe.stderr} — proceeding with arm.`,
210
+ );
211
+ }
212
+
213
+ // Arm. This is the sole authorized `gh pr merge` call site in the
214
+ // entire codebase (see check-lifecycle-lint.js).
215
+ const arm = this.ghPrMergeAutoFn({ prUrl, cwd: this.cwd });
216
+ if (arm.status !== 0) {
217
+ this.classifications.push({
218
+ event,
219
+ seqId,
220
+ outcome: 'failed',
221
+ reason: `arm-failed:status=${arm.status}`,
222
+ ghStderr: arm.stderr,
223
+ });
224
+ this.logger.warn?.(
225
+ `[AutomergeArmer] gh pr merge --auto failed (status=${arm.status}): ${arm.stderr}`,
226
+ );
227
+ return;
228
+ }
229
+
230
+ this.classifications.push({ event, seqId, outcome: 'armed', prUrl });
231
+ await this._emitArmed(prUrl);
232
+ }
233
+
234
+ async _emitArmed(prUrl) {
235
+ try {
236
+ await this.bus.emit('epic.merge.armed', { prUrl });
237
+ } catch (err) {
238
+ this.logger.warn?.(
239
+ `[AutomergeArmer] epic.merge.armed emit failed (swallowed): ${err?.message ?? err}`,
240
+ );
241
+ }
242
+ }
243
+
244
+ reset() {
245
+ this._seen.clear();
246
+ this.classifications = [];
247
+ }
248
+ }