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,464 +0,0 @@
1
- #!/usr/bin/env node
2
- /* node:coverage ignore file */
3
-
4
- /**
5
- * wave-tick.js — thin CLI shim around `lib/wave-runner/tick.js`.
6
- *
7
- * Reads the `epic-run-state` checkpoint plus fresh Story labels and
8
- * prints one `WaveTickResult` envelope. The slash-command operator
9
- * (`/deliver`) consumes the envelope to decide whether to dispatch
10
- * the next wave, observe in-flight stories, or finalize the Epic.
11
- *
12
- * Usage:
13
- * node .agents/scripts/wave-tick.js --epic <epicId> [--check-idle <minutes>]
14
- *
15
- * The tick is stateless — "loop until terminal" is the caller's job
16
- * (today: the markdown's wave loop).
17
- *
18
- * Output: one JSON object on stdout. Schema in `lib/wave-runner/tick.js`.
19
- */
20
-
21
- import { execFileSync } from 'node:child_process';
22
- import { existsSync, readFileSync } from 'node:fs';
23
- import { parseArgs } from 'node:util';
24
-
25
- import { runAsCli } from './lib/cli-utils.js';
26
- import { epicLedgerPath } from './lib/config/temp-paths.js';
27
- import { resolveConfig } from './lib/config-resolver.js';
28
- import { Logger } from './lib/Logger.js';
29
- import { createProvider } from './lib/provider-factory.js';
30
- import { tick } from './lib/wave-runner/tick.js';
31
-
32
- const HELP = `Usage: node .agents/scripts/wave-tick.js --epic <epicId> [--check-idle <minutes>]
33
-
34
- Stateless wave-loop planner. Reads the epic-run-state checkpoint on
35
- Epic #<id>, evaluates the live story-label state, and prints one
36
- WaveTickResult envelope describing the next dispatchable action.
37
-
38
- When --check-idle <minutes> is supplied, the planner skips the normal
39
- WaveTickResult emit and instead scans the per-Epic lifecycle ledger
40
- (temp/epic-<id>/lifecycle.ndjson) for in-flight Stories whose most
41
- recent lifecycle event is older than the threshold. Emits a single
42
- JSON envelope on stdout and exits non-zero when at least one stalled
43
- Story is detected. The envelope shape mirrors the wave-stall
44
- structured-comment payload so the slash-command host can post it
45
- verbatim.
46
- `;
47
-
48
- export async function runWaveTickCli({
49
- epicId,
50
- cwd,
51
- injectedProvider,
52
- injectedConfig,
53
- } = {}) {
54
- if (!Number.isInteger(epicId) || epicId <= 0) {
55
- throw new TypeError('runWaveTickCli: --epic must be a positive integer');
56
- }
57
-
58
- const config = injectedConfig ?? resolveConfig({ cwd });
59
- const provider = injectedProvider ?? createProvider(config);
60
-
61
- const result = await tick({
62
- epic: epicId,
63
- collaborators: { provider },
64
- ctx: { config },
65
- });
66
-
67
- return result;
68
- }
69
-
70
- /**
71
- * Scan the per-Epic lifecycle ledger and compute, per in-flight Story,
72
- * the timestamp of its most recent lifecycle event. A Story is
73
- * "in-flight" when the ledger carries a `story.dispatch.start` record
74
- * without a matching `story.dispatch.end`. Any other `story.*` event
75
- * (notably `story.heartbeat` from Story #3057) refreshes the Story's
76
- * last-event timestamp.
77
- *
78
- * Pure helper — exported for unit tests.
79
- *
80
- * @param {string} ledgerPath Absolute path to `lifecycle.ndjson`.
81
- * @returns {Map<number, string>} `storyId → ISO-8601 timestamp`. Empty
82
- * when the ledger is missing, unreadable, or carries no in-flight
83
- * Stories.
84
- */
85
- export function readLedgerLastEvents(ledgerPath) {
86
- if (!ledgerPath || !existsSync(ledgerPath)) return new Map();
87
- let raw;
88
- try {
89
- raw = readFileSync(ledgerPath, 'utf8');
90
- } catch {
91
- return new Map();
92
- }
93
- if (!raw) return new Map();
94
- const started = new Set();
95
- const ended = new Set();
96
- const lastTs = new Map();
97
- for (const line of raw.split(/\r?\n/)) {
98
- if (!line) continue;
99
- let record;
100
- try {
101
- record = JSON.parse(line);
102
- } catch {
103
- continue;
104
- }
105
- if (!record || record.kind !== 'emitted') continue;
106
- const event = typeof record.event === 'string' ? record.event : '';
107
- if (!event.startsWith('story.')) continue;
108
- const storyId = record.payload?.storyId;
109
- if (!Number.isInteger(storyId) || storyId <= 0) continue;
110
- if (event === 'story.dispatch.start') started.add(storyId);
111
- else if (event === 'story.dispatch.end') ended.add(storyId);
112
- const ts = typeof record.ts === 'string' ? record.ts : null;
113
- if (ts) {
114
- const prior = lastTs.get(storyId);
115
- if (!prior || prior < ts) lastTs.set(storyId, ts);
116
- }
117
- }
118
- const out = new Map();
119
- for (const id of started) {
120
- if (ended.has(id)) continue;
121
- const ts = lastTs.get(id);
122
- if (ts) out.set(id, ts);
123
- }
124
- return out;
125
- }
126
-
127
- /**
128
- * Single-delivery analogue of {@link readLedgerLastEvents} (Epic #4476, M5).
129
- * A single-delivery run has no Story fan-out; the whole Epic is one long
130
- * guarded session walking the Delivery Slicing table, and its liveness signal
131
- * is `slice.heartbeat` (emitted off the token stream by the PostToolUse hook).
132
- * This scans the ledger for `slice.*` events, treats a slice carrying a
133
- * `slice.start` without a matching `slice.end` as in-flight, and returns each
134
- * in-flight slice's most recent event timestamp — the same
135
- * started-without-ended shape the Story reader uses, keyed by the string
136
- * `sliceId`. Any `slice.*` event (notably `slice.heartbeat`) refreshes the
137
- * timestamp.
138
- *
139
- * Pure helper — exported for unit tests.
140
- *
141
- * @param {string} ledgerPath Absolute path to `lifecycle.ndjson`.
142
- * @returns {Map<string, string>} `sliceId → ISO-8601 timestamp`. Empty when
143
- * the ledger is missing, unreadable, or carries no in-flight slices.
144
- */
145
- export function readLedgerSliceEvents(ledgerPath) {
146
- if (!ledgerPath || !existsSync(ledgerPath)) return new Map();
147
- let raw;
148
- try {
149
- raw = readFileSync(ledgerPath, 'utf8');
150
- } catch {
151
- return new Map();
152
- }
153
- if (!raw) return new Map();
154
- const started = new Set();
155
- const ended = new Set();
156
- const lastTs = new Map();
157
- for (const line of raw.split(/\r?\n/)) {
158
- if (!line) continue;
159
- let record;
160
- try {
161
- record = JSON.parse(line);
162
- } catch {
163
- continue;
164
- }
165
- if (!record || record.kind !== 'emitted') continue;
166
- const event = typeof record.event === 'string' ? record.event : '';
167
- if (!event.startsWith('slice.')) continue;
168
- const sliceId = record.payload?.sliceId;
169
- if (typeof sliceId !== 'string' || sliceId.length === 0) continue;
170
- if (event === 'slice.start') started.add(sliceId);
171
- else if (event === 'slice.end') ended.add(sliceId);
172
- const ts = typeof record.ts === 'string' ? record.ts : null;
173
- if (ts) {
174
- const prior = lastTs.get(sliceId);
175
- if (!prior || prior < ts) lastTs.set(sliceId, ts);
176
- }
177
- }
178
- const out = new Map();
179
- for (const id of started) {
180
- if (ended.has(id)) continue;
181
- const ts = lastTs.get(id);
182
- if (ts) out.set(id, ts);
183
- }
184
- return out;
185
- }
186
-
187
- /**
188
- * Deterministic branch-activity resolver (Story #3900). Returns the epoch-ms
189
- * timestamp of the most recent commit on `story-<storyId>` via
190
- * `git log -1 --format=%cI`, or `null` when the branch does not exist, has no
191
- * commits, or git is unavailable.
192
- *
193
- * This is the secondary liveness signal the idle watchdog consults before
194
- * flagging a Story as stalled: a healthy long-running Story routinely exceeds
195
- * the heartbeat threshold during `implementing → closing` (heartbeats fire
196
- * only at phase transitions), but its branch keeps gaining commits. A recent
197
- * commit is hard, deterministic evidence of forward progress that does not
198
- * depend on a heartbeat landing in the ledger. Pure-ish (shells out to git)
199
- * and injectable so unit tests never spawn a subprocess.
200
- *
201
- * @param {number} storyId
202
- * @param {{ cwd?: string, exec?: typeof execFileSync, branch?: string }} [deps]
203
- * `branch` overrides the default `story-<storyId>` ref — the single-delivery
204
- * watchdog passes `epic-<id>` (Epic #4476, M5) to consult the one
205
- * integration branch instead of a per-Story branch.
206
- * @returns {number|null} epoch-ms of the last commit, or null.
207
- */
208
- export function branchLastCommitMs(storyId, deps = {}) {
209
- const exec = deps.exec ?? execFileSync;
210
- const cwd = deps.cwd ?? process.cwd();
211
- const branch =
212
- typeof deps.branch === 'string' && deps.branch
213
- ? deps.branch
214
- : `story-${storyId}`;
215
- try {
216
- const out = exec('git', ['log', '-1', '--format=%cI', branch, '--'], {
217
- cwd,
218
- encoding: 'utf8',
219
- stdio: ['ignore', 'pipe', 'ignore'],
220
- }).trim();
221
- if (!out) return null;
222
- const ms = Date.parse(out);
223
- return Number.isFinite(ms) ? ms : null;
224
- } catch {
225
- // Branch absent / git unavailable — no deterministic signal.
226
- return null;
227
- }
228
- }
229
-
230
- /**
231
- * Build the wave-stall envelope. Pure helper — exported for unit tests.
232
- *
233
- * A Story whose latest ledger event is older than the threshold is *not*
234
- * flagged as stalled when its `story-<id>` branch carries a commit newer
235
- * than the threshold (Story #3900). Branch commits are deterministic
236
- * forward-progress evidence that survives the heartbeat-cadence gap during
237
- * `implementing → closing`, so consulting them eliminates the false-positive
238
- * re-dispatch hazard (two agents on one branch) the watchdog otherwise
239
- * manufactures for every healthy long-running Story.
240
- *
241
- * @param {object} args
242
- * @param {number} args.epicId
243
- * @param {number} args.thresholdMinutes
244
- * @param {Map<number, string>} args.lastEvents `storyId → ISO-8601 ts`
245
- * from {@link readLedgerLastEvents}.
246
- * @param {Date} args.now Reference clock for the staleness comparison.
247
- * @param {(storyId: number) => (number|null)} [args.branchActivity]
248
- * Resolver for the last commit epoch-ms on `story-<id>`. Defaults to
249
- * {@link branchLastCommitMs}. Injected for tests.
250
- * @param {Map<string, string>} [args.sliceEvents] `sliceId → ISO-8601 ts`
251
- * from {@link readLedgerSliceEvents} (Epic #4476, M5). Single-delivery has
252
- * no Story fan-out; its liveness signal is `slice.heartbeat`. When
253
- * non-empty, in-flight slices are surfaced under the additive
254
- * `inFlightSlices` / `stalledSlices` fields — the story fields are
255
- * untouched, so a fan-out run's envelope is byte-for-byte unchanged.
256
- * @param {(epicId: number) => (number|null)} [args.epicBranchActivity]
257
- * Resolver for the last commit epoch-ms on the single-delivery integration
258
- * branch `epic-<id>` — the deterministic forward-progress signal for the
259
- * one long session, mirroring the per-Story branch check. Injected for
260
- * tests.
261
- * @returns {{
262
- * kind: 'wave-stall',
263
- * epicId: number,
264
- * thresholdMinutes: number,
265
- * checkedAt: string,
266
- * stalled: Array<{storyId: number, lastEventAt: string, idleMinutes: number}>,
267
- * inFlight: number[],
268
- * stalledSlices: Array<{sliceId: string, lastEventAt: string, idleMinutes: number}>,
269
- * inFlightSlices: string[]
270
- * }}
271
- */
272
- export function buildWaveStallEnvelope({
273
- epicId,
274
- thresholdMinutes,
275
- lastEvents,
276
- now,
277
- branchActivity = branchLastCommitMs,
278
- sliceEvents = new Map(),
279
- epicBranchActivity = (eid) =>
280
- branchLastCommitMs(0, { branch: `epic-${eid}` }),
281
- }) {
282
- const checkedAt = now.toISOString();
283
- const thresholdMs = thresholdMinutes * 60 * 1000;
284
- const stalled = [];
285
- const inFlight = [];
286
- for (const [storyId, ts] of lastEvents) {
287
- inFlight.push(storyId);
288
- const eventMs = Date.parse(ts);
289
- if (!Number.isFinite(eventMs)) continue;
290
- const idleMs = now.getTime() - eventMs;
291
- if (idleMs < thresholdMs) continue;
292
-
293
- // Ledger says idle — consult the branch as a deterministic liveness
294
- // signal before declaring a stall. A recent commit means the Story is
295
- // making progress despite the heartbeat-cadence gap.
296
- const commitMs = branchActivity(storyId);
297
- if (
298
- typeof commitMs === 'number' &&
299
- Number.isFinite(commitMs) &&
300
- now.getTime() - commitMs < thresholdMs
301
- ) {
302
- continue;
303
- }
304
-
305
- stalled.push({
306
- storyId,
307
- lastEventAt: ts,
308
- idleMinutes: Math.floor(idleMs / 60000),
309
- });
310
- }
311
- inFlight.sort((a, b) => a - b);
312
- stalled.sort((a, b) => a.storyId - b.storyId);
313
-
314
- // Single-delivery slice liveness (additive). A slice that has gone silent
315
- // past the threshold is a stall UNLESS the `epic-<id>` branch carries a
316
- // recent commit — the same forward-progress carve-out the Story path uses.
317
- const stalledSlices = [];
318
- const inFlightSlices = [];
319
- for (const [sliceId, ts] of sliceEvents) {
320
- inFlightSlices.push(sliceId);
321
- const eventMs = Date.parse(ts);
322
- if (!Number.isFinite(eventMs)) continue;
323
- const idleMs = now.getTime() - eventMs;
324
- if (idleMs < thresholdMs) continue;
325
-
326
- const commitMs = epicBranchActivity(epicId);
327
- if (
328
- typeof commitMs === 'number' &&
329
- Number.isFinite(commitMs) &&
330
- now.getTime() - commitMs < thresholdMs
331
- ) {
332
- continue;
333
- }
334
-
335
- stalledSlices.push({
336
- sliceId,
337
- lastEventAt: ts,
338
- idleMinutes: Math.floor(idleMs / 60000),
339
- });
340
- }
341
- inFlightSlices.sort();
342
- stalledSlices.sort((a, b) => a.sliceId.localeCompare(b.sliceId));
343
-
344
- return {
345
- kind: 'wave-stall',
346
- epicId,
347
- thresholdMinutes,
348
- checkedAt,
349
- stalled,
350
- inFlight,
351
- stalledSlices,
352
- inFlightSlices,
353
- };
354
- }
355
-
356
- /**
357
- * Run the `--check-idle` path. Exported so unit tests can drive the
358
- * branch without spawning the CLI subprocess.
359
- *
360
- * @param {object} args
361
- * @param {number} args.epicId
362
- * @param {number} args.thresholdMinutes
363
- * @param {string} [args.ledgerPath] Override for tests; defaults to the
364
- * canonical `temp/epic-<id>/lifecycle.ndjson`.
365
- * @param {Date} [args.now] Override for tests; defaults to wall clock.
366
- * @param {object} [args.config] Optional resolved config for tempRoot.
367
- * @param {(storyId: number) => (number|null)} [args.branchActivity]
368
- * Branch-liveness resolver; defaults to {@link branchLastCommitMs}.
369
- * Injected for tests so the watchdog never spawns git.
370
- * @param {(epicId: number) => (number|null)} [args.epicBranchActivity]
371
- * Single-delivery integration-branch (`epic-<id>`) liveness resolver;
372
- * injected for tests. Defaults to {@link branchLastCommitMs} with the
373
- * `epic-<id>` ref.
374
- * @returns {{envelope: object, stalledCount: number}} `stalledCount` counts
375
- * both stalled Stories (fan-out) and stalled slices (single delivery), so a
376
- * dead single-delivery session still exits the CLI non-zero.
377
- */
378
- export function runCheckIdle({
379
- epicId,
380
- thresholdMinutes,
381
- ledgerPath,
382
- now = new Date(),
383
- config,
384
- branchActivity = branchLastCommitMs,
385
- epicBranchActivity,
386
- }) {
387
- if (!Number.isInteger(epicId) || epicId <= 0) {
388
- throw new TypeError('runCheckIdle: epicId must be a positive integer');
389
- }
390
- if (!Number.isInteger(thresholdMinutes) || thresholdMinutes <= 0) {
391
- throw new TypeError(
392
- 'runCheckIdle: thresholdMinutes must be a positive integer',
393
- );
394
- }
395
- const resolvedPath = ledgerPath ?? epicLedgerPath(epicId, config);
396
- const lastEvents = readLedgerLastEvents(resolvedPath);
397
- const sliceEvents = readLedgerSliceEvents(resolvedPath);
398
- const envelope = buildWaveStallEnvelope({
399
- epicId,
400
- thresholdMinutes,
401
- lastEvents,
402
- now,
403
- branchActivity,
404
- sliceEvents,
405
- ...(epicBranchActivity ? { epicBranchActivity } : {}),
406
- });
407
- return {
408
- envelope,
409
- stalledCount: envelope.stalled.length + envelope.stalledSlices.length,
410
- };
411
- }
412
-
413
- async function main(argv) {
414
- const { values } = parseArgs({
415
- args: argv,
416
- options: {
417
- epic: { type: 'string' },
418
- 'check-idle': { type: 'string' },
419
- help: { type: 'boolean', short: 'h' },
420
- },
421
- strict: false,
422
- allowPositionals: true,
423
- });
424
-
425
- if (values.help) {
426
- process.stdout.write(`${HELP}\n`);
427
- return;
428
- }
429
-
430
- const epicId = Number.parseInt(
431
- String(values.epic ?? '').replace(/^#/, ''),
432
- 10,
433
- );
434
- if (!Number.isInteger(epicId) || epicId <= 0) {
435
- Logger.error('wave-tick: --epic <id> is required (positive integer)');
436
- process.exitCode = 2;
437
- return;
438
- }
439
-
440
- if (values['check-idle'] !== undefined) {
441
- const thresholdMinutes = Number.parseInt(String(values['check-idle']), 10);
442
- if (!Number.isInteger(thresholdMinutes) || thresholdMinutes <= 0) {
443
- Logger.error(
444
- 'wave-tick: --check-idle <minutes> must be a positive integer',
445
- );
446
- process.exitCode = 2;
447
- return;
448
- }
449
- const { envelope, stalledCount } = runCheckIdle({
450
- epicId,
451
- thresholdMinutes,
452
- });
453
- process.stdout.write(`${JSON.stringify(envelope, null, 2)}\n`);
454
- process.exitCode = stalledCount > 0 ? 1 : 0;
455
- return;
456
- }
457
-
458
- const result = await runWaveTickCli({ epicId });
459
- process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
460
- }
461
-
462
- runAsCli(import.meta.url, () => main(process.argv.slice(2)), {
463
- source: 'wave-tick',
464
- });
@@ -1,98 +0,0 @@
1
- ---
2
- name: analyze-execution
3
- description: >-
4
- Aggregate per-Story or per-Epic execution signals into a structured
5
- perf-summary or perf-report and upsert it onto the corresponding GitHub
6
- ticket. Use after a Story closes (Story mode) or as part of
7
- `/deliver` Phase 6 (Epic mode). Reads NDJSON via
8
- `lib/signals/read` and writes a single structured comment.
9
- allowed_tools:
10
- - Read
11
- - Bash
12
- ---
13
-
14
- # analyze-execution
15
-
16
- ## Policy Capsule
17
-
18
- - Invoke via the wrapping CLI `node .agents/scripts/analyze-execution.js`; do not duplicate the read/write logic from this Skill body.
19
- - Resolve mode strictly by flags: `--story <sid> --epic <eid>` → Story mode; `--epic <eid>` alone → Epic mode.
20
- - Read NDJSON signals only through `lib/signals/read` (the async-iterator entry point). Never open `<tempRoot>/epic-<eid>/story-<sid>/signals.ndjson` directly — the reader owns the warn-once malformed-JSON policy.
21
- - Emit a single structured GitHub comment per ticket (`<!-- structured:story-perf-summary -->` or `<!-- structured:epic-perf-report -->`); rely on `upsertStructuredComment` for idempotence — never post duplicates.
22
- - Never rename or alter the structured-marker IDs; the retro composer and Epic dashboard grep them verbatim.
23
- - Validate the structured payload against `docs/data-dictionary.md §StoryPerfSummary` or `§EpicPerfReport` before posting. Schema violations exit non-zero.
24
- - Soft-fail (exit 0 with a warning) when NDJSON is missing for a Story or an Epic has no children — observability output MUST NOT block the close pipeline.
25
- - Do not write to disk. Persistence is GitHub; the Skill is read-NDJSON + post-comment only.
26
-
27
- ## Role
28
-
29
- Observability writer. Composes the structured `story-perf-summary` /
30
- `epic-perf-report` comment bodies the retro composer downstream renders
31
- into the Epic dashboard.
32
-
33
- ## When to use
34
-
35
- - **Story mode** — after `story-close.js` finishes, the post-merge
36
- pipeline dispatches this Skill (or the wrapping script) to roll up the
37
- Story's NDJSON signals into a single `<!-- structured:story-perf-summary -->`
38
- marker comment on the Story ticket.
39
- - **Epic mode** — during `/deliver` Phase 6.0 (or the retro
40
- composer), the Skill fans out across every Story under the Epic,
41
- reads each Story's structured perf summary, and posts a single
42
- `<!-- structured:epic-perf-report -->` marker on the Epic ticket.
43
-
44
- ## Inputs
45
-
46
- The Skill reads (never writes) the NDJSON signal stream at:
47
-
48
- ```text
49
- <tempRoot>/epic-<eid>/story-<sid>/signals.ndjson
50
- ```
51
-
52
- Use the `lib/signals/read` async-iterator entry point — never open the
53
- file directly. Story mode also reads `phase-timings.json` written by
54
- `post-merge-close.js`.
55
-
56
- ## Outputs
57
-
58
- A single upserted GitHub comment per ticket. The Skill writes nothing to
59
- disk — the persist path is GitHub. Idempotence: the underlying script's
60
- `upsertStructuredComment` helper deletes any prior marker before posting
61
- the new one.
62
-
63
- ## Procedure
64
-
65
- ### Step 1 — Resolve mode
66
-
67
- If both `--story <sid>` and `--epic <eid>` are supplied → Story mode.
68
- If only `--epic <eid>` is supplied → Epic mode. The script
69
- `analyze-execution.js` is the dispatcher today; this Skill documents the
70
- contract the dispatcher implements.
71
-
72
- ### Step 2 — Read signals via lib/signals/read
73
-
74
- ```bash
75
- node .agents/scripts/analyze-execution.js --story <sid> --epic <eid>
76
- # or
77
- node .agents/scripts/analyze-execution.js --epic <eid>
78
- ```
79
-
80
- ### Step 3 — Validate the structured payload before posting
81
-
82
- The payload must conform to `docs/data-dictionary.md §StoryPerfSummary`
83
- or §EpicPerfReport. Schema violations exit non-zero — the close
84
- pipeline treats that as a non-fatal warning, but the smoke spec pins
85
- the contract so we never silently emit malformed comments.
86
-
87
- ## Constraints
88
-
89
- - Do **not** open `signals.ndjson` outside `lib/signals/read` — the
90
- reader handles the warn-once policy for malformed JSON lines and
91
- the streaming-iteration contract.
92
- - Do **not** rename the structured-marker IDs
93
- (`<!-- structured:story-perf-summary -->`,
94
- `<!-- structured:epic-perf-report -->`); the retro composer and the
95
- Epic dashboard both grep for them verbatim.
96
- - Soft-failure mode is intentional: missing NDJSON for a Story or no
97
- children for an Epic returns exit 0 with a warning so close pipelines
98
- never block on observability output.