mandrel 1.94.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. package/.agents/README.md +116 -99
  2. package/.agents/agents/acceptance-critic.md +9 -7
  3. package/.agents/agents/story-worker.md +45 -51
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +498 -1287
  6. package/.agents/docs/agentrc-reference.json +185 -80
  7. package/.agents/docs/configuration.md +132 -190
  8. package/.agents/docs/execution-reference.md +51 -25
  9. package/.agents/docs/quality-gates.md +25 -33
  10. package/.agents/docs/workflows.md +8 -8
  11. package/.agents/instructions.md +113 -139
  12. package/.agents/rules/ci-remediation.md +11 -15
  13. package/.agents/rules/git-conventions-reference.md +48 -58
  14. package/.agents/rules/git-conventions.md +16 -22
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  16. package/.agents/schemas/agentrc.schema.json +83 -254
  17. package/.agents/schemas/audit-rules.json +59 -1
  18. package/.agents/schemas/audit-rules.schema.json +33 -1
  19. package/.agents/schemas/lifecycle/README.md +1 -2
  20. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  21. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  22. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  23. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  24. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  25. package/.agents/schemas/signal-event.schema.json +3 -3
  26. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  27. package/.agents/schemas/validation-evidence.schema.json +1 -1
  28. package/.agents/scripts/acceptance-eval.js +22 -66
  29. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  30. package/.agents/scripts/audit-to-stories.js +7 -7
  31. package/.agents/scripts/boot-sweep.js +1 -1
  32. package/.agents/scripts/bootstrap.js +3 -3
  33. package/.agents/scripts/check-dead-exports.js +43 -104
  34. package/.agents/scripts/check-doc-links.js +2 -2
  35. package/.agents/scripts/check-lifecycle-lint.js +7 -10
  36. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  37. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  38. package/.agents/scripts/deliver-recover.js +122 -0
  39. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  40. package/.agents/scripts/evidence-gate.js +20 -50
  41. package/.agents/scripts/generate-skills-index.js +17 -1
  42. package/.agents/scripts/generate-workflows-doc.js +4 -4
  43. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  44. package/.agents/scripts/lib/Logger.js +6 -10
  45. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  46. package/.agents/scripts/lib/audit-suite/selector.js +328 -28
  47. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  48. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  49. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
  50. package/.agents/scripts/lib/baselines/reader.js +1 -6
  51. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  52. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  53. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  54. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  55. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  56. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  57. package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
  58. package/.agents/scripts/lib/checks/index.js +3 -2
  59. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  60. package/.agents/scripts/lib/checks/state.js +17 -248
  61. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
  62. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  63. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  64. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  65. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  66. package/.agents/scripts/lib/cli-args.js +39 -9
  67. package/.agents/scripts/lib/close-validation/gates.js +15 -15
  68. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  69. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  70. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  71. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  72. package/.agents/scripts/lib/config/ci.js +6 -31
  73. package/.agents/scripts/lib/config/delivery-routing.js +52 -35
  74. package/.agents/scripts/lib/config/explain.js +61 -48
  75. package/.agents/scripts/lib/config/github.js +7 -5
  76. package/.agents/scripts/lib/config/limits.js +29 -80
  77. package/.agents/scripts/lib/config/paths.js +0 -2
  78. package/.agents/scripts/lib/config/quality.js +12 -15
  79. package/.agents/scripts/lib/config/runners.js +20 -66
  80. package/.agents/scripts/lib/config/temp-paths.js +30 -63
  81. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  82. package/.agents/scripts/lib/config-resolver.js +2 -7
  83. package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
  84. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
  85. package/.agents/scripts/lib/config-settings-schema.js +100 -60
  86. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  87. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  88. package/.agents/scripts/lib/dependency-parser.js +3 -2
  89. package/.agents/scripts/lib/doc-tiers.js +2 -2
  90. package/.agents/scripts/lib/duplicate-search.js +242 -41
  91. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  93. package/.agents/scripts/lib/format-generated-json.js +97 -0
  94. package/.agents/scripts/lib/framework-version.js +19 -190
  95. package/.agents/scripts/lib/gh-exec.js +8 -0
  96. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  97. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
  98. package/.agents/scripts/lib/git-utils.js +32 -20
  99. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  100. package/.agents/scripts/lib/json-utils.js +1 -2
  101. package/.agents/scripts/lib/label-constants.js +10 -38
  102. package/.agents/scripts/lib/label-taxonomy.js +10 -55
  103. package/.agents/scripts/lib/observability/active-story-env.js +44 -165
  104. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  105. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  106. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  107. package/.agents/scripts/lib/observability/source-classifier.js +5 -5
  108. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  109. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  110. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  111. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  112. package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
  113. package/.agents/scripts/lib/orchestration/code-review.js +78 -436
  114. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  115. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
  116. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  117. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  118. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  119. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  120. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  121. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  122. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  123. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  124. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  125. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
  126. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  127. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  128. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  129. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
  130. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  131. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  132. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  133. package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
  134. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  135. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  136. package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
  137. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
  138. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
  139. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  140. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  141. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
  142. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
  143. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  144. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
  145. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
  146. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
  147. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  148. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  149. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  150. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
  151. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  152. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
  153. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  154. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  155. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  156. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  157. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  158. package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
  159. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  160. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  161. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  162. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  163. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  164. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  165. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  166. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  167. package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  170. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  171. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
  172. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  173. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
  174. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  175. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  176. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
  177. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  178. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  179. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
  180. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  181. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  182. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  183. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  184. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  185. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  186. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  187. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
  188. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  189. package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
  190. package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
  191. package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
  192. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  193. package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
  194. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  195. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
  196. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
  197. package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
  198. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
  199. package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
  200. package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
  201. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  202. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  203. package/.agents/scripts/lib/planning-corpus.js +12 -281
  204. package/.agents/scripts/lib/preflight-runner.js +4 -4
  205. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  206. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  207. package/.agents/scripts/lib/signals/index.js +4 -17
  208. package/.agents/scripts/lib/signals/read.js +35 -35
  209. package/.agents/scripts/lib/signals/schema.js +8 -11
  210. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  211. package/.agents/scripts/lib/signals/write.js +0 -1
  212. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  213. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  214. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  215. package/.agents/scripts/lib/story-adjacency.js +17 -19
  216. package/.agents/scripts/lib/story-body/story-body.js +130 -75
  217. package/.agents/scripts/lib/story-plan.js +2 -4
  218. package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
  219. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  220. package/.agents/scripts/lib/test-env.js +14 -1
  221. package/.agents/scripts/lib/test-tiers.js +0 -3
  222. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
  223. package/.agents/scripts/lib/validation-evidence.js +32 -60
  224. package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
  225. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  226. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
  228. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  229. package/.agents/scripts/lint-issue-body.js +71 -40
  230. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  231. package/.agents/scripts/notify.js +4 -3
  232. package/.agents/scripts/plan-context.js +102 -80
  233. package/.agents/scripts/plan-persist.js +230 -279
  234. package/.agents/scripts/plan-run-epilogue.js +142 -0
  235. package/.agents/scripts/post-structured-comment.js +0 -38
  236. package/.agents/scripts/pr-watch-with-update.js +43 -22
  237. package/.agents/scripts/providers/github/compose.js +0 -1
  238. package/.agents/scripts/providers/github/errors.js +0 -19
  239. package/.agents/scripts/providers/github/issues.js +13 -39
  240. package/.agents/scripts/providers/github/mappers.js +5 -12
  241. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  242. package/.agents/scripts/providers/github/tickets.js +33 -156
  243. package/.agents/scripts/providers/github.js +17 -6
  244. package/.agents/scripts/resolve-stories.js +236 -0
  245. package/.agents/scripts/run-coverage.js +4 -1
  246. package/.agents/scripts/run-lint.js +2 -2
  247. package/.agents/scripts/run-verify.js +31 -2
  248. package/.agents/scripts/signals-view.js +25 -21
  249. package/.agents/scripts/single-story-close.js +178 -26
  250. package/.agents/scripts/single-story-confirm-merge.js +313 -24
  251. package/.agents/scripts/single-story-init.js +35 -30
  252. package/.agents/scripts/stories-wave-tick.js +85 -10
  253. package/.agents/scripts/story-plan.js +28 -49
  254. package/.agents/scripts/update-ticket-state.js +14 -65
  255. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  256. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  257. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  258. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  259. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  260. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  261. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  262. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  263. package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
  264. package/.agents/skills/core/scope-triage/SKILL.md +31 -172
  265. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  266. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  267. package/.agents/skills/skills.index.json +3 -53
  268. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  269. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  270. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  271. package/.agents/starter-agentrc.json +0 -5
  272. package/.agents/templates/agent-protocol.md +9 -10
  273. package/.agents/workflows/audit-architecture.md +6 -7
  274. package/.agents/workflows/audit-clean-code.md +7 -7
  275. package/.agents/workflows/audit-dependencies.md +3 -3
  276. package/.agents/workflows/audit-devops.md +3 -3
  277. package/.agents/workflows/audit-documentation.md +9 -10
  278. package/.agents/workflows/audit-lighthouse.md +11 -3
  279. package/.agents/workflows/audit-navigability.md +13 -2
  280. package/.agents/workflows/audit-performance.md +5 -6
  281. package/.agents/workflows/audit-privacy.md +3 -3
  282. package/.agents/workflows/audit-quality.md +11 -12
  283. package/.agents/workflows/audit-security.md +4 -5
  284. package/.agents/workflows/audit-seo.md +13 -3
  285. package/.agents/workflows/audit-sre.md +3 -3
  286. package/.agents/workflows/audit-to-stories.md +20 -20
  287. package/.agents/workflows/audit-ux-ui.md +10 -3
  288. package/.agents/workflows/deliver.md +177 -176
  289. package/.agents/workflows/git-cleanup.md +5 -6
  290. package/.agents/workflows/git-deliver.md +1 -1
  291. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  292. package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
  293. package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
  294. package/.agents/workflows/helpers/code-review.md +75 -196
  295. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
  296. package/.agents/workflows/helpers/deliver-story.md +606 -0
  297. package/.agents/workflows/helpers/diagnose.md +10 -10
  298. package/.agents/workflows/helpers/parallel-tooling.md +3 -3
  299. package/.agents/workflows/helpers/signals.md +16 -16
  300. package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
  301. package/.agents/workflows/mandrel-update.md +2 -1
  302. package/.agents/workflows/plan.md +277 -145
  303. package/.agents/workflows/qa-assist.md +27 -33
  304. package/.agents/workflows/qa-explore.md +29 -38
  305. package/.agents/workflows/qa-run.md +2 -6
  306. package/README.md +9 -8
  307. package/bin/mandrel.js +12 -1
  308. package/docs/CHANGELOG.md +70 -0
  309. package/lib/cli/registry.js +262 -19
  310. package/lib/cli/sync-agents.js +157 -0
  311. package/lib/cli/sync-commands.js +115 -6
  312. package/lib/cli/sync.js +168 -6
  313. package/lib/cli/update.js +105 -8
  314. package/lib/cli/version-helpers.js +131 -0
  315. package/lib/migrations/README.md +7 -5
  316. package/lib/migrations/index.js +12 -8
  317. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  318. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  319. package/package.json +2 -2
  320. package/.agents/agents/retro.md +0 -42
  321. package/.agents/personas/architect.md +0 -113
  322. package/.agents/personas/devops-engineer.md +0 -38
  323. package/.agents/personas/engineer.md +0 -33
  324. package/.agents/personas/project-manager.md +0 -114
  325. package/.agents/personas/qa-engineer.md +0 -95
  326. package/.agents/personas/security-engineer.md +0 -111
  327. package/.agents/personas/technical-writer.md +0 -101
  328. package/.agents/schemas/dispatch-manifest.json +0 -232
  329. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  330. package/.agents/schemas/epic-spec.schema.json +0 -153
  331. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  332. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  333. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  334. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  335. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  336. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  337. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  338. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  339. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  340. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  341. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  342. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  343. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  344. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  345. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  346. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  347. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  348. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  349. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  350. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  351. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  352. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  353. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  354. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  355. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  356. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  357. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  358. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  359. package/.agents/schemas/risk-verdict.schema.json +0 -66
  360. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  361. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  362. package/.agents/scripts/analyze-execution.js +0 -444
  363. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  364. package/.agents/scripts/check-prepush-recovery.js +0 -90
  365. package/.agents/scripts/dispatcher.js +0 -295
  366. package/.agents/scripts/epic-audit-prepare.js +0 -497
  367. package/.agents/scripts/epic-audit-recheck.js +0 -274
  368. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  369. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  370. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  371. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  372. package/.agents/scripts/epic-plan-clarity.js +0 -211
  373. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  374. package/.agents/scripts/epic-reconcile.js +0 -625
  375. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  376. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  377. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  378. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  379. package/.agents/scripts/lib/config/preflight.js +0 -58
  380. package/.agents/scripts/lib/config/retro.js +0 -77
  381. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  382. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  383. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  384. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  385. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  386. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
  387. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  388. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  389. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  390. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
  391. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  392. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  393. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  394. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  395. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  396. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  397. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  398. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  399. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  400. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  401. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  402. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  403. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  404. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  405. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  406. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  407. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  408. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
  409. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  410. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  411. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  412. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  413. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  414. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  415. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  416. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  417. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  418. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  419. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  420. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  421. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  422. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  423. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  424. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  425. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  426. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
  427. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  428. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  429. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  430. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  431. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  432. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  433. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  434. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  435. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  436. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  437. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  438. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  439. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  440. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  441. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  442. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  443. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  444. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  445. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  446. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  447. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  448. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  449. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  450. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  451. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  452. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  453. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  454. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  455. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  456. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  457. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  458. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  459. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  460. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  461. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
  462. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  463. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  464. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  465. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
  466. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  467. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  468. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  469. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  470. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  471. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  472. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  473. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  474. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  475. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  476. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  477. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  478. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  479. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  480. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  481. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  482. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  483. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  484. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  485. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  486. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  487. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  488. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  489. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  490. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  491. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  492. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  493. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  494. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  495. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  496. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  497. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  498. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  499. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  500. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  501. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  502. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  503. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  504. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  505. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  506. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  507. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  508. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  509. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  510. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  511. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  512. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  513. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  514. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  515. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  516. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  517. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  518. package/.agents/scripts/lib/spec/index.js +0 -36
  519. package/.agents/scripts/lib/spec/loader.js +0 -425
  520. package/.agents/scripts/lib/spec/state.js +0 -208
  521. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  522. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  523. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  524. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  525. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  526. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  527. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  528. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  529. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  530. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  531. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  532. package/.agents/scripts/lifecycle-emit.js +0 -510
  533. package/.agents/scripts/retro-run.js +0 -218
  534. package/.agents/scripts/slice-phase.js +0 -361
  535. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  536. package/.agents/scripts/story-close.js +0 -294
  537. package/.agents/scripts/story-init.js +0 -599
  538. package/.agents/scripts/story-phase.js +0 -369
  539. package/.agents/scripts/wave-tick.js +0 -464
  540. package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
  541. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  542. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  543. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  544. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  545. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  546. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  547. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  548. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  549. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  550. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  551. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  552. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  553. package/.agents/workflows/helpers/epic-audit.md +0 -189
  554. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  555. package/.agents/workflows/helpers/epic-testing.md +0 -125
  556. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  557. package/.agents/workflows/helpers/plan-epic.md +0 -353
  558. package/.agents/workflows/helpers/plan-story.md +0 -251
  559. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  560. package/.agents/workflows/helpers/single-story-deliver.md +0 -557
@@ -1,444 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * analyze-execution.js — single writer of the structured perf-summary
5
- * comments (Epic #1030 / Story #1123).
6
- *
7
- * Reads NDJSON from `temp/epic-<eid>/stories/story-<sid>/signals.ndjson` and
8
- * upserts one of two structured comments:
9
- *
10
- * - `--story <sid> --epic <eid>` (Story mode): posts
11
- * `<!-- structured:story-perf-summary -->` on the Story ticket. The
12
- * payload combines the Story's NDJSON signals with the timing
13
- * summary written by `post-merge-close.js` to
14
- * `temp/epic-<eid>/stories/story-<sid>/phase-timings.json` (path overridable
15
- * via `--phase-timings <path>`).
16
- *
17
- * - `--epic <eid>` (Epic mode): rolls up every Story under the Epic by
18
- * fetching each `story-perf-summary` structured comment from the
19
- * ticketing provider. Posts the
20
- * `<!-- structured:epic-perf-report -->` comment on the Epic ticket.
21
- * Run from the retro composer / `/deliver` Phase 6.0.
22
- *
23
- * Both modes are idempotent: `upsertStructuredComment` deletes the prior
24
- * marker before posting the new one.
25
- *
26
- * Exit code is `0` on success, `0` on tolerated soft failures (missing
27
- * NDJSON for a Story, no children for an Epic) so the close pipelines
28
- * never block on observability output. Hard failures (bad CLI args,
29
- * provider error, schema-violating payload) exit non-zero — the call
30
- * sites in post-merge-pipeline / `/deliver` Phase 5 treat that
31
- * as a non-fatal warning.
32
- *
33
- * This file is a thin CLI: it wires the I/O readers from
34
- * `lib/observability/perf-report-readers.js` to the pure renderers in
35
- * `lib/observability/perf-report-render.js` inside `runStoryMode` /
36
- * `runEpicMode`, then parses argv and dispatches. The report-formatting
37
- * and signal-reading logic live in those two modules so report formatting
38
- * is unit-testable without fixtures (Story #3350).
39
- *
40
- * Usage:
41
- * node .agents/scripts/analyze-execution.js --story <sid> --epic <eid> \
42
- * [--phase-timings <path>]
43
- * node .agents/scripts/analyze-execution.js --epic <eid>
44
- * node .agents/scripts/analyze-execution.js --epic <eid> --plan-metrics-json
45
- *
46
- * `--plan-metrics-json` (Epic #4474 PR7 — the G2 extraction surface) is a
47
- * **local read-only** mode: it reads the per-Epic plan-metrics ledger
48
- * (`temp/epic-<eid>/plan-metrics.json`), rolls it up with
49
- * `summarizePlanMetrics`, and prints one compact JSON envelope
50
- * `{ epicId, planMetrics, summaryLine }` to stdout — no provider call, no
51
- * comment write, all logs on stderr — so a bench cohort can extract
52
- * turns-per-plan / per-mode invocation counts / critic skips without
53
- * scraping GitHub or the human log.
54
- *
55
- * @see docs/data-dictionary.md §StoryPerfSummary, §EpicPerfReport
56
- */
57
-
58
- import fs from 'node:fs/promises';
59
- import path from 'node:path';
60
- import { parseArgs } from 'node:util';
61
- import { runAsCli } from './lib/cli-utils.js';
62
- import { signalsFile } from './lib/config/temp-paths.js';
63
- import { PROJECT_ROOT, resolveConfig } from './lib/config-resolver.js';
64
- import { Logger, routeAllOutputToStderr } from './lib/Logger.js';
65
- import { computeBaselineRefreshRate } from './lib/observability/baseline-refresh-rate.js';
66
- import {
67
- computeEpicPerfReport,
68
- computeStoryPerfSummary,
69
- } from './lib/observability/perf-aggregator.js';
70
- import {
71
- aggregateBaselineFrictionFromSignals,
72
- collectStorySummaries,
73
- gatherEpicCommitsFromGit,
74
- readEpicLifecycleEvents,
75
- readGhSpawnCount,
76
- readPhaseTimings,
77
- readStorySignals,
78
- } from './lib/observability/perf-report-readers.js';
79
- import {
80
- EPIC_PERF_TYPE,
81
- renderEpicBody,
82
- renderStoryBody,
83
- STORY_PERF_TYPE,
84
- } from './lib/observability/perf-report-render.js';
85
- import {
86
- readPlanMetrics,
87
- renderPlanMetricsSummaryLine,
88
- summarizePlanMetrics,
89
- } from './lib/orchestration/plan-metrics.js';
90
- import { upsertStructuredComment } from './lib/orchestration/ticketing.js';
91
- import { createProvider } from './lib/provider-factory.js';
92
-
93
- // Re-exported so existing importers (tests, retro composer) keep a stable
94
- // entry point after the read/render split (Story #3350).
95
- export { extractStoryPerfSummaryFromComment } from './lib/observability/perf-report-render.js';
96
-
97
- /**
98
- * Resolve the wave-execution concurrency cap from the resolved config
99
- * (`delivery.deliverRunner.concurrencyCap`), falling back to the
100
- * dispatcher's safe default of 2. Story #3025 / Task #3030.
101
- */
102
- function resolveConcurrencyCap(config) {
103
- const cap = config?.delivery?.deliverRunner?.concurrencyCap;
104
- return Number.isInteger(cap) && cap >= 1 ? cap : 2;
105
- }
106
-
107
- /**
108
- * Resolve the verify-results concurrency cap from the resolved config
109
- * (`delivery.deliverRunner.verifyConcurrencyCap`), falling back to 4.
110
- * Story #3025 / Task #3030.
111
- */
112
- function resolveVerifyConcurrencyCap(config) {
113
- const cap = config?.delivery?.deliverRunner?.verifyConcurrencyCap;
114
- return Number.isInteger(cap) && cap >= 1 ? cap : 4;
115
- }
116
-
117
- /**
118
- * Story mode: read NDJSON + phase-timings, build the payload, upsert.
119
- *
120
- * @param {{
121
- * storyId: number,
122
- * epicId: number,
123
- * phaseTimingsPath?: string|null,
124
- * provider: object,
125
- * config: object,
126
- * logger?: object,
127
- * now?: () => Date,
128
- * }} ctx
129
- * @returns {Promise<{ commentId: number, payload: object }>}
130
- */
131
- export async function runStoryMode(ctx) {
132
- const { storyId, epicId, provider, config } = ctx;
133
- const logger = ctx.logger ?? Logger;
134
- const now = ctx.now ?? (() => new Date());
135
-
136
- logger.info?.(
137
- `[analyze-execution] story-mode story=#${storyId} epic=#${epicId}`,
138
- );
139
-
140
- const events = await readStorySignals(epicId, storyId, config);
141
- const phaseTiming = await readPhaseTimings(
142
- epicId,
143
- storyId,
144
- config,
145
- ctx.phaseTimingsPath ?? null,
146
- );
147
- const ghSpawnCount = await readGhSpawnCount(epicId, storyId, config);
148
-
149
- const payload = computeStoryPerfSummary(events, {
150
- storyId,
151
- epicId,
152
- closedAt: now().toISOString(),
153
- phaseTiming,
154
- });
155
- if (ghSpawnCount !== null) {
156
- // Throw-away measurement field (Story #1795). Surfaces the in-process
157
- // `gh-exec.getSpawnCount()` snapshot captured at the end of close
158
- // validation so the Story-close structured comment can be diffed
159
- // against the baseline recorded under `temp/epic-1788/` for the
160
- // "≥100 fewer spawns" acceptance criterion.
161
- payload.ghSpawnCount = ghSpawnCount;
162
- }
163
-
164
- const body = renderStoryBody(payload);
165
- const result = await upsertStructuredComment(
166
- provider,
167
- storyId,
168
- STORY_PERF_TYPE,
169
- body,
170
- );
171
- logger.info?.(
172
- `[analyze-execution] story-perf-summary upserted on Story #${storyId} (commentId=${result.commentId})`,
173
- );
174
- return { commentId: result.commentId, payload };
175
- }
176
-
177
- /**
178
- * Epic mode: collect every Story's perf summary, roll them up, upsert
179
- * the epic-perf-report comment.
180
- *
181
- * @param {{
182
- * epicId: number,
183
- * provider: object,
184
- * config?: object,
185
- * cwd?: string,
186
- * windowDays?: number,
187
- * logger?: object,
188
- * now?: () => Date,
189
- * collectSummariesFn?: typeof collectStorySummaries,
190
- * gatherEpicCommitsFn?: typeof gatherEpicCommitsFromGit,
191
- * aggregateFrictionFn?: typeof aggregateBaselineFrictionFromSignals,
192
- * }} ctx
193
- * @returns {Promise<{ commentId: number, payload: object, baselineRefreshRate: object | null, qualityGateFriction: object | null }>}
194
- */
195
- export async function runEpicMode(ctx) {
196
- const { epicId, provider } = ctx;
197
- const logger = ctx.logger ?? Logger;
198
- const now = ctx.now ?? (() => new Date());
199
- const windowDays =
200
- Number.isFinite(ctx.windowDays) && ctx.windowDays > 0
201
- ? Math.floor(ctx.windowDays)
202
- : 28;
203
- const collectFn = ctx.collectSummariesFn ?? collectStorySummaries;
204
- const gatherCommitsFn = ctx.gatherEpicCommitsFn ?? gatherEpicCommitsFromGit;
205
- const aggregateFrictionFn =
206
- ctx.aggregateFrictionFn ?? aggregateBaselineFrictionFromSignals;
207
-
208
- logger.info?.(`[analyze-execution] epic-mode epic=#${epicId}`);
209
-
210
- const summaries = await collectFn(provider, epicId, logger);
211
-
212
- // Story #3025 / Task #3030 — forward lifecycle events to the
213
- // aggregator so the report's `waveParallelism` array is populated
214
- // (the analyzer used to omit the field, leaving the report at `[]`).
215
- const readLifecycleEventsFn =
216
- ctx.readLifecycleEventsFn ?? readEpicLifecycleEvents;
217
- const lifecycleEvents = ctx.config
218
- ? await readLifecycleEventsFn(epicId, ctx.config, logger)
219
- : [];
220
- const concurrencyCap = resolveConcurrencyCap(ctx.config);
221
- const verifyConcurrencyCap = resolveVerifyConcurrencyCap(ctx.config);
222
-
223
- // Only forward `events` when we actually have something — passing an
224
- // empty array suppresses the friction-from-summaries fallback in
225
- // `computeEpicPerfReport.buildSignalCounts`, which would zero the
226
- // counts for callers that have summaries but no lifecycle stream
227
- // (e.g. legacy/test paths without a `config`).
228
- const reportOpts = {
229
- epicId,
230
- generatedAt: now().toISOString(),
231
- concurrencyCap,
232
- verifyConcurrencyCap,
233
- };
234
- if (lifecycleEvents.length > 0) {
235
- reportOpts.events = lifecycleEvents;
236
- }
237
-
238
- const payload = computeEpicPerfReport(summaries, reportOpts);
239
-
240
- // Story #1400 / Task #1427 — baseline-refresh-rate row. Pure reporter
241
- // operates on a fixture of git-log records gathered by the injected
242
- // `gatherEpicCommitsFn`. A spawn failure surfaces as `[]` and degrades
243
- // to the "no Story merges in window" line in the rendered body.
244
- let baselineRefreshRate = null;
245
- try {
246
- const commits = await gatherCommitsFn({
247
- epicId,
248
- windowDays,
249
- cwd: ctx.cwd ?? process.cwd(),
250
- logger,
251
- });
252
- baselineRefreshRate = computeBaselineRefreshRate(commits, {
253
- windowDays,
254
- now,
255
- });
256
- } catch (err) {
257
- logger.warn?.(
258
- `[analyze-execution] baseline-refresh-rate gather failed (non-fatal): ${
259
- err instanceof Error ? err.message : String(err)
260
- }`,
261
- );
262
- }
263
-
264
- // Story #1400 / Task #1429 — Quality gate friction block. Aggregates
265
- // `baseline-refresh-regression` records from the existing
266
- // signals.ndjson stream (no new file format).
267
- let qualityGateFriction = null;
268
- if (ctx.config) {
269
- try {
270
- const storyIds = (summaries ?? [])
271
- .map((s) => s?.storyId)
272
- .filter((n) => Number.isInteger(n) && n > 0);
273
- qualityGateFriction = await aggregateFrictionFn({
274
- epicId,
275
- storyIds,
276
- config: ctx.config,
277
- windowDays,
278
- now,
279
- });
280
- } catch (err) {
281
- logger.warn?.(
282
- `[analyze-execution] quality-gate-friction aggregate failed (non-fatal): ${
283
- err instanceof Error ? err.message : String(err)
284
- }`,
285
- );
286
- }
287
- }
288
-
289
- const body = renderEpicBody(payload, {
290
- baselineRefreshRate,
291
- qualityGateFriction,
292
- });
293
- const result = await upsertStructuredComment(
294
- provider,
295
- epicId,
296
- EPIC_PERF_TYPE,
297
- body,
298
- );
299
- logger.info?.(
300
- `[analyze-execution] epic-perf-report upserted on Epic #${epicId} (commentId=${result.commentId}, stories=${summaries.length})`,
301
- );
302
-
303
- // Plan-metrics roll-up (#4474 PR1) — surface the plan-CLI invocation
304
- // ledger (`temp/epic-<id>/plan-metrics.json`) alongside the perf report.
305
- // Additive and non-fatal: a missing or unreadable ledger yields `null`.
306
- let planMetrics = null;
307
- try {
308
- planMetrics = summarizePlanMetrics(
309
- await readPlanMetrics(epicId, ctx.config),
310
- );
311
- if (planMetrics) {
312
- logger.info?.(
313
- `[analyze-execution] ${renderPlanMetricsSummaryLine(planMetrics)}`,
314
- );
315
- }
316
- } catch (err) {
317
- logger.warn?.(
318
- `[analyze-execution] plan-metrics read failed (non-fatal): ${
319
- err instanceof Error ? err.message : String(err)
320
- }`,
321
- );
322
- }
323
-
324
- return {
325
- commentId: result.commentId,
326
- payload,
327
- baselineRefreshRate,
328
- qualityGateFriction,
329
- planMetrics,
330
- };
331
- }
332
-
333
- function parseCli(argv) {
334
- const { values } = parseArgs({
335
- args: argv,
336
- options: {
337
- story: { type: 'string' },
338
- epic: { type: 'string' },
339
- 'phase-timings': { type: 'string' },
340
- 'window-days': { type: 'string' },
341
- 'plan-metrics-json': { type: 'boolean', default: false },
342
- cwd: { type: 'string' },
343
- },
344
- strict: false,
345
- });
346
- const story = values.story != null ? Number.parseInt(values.story, 10) : null;
347
- const epic = values.epic != null ? Number.parseInt(values.epic, 10) : null;
348
- const windowDays =
349
- values['window-days'] != null
350
- ? Number.parseInt(values['window-days'], 10)
351
- : null;
352
- return {
353
- storyId: Number.isInteger(story) && story > 0 ? story : null,
354
- epicId: Number.isInteger(epic) && epic > 0 ? epic : null,
355
- phaseTimingsPath: values['phase-timings'] ?? null,
356
- windowDays:
357
- Number.isInteger(windowDays) && windowDays > 0 ? windowDays : null,
358
- planMetricsJson: values['plan-metrics-json'] === true,
359
- cwd: values.cwd ?? null,
360
- };
361
- }
362
-
363
- /**
364
- * `--plan-metrics-json` — local, read-only G2 extraction surface (Epic
365
- * #4474 PR7). Reads the per-Epic plan-metrics ledger and prints one
366
- * compact JSON envelope to stdout. No provider, no comment write; stdout
367
- * is reserved for the envelope (all logs on stderr). A missing ledger is
368
- * not an error — it yields `planMetrics: null` so a cohort script can
369
- * branch on the field instead of the exit code.
370
- *
371
- * @param {{ epicId: number, config: object }} input
372
- * @returns {Promise<{ epicId: number, planMetrics: object|null, summaryLine: string }>}
373
- */
374
- export async function runPlanMetricsJsonMode({ epicId, config }) {
375
- const planMetrics = summarizePlanMetrics(
376
- await readPlanMetrics(epicId, config),
377
- );
378
- return {
379
- epicId,
380
- planMetrics,
381
- summaryLine: renderPlanMetricsSummaryLine(planMetrics),
382
- };
383
- }
384
-
385
- async function main(argv = process.argv.slice(2)) {
386
- const args = parseCli(argv);
387
-
388
- if (!args.epicId) {
389
- throw new Error(
390
- 'Usage: analyze-execution.js --epic <eid> [--story <sid>] [--phase-timings <path>]',
391
- );
392
- }
393
-
394
- const cwd = path.resolve(args.cwd ?? PROJECT_ROOT);
395
- const config = resolveConfig({ cwd });
396
-
397
- if (args.planMetricsJson) {
398
- // Stdout is reserved for the compact envelope — flip every log sink to
399
- // stderr before any pipeline code runs (Story #2278 discipline).
400
- routeAllOutputToStderr();
401
- const result = await runPlanMetricsJsonMode({
402
- epicId: args.epicId,
403
- config,
404
- });
405
- process.stdout.write(`${JSON.stringify(result)}\n`);
406
- return;
407
- }
408
-
409
- const provider = createProvider(config);
410
-
411
- if (args.storyId) {
412
- // Existence guard: surface a clear log when the Story has no signals
413
- // yet, but still post the comment with empty arrays so the marker
414
- // exists for idempotence checks downstream.
415
- const sigPath = signalsFile(args.epicId, args.storyId, config);
416
- try {
417
- await fs.access(sigPath);
418
- } catch {
419
- Logger.info?.(
420
- `[analyze-execution] no signals.ndjson at ${sigPath} — posting empty story-perf-summary`,
421
- );
422
- }
423
- const result = await runStoryMode({
424
- storyId: args.storyId,
425
- epicId: args.epicId,
426
- phaseTimingsPath: args.phaseTimingsPath,
427
- provider,
428
- config,
429
- });
430
- process.stdout.write(`${JSON.stringify(result)}\n`);
431
- return;
432
- }
433
-
434
- const result = await runEpicMode({
435
- epicId: args.epicId,
436
- provider,
437
- config,
438
- cwd,
439
- windowDays: args.windowDays ?? undefined,
440
- });
441
- process.stdout.write(`${JSON.stringify(result)}\n`);
442
- }
443
-
444
- runAsCli(import.meta.url, main, { source: 'analyze-execution' });
@@ -1,117 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * bookkeeping-reconcile.js — Epic #4476 (M5).
5
- *
6
- * Drain the per-Epic bookkeeping outbox (buffered structured-comment upserts
7
- * and `agent::*` label flips accumulated during an unattended run) to GitHub,
8
- * once, at finalize. GitHub becomes the source of truth at rest; the outbox is
9
- * cleared only when the whole batch lands (crash-recovery: a partial drain
10
- * leaves the remainder for the next reconcile).
11
- *
12
- * The `/deliver` Phase 7 finalize step calls this once after the merge tail
13
- * opens the PR. It is idempotent: an empty / already-drained outbox is a
14
- * no-op, and both sink operations converge on a re-run.
15
- *
16
- * Usage:
17
- * node .agents/scripts/bookkeeping-reconcile.js --epic <id> [--provider github]
18
- *
19
- * Stdout: a single JSON envelope
20
- * { ok, epicId, drained, comments, labels, errors, cleared }
21
- *
22
- * Exit codes:
23
- * 0 — every buffered op drained (or nothing was buffered)
24
- * 1 — one or more ops failed (outbox retained for the next reconcile)
25
- * 2 — usage error
26
- */
27
-
28
- import { parseArgs } from 'node:util';
29
-
30
- import { runAsCli } from './lib/cli-utils.js';
31
- import { resolveConfig } from './lib/config-resolver.js';
32
- import { Logger } from './lib/Logger.js';
33
- import {
34
- outboxPathFor,
35
- reconcileOutbox,
36
- } from './lib/orchestration/bookkeeping-outbox.js';
37
- import { createProvider } from './lib/provider-factory.js';
38
-
39
- const HELP = `Usage: node .agents/scripts/bookkeeping-reconcile.js \\
40
- --epic <id> [--provider github]
41
-
42
- Drains temp/epic-<id>/bookkeeping-outbox.ndjson (buffered comment upserts +
43
- label flips from an unattended run) to GitHub once, at finalize. Idempotent.
44
-
45
- Flags:
46
- --epic Epic id whose outbox to drain (required).
47
- --provider Provider name (default: inferred from .agentrc.json github block).
48
- --help Show this message.
49
- `;
50
-
51
- /**
52
- * Core: resolve the outbox path and drain it. Exported so tests can drive it
53
- * with a fake provider and an injected outbox path.
54
- *
55
- * @param {{ epicId: number, provider: object, config?: object,
56
- * outboxPath?: string, logger?: object }} args
57
- * @returns {Promise<object>}
58
- */
59
- export async function runBookkeepingReconcile({
60
- epicId,
61
- provider,
62
- config,
63
- outboxPath,
64
- logger = Logger,
65
- }) {
66
- const resolvedOutbox = outboxPath ?? outboxPathFor(epicId, config);
67
- const result = await reconcileOutbox({
68
- outboxPath: resolvedOutbox,
69
- provider,
70
- logger,
71
- });
72
- return { ok: result.errors.length === 0, epicId, ...result };
73
- }
74
-
75
- export function parseArgv(argv) {
76
- const { values } = parseArgs({
77
- args: argv,
78
- options: {
79
- epic: { type: 'string' },
80
- provider: { type: 'string' },
81
- help: { type: 'boolean' },
82
- },
83
- strict: false,
84
- });
85
- return values;
86
- }
87
-
88
- export async function main(argv = process.argv.slice(2)) {
89
- const values = parseArgv(argv);
90
- if (values.help) {
91
- process.stdout.write(HELP);
92
- return;
93
- }
94
-
95
- const epicId = Number.parseInt(values.epic ?? '', 10);
96
- if (!Number.isInteger(epicId) || epicId <= 0) {
97
- process.stderr.write('[bookkeeping-reconcile] --epic <id> is required.\n');
98
- process.stderr.write(HELP);
99
- process.exit(2);
100
- }
101
-
102
- const config = resolveConfig();
103
- const effectiveConfig = values.provider
104
- ? { ...config, provider: values.provider }
105
- : config;
106
- const provider = createProvider(effectiveConfig);
107
-
108
- const envelope = await runBookkeepingReconcile({
109
- epicId,
110
- provider,
111
- config,
112
- });
113
- process.stdout.write(`${JSON.stringify(envelope)}\n`);
114
- if (!envelope.ok) process.exitCode = 1;
115
- }
116
-
117
- runAsCli(import.meta.url, main, { source: 'bookkeeping-reconcile' });
@@ -1,90 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * check-prepush-recovery.js — gate decision for the pre-push coverage step.
4
- *
5
- * Story #3162. The pre-push hook normally runs `coverage-capture.js` +
6
- * `crap:check` on every push. During a `story-close.js` recovery (operator
7
- * pushing `epic/<id>` to unblock a run after a merge-orchestrator failure),
8
- * a pre-existing coverage regression on `epic/<id>` — unrelated to the
9
- * Story under recovery — hard-blocks the push and forces a `--no-verify`
10
- * bypass, which violates the global "no hook bypass" rule.
11
- *
12
- * This script is the scoped escape hatch. It exits 0 ("skip coverage gate")
13
- * only when BOTH conditions hold:
14
- *
15
- * 1. `STORY_CLOSE_RECOVERY=1` is set in the environment.
16
- * 2. At least one ref being pushed has a local ref of the shape
17
- * `refs/heads/epic/<id>` (parsed from the pre-push stdin protocol).
18
- *
19
- * Otherwise it exits 1 ("run coverage gate as today"). The narrow scope is
20
- * deliberate: a generic env-var bypass would erode the gate; tying the
21
- * skip to an epic-branch target keeps every other push honest.
22
- *
23
- * Stdin contract (git pre-push hook protocol): zero or more lines, each
24
- * `<local_ref> <local_sha> <remote_ref> <remote_sha>`
25
- * separated by whitespace. Empty stdin (no refs being pushed) yields exit 1.
26
- */
27
-
28
- import { runAsCli } from './lib/cli-utils.js';
29
-
30
- const EPIC_REF_PATTERN = /^refs\/heads\/epic\//;
31
- const SKIP_LOG = '[pre-push] coverage gate skipped by STORY_CLOSE_RECOVERY';
32
-
33
- /**
34
- * Parse pre-push stdin into the list of local refs being pushed. Lines with
35
- * fewer than four whitespace-separated tokens are tolerated (git in practice
36
- * always emits four, but defensive parsing keeps the helper robust against
37
- * empty pushes and trailing whitespace).
38
- *
39
- * @param {string} stdin
40
- * @returns {string[]} local ref names (first token of each non-empty line)
41
- */
42
- export function parsePrePushLocalRefs(stdin) {
43
- if (typeof stdin !== 'string' || stdin.length === 0) return [];
44
- return stdin
45
- .split(/\r?\n/)
46
- .map((line) => line.trim())
47
- .filter(Boolean)
48
- .map((line) => line.split(/\s+/)[0])
49
- .filter(Boolean);
50
- }
51
-
52
- /**
53
- * Pure decision function. `true` means "skip the coverage gate".
54
- *
55
- * @param {object} input
56
- * @param {string|undefined} input.env value of STORY_CLOSE_RECOVERY
57
- * @param {string[]} input.localRefs parsed local refs
58
- * @returns {boolean}
59
- */
60
- export function shouldSkipCoverageGate({ env, localRefs }) {
61
- if (env !== '1') return false;
62
- if (!Array.isArray(localRefs) || localRefs.length === 0) return false;
63
- return localRefs.some((ref) => EPIC_REF_PATTERN.test(ref));
64
- }
65
-
66
- async function readStdin() {
67
- if (process.stdin.isTTY) return '';
68
- let data = '';
69
- process.stdin.setEncoding('utf8');
70
- for await (const chunk of process.stdin) data += chunk;
71
- return data;
72
- }
73
-
74
- async function main() {
75
- const stdin = await readStdin();
76
- const localRefs = parsePrePushLocalRefs(stdin);
77
- const skip = shouldSkipCoverageGate({
78
- env: process.env.STORY_CLOSE_RECOVERY,
79
- localRefs,
80
- });
81
- if (skip) {
82
- process.stdout.write(`${SKIP_LOG}\n`);
83
- process.exit(0);
84
- }
85
- process.exit(1);
86
- }
87
-
88
- runAsCli(import.meta.url, main);
89
-
90
- export const __testing = { EPIC_REF_PATTERN, SKIP_LOG };