mandrel 1.58.0 → 1.60.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 (319) hide show
  1. package/.agents/README.md +100 -98
  2. package/.agents/docs/SDLC.md +140 -141
  3. package/.agents/docs/configuration.md +16 -16
  4. package/.agents/docs/workflows.md +7 -8
  5. package/.agents/instructions.md +12 -11
  6. package/.agents/personas/architect.md +1 -1
  7. package/.agents/personas/product.md +1 -1
  8. package/.agents/personas/project-manager.md +14 -14
  9. package/.agents/personas/technical-writer.md +1 -1
  10. package/.agents/rules/changelog-style.md +5 -5
  11. package/.agents/rules/git-conventions.md +3 -3
  12. package/.agents/schemas/agentrc.schema.json +3 -3
  13. package/.agents/schemas/audit-rules.json +20 -0
  14. package/.agents/schemas/dispatch-manifest.json +4 -4
  15. package/.agents/schemas/epic-spec.schema.json +15 -45
  16. package/.agents/schemas/lifecycle/README.md +1 -1
  17. package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +1 -1
  18. package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +1 -1
  20. package/.agents/schemas/validation-evidence.schema.json +1 -1
  21. package/.agents/scripts/README.md +1 -1
  22. package/.agents/scripts/acceptance-eval.js +21 -4
  23. package/.agents/scripts/acceptance-spec-reconciler.js +2 -2
  24. package/.agents/scripts/analyze-execution.js +2 -2
  25. package/.agents/scripts/assert-branch.js +1 -3
  26. package/.agents/scripts/audit-to-stories.js +1 -1
  27. package/.agents/scripts/bootstrap.js +1 -1
  28. package/.agents/scripts/check-arch-cycles.js +360 -0
  29. package/.agents/scripts/check-doc-links.js +2 -3
  30. package/.agents/scripts/coverage-capture.js +24 -3
  31. package/.agents/scripts/diagnose-friction.js +1 -1
  32. package/.agents/scripts/dispatcher.js +2 -2
  33. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  34. package/.agents/scripts/epic-audit-prepare.js +3 -3
  35. package/.agents/scripts/epic-deliver-note-intervention.js +2 -2
  36. package/.agents/scripts/epic-deliver-preflight.js +11 -9
  37. package/.agents/scripts/epic-deliver-prepare.js +13 -5
  38. package/.agents/scripts/epic-execute-record-wave.js +5 -5
  39. package/.agents/scripts/epic-plan-healthcheck.js +6 -10
  40. package/.agents/scripts/epic-plan-spec-validate.js +1 -1
  41. package/.agents/scripts/epic-reconcile.js +11 -29
  42. package/.agents/scripts/evidence-gate.js +2 -2
  43. package/.agents/scripts/generate-workflows-doc.js +1 -1
  44. package/.agents/scripts/git-rebase-and-resolve.js +1 -1
  45. package/.agents/scripts/hierarchy-gate.js +40 -24
  46. package/.agents/scripts/lib/ITicketingProvider.js +1 -1
  47. package/.agents/scripts/lib/audit-suite/selector.js +1 -1
  48. package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +2 -2
  49. package/.agents/scripts/lib/baseline-snapshot.js +7 -7
  50. package/.agents/scripts/lib/baselines/kinds/coverage.js +33 -149
  51. package/.agents/scripts/lib/baselines/kinds/duplication.js +27 -116
  52. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +192 -0
  53. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +34 -133
  54. package/.agents/scripts/lib/baselines/kinds/maintainability.js +31 -124
  55. package/.agents/scripts/lib/baselines/kinds/mutation.js +25 -111
  56. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +59 -0
  57. package/.agents/scripts/lib/baselines/maintainability-baseline-save.js +37 -0
  58. package/.agents/scripts/lib/baselines/writer.js +1 -1
  59. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  60. package/.agents/scripts/lib/bdd-scenario-scanner.js +3 -3
  61. package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +1 -1
  62. package/.agents/scripts/lib/bootstrap/branch-protection.js +1 -1
  63. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +1 -1
  64. package/.agents/scripts/lib/bootstrap/commit-push.js +2 -2
  65. package/.agents/scripts/lib/close-validation/commands.js +188 -0
  66. package/.agents/scripts/lib/close-validation/gates.js +235 -0
  67. package/.agents/scripts/lib/close-validation/process.js +101 -0
  68. package/.agents/scripts/lib/close-validation/projections/maintainability.js +1 -1
  69. package/.agents/scripts/lib/close-validation/runner.js +325 -0
  70. package/.agents/scripts/lib/close-validation/telemetry.js +70 -0
  71. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  72. package/.agents/scripts/lib/config/explain.js +1 -1
  73. package/.agents/scripts/lib/config/quality.js +6 -6
  74. package/.agents/scripts/lib/config/runners.js +2 -2
  75. package/.agents/scripts/lib/config/runtime.js +1 -1
  76. package/.agents/scripts/lib/config/temp-paths.js +2 -2
  77. package/.agents/scripts/lib/config-resolver.js +2 -5
  78. package/.agents/scripts/lib/config-settings-schema-delivery.js +2 -2
  79. package/.agents/scripts/lib/config-settings-schema-quality.js +1 -1
  80. package/.agents/scripts/lib/config-settings-schema.js +3 -3
  81. package/.agents/scripts/lib/coverage-capture.js +147 -4
  82. package/.agents/scripts/lib/cpu-pool.js +14 -0
  83. package/.agents/scripts/lib/crap-utils.js +6 -11
  84. package/.agents/scripts/lib/duplicate-search.js +1 -1
  85. package/.agents/scripts/lib/dynamic-workflow/capability.js +1 -1
  86. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +87 -0
  87. package/.agents/scripts/lib/epic-plan-clarity.js +1 -1
  88. package/.agents/scripts/lib/epic-plan-ideation.js +1 -1
  89. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +1 -1
  90. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +1 -1
  91. package/.agents/scripts/lib/findings/classify-finding.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +10 -10
  93. package/.agents/scripts/lib/git-utils.js +24 -22
  94. package/.agents/scripts/lib/label-constants.js +3 -4
  95. package/.agents/scripts/lib/label-taxonomy.js +3 -8
  96. package/.agents/scripts/lib/maintainability-engine.js +1 -1
  97. package/.agents/scripts/lib/maintainability-utils.js +4 -187
  98. package/.agents/scripts/lib/observability/perf-report-readers.js +32 -23
  99. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +81 -7
  100. package/.agents/scripts/lib/orchestration/code-review.js +95 -82
  101. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +8 -9
  102. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +3 -3
  103. package/.agents/scripts/lib/orchestration/detectors-phase.js +2 -2
  104. package/.agents/scripts/lib/orchestration/dispatch-engine.js +30 -38
  105. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +14 -37
  106. package/.agents/scripts/lib/orchestration/epic-cleanup.js +1 -1
  107. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +22 -22
  108. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +1 -1
  109. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +7 -21
  110. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +3 -3
  111. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +2 -2
  112. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +206 -58
  113. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +1 -1
  114. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +27 -3
  115. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +1 -1
  116. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +28 -8
  117. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +1 -1
  118. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +3 -3
  119. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +4 -4
  120. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +3 -3
  121. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +13 -41
  122. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +7 -7
  123. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +2 -3
  124. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +2 -8
  125. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +4 -4
  126. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +103 -0
  127. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +22 -64
  128. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +38 -76
  129. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +4 -4
  130. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +10 -10
  131. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +8 -20
  132. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +7 -15
  133. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +72 -41
  134. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +2 -4
  135. package/.agents/scripts/lib/orchestration/file-assumptions.js +6 -5
  136. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +1 -1
  137. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +2 -2
  138. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +1 -1
  139. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +144 -0
  140. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +1 -1
  141. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +3 -3
  142. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +1 -1
  143. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +1 -1
  144. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +1 -1
  145. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +1 -1
  146. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +1 -1
  147. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  148. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +1 -1
  149. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +1 -1
  150. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +8 -8
  151. package/.agents/scripts/lib/orchestration/manifest-builder.js +5 -5
  152. package/.agents/scripts/lib/orchestration/parked-follow-ons.js +2 -2
  153. package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +5 -5
  154. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +3 -3
  155. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +3 -3
  156. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +7 -7
  157. package/.agents/scripts/lib/orchestration/preflight-cache.js +36 -13
  158. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +1 -1
  159. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +1 -1
  160. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +2 -2
  161. package/.agents/scripts/lib/orchestration/retro-runner.js +3 -3
  162. package/.agents/scripts/lib/orchestration/review-depth.js +1 -1
  163. package/.agents/scripts/lib/orchestration/review-providers/codex.js +5 -60
  164. package/.agents/scripts/lib/orchestration/review-providers/native.js +7 -6
  165. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +105 -0
  166. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +7 -59
  167. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +2 -4
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +1 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +1 -1
  170. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +2 -4
  171. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +32 -35
  172. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +1 -2
  173. package/.agents/scripts/lib/orchestration/spec-freshness.js +1 -1
  174. package/.agents/scripts/lib/orchestration/spec-renderer.js +36 -73
  175. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  176. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +451 -503
  177. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +8 -2
  178. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +47 -2
  179. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +2 -2
  180. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +1 -1
  181. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +358 -54
  182. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +1 -1
  183. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +3 -2
  184. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +32 -5
  185. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +5 -18
  186. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +3 -3
  187. package/.agents/scripts/lib/orchestration/story-close-recovery.js +33 -16
  188. package/.agents/scripts/lib/orchestration/story-reachability.js +47 -0
  189. package/.agents/scripts/lib/orchestration/task-body-validator.js +6 -6
  190. package/.agents/scripts/lib/orchestration/ticket-lease.js +1 -1
  191. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +4 -35
  192. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +1 -10
  193. package/.agents/scripts/lib/orchestration/ticket-validator.js +25 -70
  194. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +44 -73
  195. package/.agents/scripts/lib/orchestration/ticketing/reads.js +16 -7
  196. package/.agents/scripts/lib/orchestration/ticketing/state.js +53 -439
  197. package/.agents/scripts/lib/orchestration/ticketing/transition.js +471 -0
  198. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  199. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +3 -3
  200. package/.agents/scripts/lib/orchestration/wave-record-projection.js +2 -8
  201. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -1
  202. package/.agents/scripts/lib/preflight-runner.js +1 -1
  203. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +4 -5
  204. package/.agents/scripts/lib/presentation/manifest-builder.js +28 -34
  205. package/.agents/scripts/lib/presentation/manifest-formatter.js +3 -4
  206. package/.agents/scripts/lib/presentation/manifest-helpers.js +1 -1
  207. package/.agents/scripts/lib/presentation/manifest-procedures.js +4 -4
  208. package/.agents/scripts/lib/presentation/manifest-render-waves.js +4 -23
  209. package/.agents/scripts/lib/presentation/manifest-renderer.js +1 -1
  210. package/.agents/scripts/lib/presentation/manifest-story-views.js +2 -11
  211. package/.agents/scripts/lib/project-root.js +17 -0
  212. package/.agents/scripts/lib/signals/schema.js +1 -1
  213. package/.agents/scripts/lib/spec/index.js +1 -1
  214. package/.agents/scripts/lib/spec/loader.js +2 -2
  215. package/.agents/scripts/lib/spec/state.js +7 -16
  216. package/.agents/scripts/lib/story-adjacency.js +76 -0
  217. package/.agents/scripts/lib/story-init/context-resolver.js +3 -3
  218. package/.agents/scripts/lib/story-init/state-transitioner.js +2 -2
  219. package/.agents/scripts/lib/story-init/task-graph-builder.js +7 -7
  220. package/.agents/scripts/lib/story-lifecycle.js +9 -9
  221. package/.agents/scripts/lib/story-plan.js +1 -1
  222. package/.agents/scripts/lib/templates/decomposer-prompts.js +59 -52
  223. package/.agents/scripts/lib/transpile.js +93 -0
  224. package/.agents/scripts/lib/wave-runner/tick.js +4 -153
  225. package/.agents/scripts/lib/workers/crap-worker.js +1 -1
  226. package/.agents/scripts/lib/workers/maintainability-report-worker.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/creation.js +20 -2
  228. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +90 -0
  229. package/.agents/scripts/lib/worktree/lifecycle/reap.js +26 -8
  230. package/.agents/scripts/lib/worktree/node-modules-strategy.js +74 -0
  231. package/.agents/scripts/lifecycle-emit-story-dispatch.js +1 -1
  232. package/.agents/scripts/lifecycle-emit.js +1 -1
  233. package/.agents/scripts/providers/github/board-add.js +1 -1
  234. package/.agents/scripts/providers/github/errors.js +1 -1
  235. package/.agents/scripts/providers/github/mappers.js +2 -2
  236. package/.agents/scripts/providers/github/tickets.js +114 -10
  237. package/.agents/scripts/resync-status-column.js +1 -1
  238. package/.agents/scripts/retro-run.js +2 -2
  239. package/.agents/scripts/run-lint.js +10 -1
  240. package/.agents/scripts/run-tests.js +24 -4
  241. package/.agents/scripts/single-story-init.js +1 -1
  242. package/.agents/scripts/stories-wave-tick.js +13 -10
  243. package/.agents/scripts/story-close.js +1 -1
  244. package/.agents/scripts/story-init.js +162 -26
  245. package/.agents/scripts/story-phase.js +5 -5
  246. package/.agents/scripts/story-plan.js +3 -3
  247. package/.agents/scripts/sync-branch-from-base.js +2 -2
  248. package/.agents/scripts/validate-docs-freshness.js +1 -1
  249. package/.agents/scripts/wave-tick.js +1 -1
  250. package/.agents/skills/core/analyze-execution/SKILL.md +2 -2
  251. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +21 -26
  252. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +23 -56
  253. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +4 -4
  254. package/.agents/skills/core/hydrate-context/SKILL.md +2 -2
  255. package/.agents/skills/core/idea-refinement/SKILL.md +4 -4
  256. package/.agents/skills/core/knowledge-transfer/SKILL.md +2 -2
  257. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +1 -1
  258. package/.agents/skills/core/scope-triage/SKILL.md +9 -10
  259. package/.agents/skills/core/using-agent-skills/SKILL.md +1 -1
  260. package/.agents/skills/skills.index.json +7 -7
  261. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +1 -1
  262. package/.agents/templates/agent-protocol.md +2 -2
  263. package/.agents/workflows/agents-update.md +2 -2
  264. package/.agents/workflows/audit-architecture.md +2 -2
  265. package/.agents/workflows/audit-clean-code.md +2 -2
  266. package/.agents/workflows/audit-dependencies.md +1 -1
  267. package/.agents/workflows/audit-devops.md +1 -1
  268. package/.agents/workflows/audit-documentation.md +226 -0
  269. package/.agents/workflows/audit-lighthouse.md +1 -1
  270. package/.agents/workflows/audit-performance.md +2 -2
  271. package/.agents/workflows/audit-privacy.md +1 -1
  272. package/.agents/workflows/audit-quality.md +2 -2
  273. package/.agents/workflows/audit-security.md +2 -2
  274. package/.agents/workflows/audit-seo.md +1 -1
  275. package/.agents/workflows/audit-sre.md +1 -1
  276. package/.agents/workflows/audit-to-stories.md +10 -10
  277. package/.agents/workflows/audit-ux-ui.md +1 -1
  278. package/.agents/workflows/deliver.md +85 -0
  279. package/.agents/workflows/explain.md +3 -3
  280. package/.agents/workflows/git-merge-pr.md +1 -1
  281. package/.agents/workflows/git-pr-all.md +13 -10
  282. package/.agents/workflows/git-push.md +6 -3
  283. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  284. package/.agents/workflows/helpers/acceptance-self-eval.md +1 -1
  285. package/.agents/workflows/helpers/code-review.md +5 -5
  286. package/.agents/workflows/{epic-deliver.md → helpers/deliver-epic.md} +59 -66
  287. package/.agents/workflows/{story-deliver.md → helpers/deliver-stories.md} +25 -25
  288. package/.agents/workflows/helpers/diagnose.md +1 -1
  289. package/.agents/workflows/helpers/epic-audit.md +6 -6
  290. package/.agents/workflows/helpers/epic-deliver-story.md +28 -39
  291. package/.agents/workflows/helpers/epic-plan-decompose.md +23 -23
  292. package/.agents/workflows/helpers/epic-plan-spec.md +6 -6
  293. package/.agents/workflows/helpers/epic-testing.md +3 -3
  294. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  295. package/.agents/workflows/{epic-plan.md → helpers/plan-epic.md} +84 -84
  296. package/.agents/workflows/{story-plan.md → helpers/plan-story.md} +43 -43
  297. package/.agents/workflows/helpers/signals.md +1 -1
  298. package/.agents/workflows/helpers/single-story-deliver.md +12 -11
  299. package/.agents/workflows/helpers/worktree-lifecycle.md +18 -18
  300. package/.agents/workflows/onboard.md +21 -20
  301. package/.agents/workflows/plan.md +89 -0
  302. package/.agents/workflows/qa-explore.md +1 -1
  303. package/.agents/workflows/qa-run-harness.md +1 -1
  304. package/README.md +17 -20
  305. package/docs/CHANGELOG.md +1149 -0
  306. package/lib/cli/__tests__/update-changelog-surface.test.js +357 -0
  307. package/lib/cli/__tests__/update-reexec.test.js +513 -0
  308. package/lib/cli/init.js +338 -0
  309. package/lib/cli/update.js +413 -52
  310. package/package.json +3 -1
  311. package/.agents/scripts/lib/auto-refresh-baselines.js +0 -308
  312. package/.agents/scripts/lib/close-validation.js +0 -897
  313. package/.agents/scripts/lib/orchestration/cascade-grouping.js +0 -275
  314. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +0 -69
  315. package/.agents/scripts/lib/orchestration/reconciler.js +0 -137
  316. package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +0 -221
  317. package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +0 -123
  318. package/.agents/scripts/lib/task-utils.js +0 -26
  319. package/.agents/scripts/story-deliver-prepare.js +0 -267
@@ -1,275 +0,0 @@
1
- /**
2
- * lib/orchestration/cascade-grouping.js — Cascade dispatch helpers.
3
- *
4
- * Pure helpers used by `cascadeCompletion` (see `./ticketing.js`) to
5
- * partition a list of parent tickets into disjoint shared-ancestor groups
6
- * and to buffer per-parent log output so parallel dispatch produces a
7
- * byte-identical log stream to the serial baseline.
8
- *
9
- * Pulled out of `ticketing.js` so the cascade orchestrator stays under the
10
- * project's per-file maintainability ceiling. No state is held at module
11
- * scope — every helper takes its dependencies as arguments.
12
- */
13
-
14
- /**
15
- * Walks `parent: #N` references upward from the given ticket id until no new
16
- * ancestors are discovered. Returns the set of every ticket id reachable
17
- * along the chain, including the starting id. Cycle-safe by construction —
18
- * the visited set acts as the seen guard, so a cyclic `parent: #N` graph
19
- * terminates in finite steps without revisiting nodes.
20
- *
21
- * Pure of side effects beyond the provider reads it issues. Provider
22
- * failures on a single hop fall back to "no further ancestors discovered"
23
- * for that branch (the chain truncates rather than throwing); this matches
24
- * `cascadeCompletion`'s tolerant posture toward transient reads.
25
- *
26
- * @param {import('../ITicketingProvider.js').ITicketingProvider} provider
27
- * @param {number} startId
28
- * @param {Map<number, Set<number>>} [cache] - Optional per-call cache of
29
- * already-walked chains keyed by intermediate id. Reused across parents
30
- * in {@link groupByAncestor} to amortise repeat walks.
31
- * @returns {Promise<Set<number>>} ancestor set including `startId`.
32
- */
33
- export async function walkAncestorChain(provider, startId, cache) {
34
- // Inner DFS with memoisation. `inProgress` guards cycles so a cyclic
35
- // `parent: #N` graph terminates without recursion depth issues. Each
36
- // visited node gets its own cache entry holding the set of ids reachable
37
- // from it (inclusive), so a sibling walk that re-enters this subgraph
38
- // can splice the cached set wholesale instead of re-reading the provider.
39
- async function visit(id, inProgress) {
40
- if (cache?.has(id)) return cache.get(id);
41
- if (inProgress.has(id)) {
42
- // Cycle: return a singleton so the caller still includes `id` in its
43
- // ancestor set without recursing further through this loop. Do NOT
44
- // memoise — the partial result is incomplete for `id`'s true chain.
45
- return new Set([id]);
46
- }
47
- inProgress.add(id);
48
-
49
- const set = new Set([id]);
50
- let ticket = null;
51
- try {
52
- ticket = await provider.getTicket(id);
53
- } catch {
54
- // Provider read failure: truncate the chain branch. Memoise as the
55
- // singleton so subsequent walks don't retry an already-failed read.
56
- inProgress.delete(id);
57
- cache?.set(id, set);
58
- return set;
59
- }
60
-
61
- if (ticket?.body) {
62
- const matches = [...ticket.body.matchAll(/parent:\s*#(\d+)/gi)];
63
- for (const m of matches) {
64
- const next = Number.parseInt(m[1], 10);
65
- if (!Number.isFinite(next)) continue;
66
- const subset = await visit(next, inProgress);
67
- for (const v of subset) set.add(v);
68
- }
69
- }
70
-
71
- inProgress.delete(id);
72
- cache?.set(id, set);
73
- return set;
74
- }
75
-
76
- return visit(startId, new Set());
77
- }
78
-
79
- /**
80
- * Partitions a list of parent ids into disjoint groups whose members share
81
- * at least one ancestor (transitively, via `parent: #N` references walked
82
- * to fixpoint).
83
- *
84
- * Two parents end up in the same group if and only if their ancestor sets
85
- * overlap on at least one ticket id. Parents with no shared ancestors end
86
- * up in singleton groups. The union of the returned groups equals the
87
- * input set; the order of `parents[]` is preserved within each group, and
88
- * groups are returned in the order their first member appears in the
89
- * input.
90
- *
91
- * Pure of side effects beyond the provider reads needed to walk chains.
92
- * Walked ancestor sets are cached per call so a parent that contributes
93
- * to multiple groups is not re-walked. Cycle-safe — see
94
- * {@link walkAncestorChain}.
95
- *
96
- * Used by `cascadeCompletion` to dispatch disjoint groups in parallel
97
- * while keeping shared-ancestor groups strictly sequential (concurrent
98
- * transitions on the same ancestor would race the "all children done?"
99
- * check).
100
- *
101
- * @param {Array<number>} parents
102
- * @param {import('../ITicketingProvider.js').ITicketingProvider} provider
103
- * @returns {Promise<Array<Array<number>>>} disjoint groups of parent ids.
104
- */
105
- export async function groupByAncestor(parents, provider) {
106
- if (!Array.isArray(parents) || parents.length === 0) return [];
107
-
108
- // Walk each parent's ancestor chain once, sharing a cache so a parent
109
- // that re-enters an already-walked subgraph reuses the cached set.
110
- const cache = new Map();
111
- const ancestorsByParent = new Map();
112
- for (const parentId of parents) {
113
- const chain = await walkAncestorChain(provider, parentId, cache);
114
- ancestorsByParent.set(parentId, chain);
115
- }
116
-
117
- return unionFindByAncestor(parents, ancestorsByParent);
118
- }
119
-
120
- /**
121
- * Union-Find over `parents`, joined whenever any two parents' ancestor
122
- * chains overlap on at least one id. Returns the parents bucketed by
123
- * representative, in input order both for the groups themselves and for
124
- * members within each group.
125
- *
126
- * Pulled out of {@link groupByAncestor} to keep that function's CRAP
127
- * under the v6 ceiling.
128
- *
129
- * @param {Array<number>} parents
130
- * @param {Map<number, Set<number>>} ancestorsByParent
131
- * @returns {Array<Array<number>>}
132
- */
133
- function unionFindByAncestor(parents, ancestorsByParent) {
134
- const parentIndex = new Map();
135
- parents.forEach((p, i) => {
136
- parentIndex.set(p, i);
137
- });
138
- const uf = parents.map((_, i) => i);
139
- const find = (i) => {
140
- while (uf[i] !== i) {
141
- uf[i] = uf[uf[i]];
142
- i = uf[i];
143
- }
144
- return i;
145
- };
146
- const union = (a, b) => {
147
- const ra = find(a);
148
- const rb = find(b);
149
- if (ra !== rb) uf[ra] = rb;
150
- };
151
-
152
- // For each ancestor id, collect parents whose chain hits it; union them.
153
- const ancestorToParents = new Map();
154
- for (const [parentId, chain] of ancestorsByParent) {
155
- for (const ancestorId of chain) {
156
- if (!ancestorToParents.has(ancestorId)) {
157
- ancestorToParents.set(ancestorId, []);
158
- }
159
- ancestorToParents.get(ancestorId).push(parentId);
160
- }
161
- }
162
- for (const sharing of ancestorToParents.values()) {
163
- if (sharing.length < 2) continue;
164
- const first = parentIndex.get(sharing[0]);
165
- for (let i = 1; i < sharing.length; i++) {
166
- union(first, parentIndex.get(sharing[i]));
167
- }
168
- }
169
-
170
- // Bucket parents by representative, preserving first-seen order for
171
- // both groups and within-group ordering.
172
- const repToGroup = new Map();
173
- const groupOrder = [];
174
- for (const parentId of parents) {
175
- const rep = find(parentIndex.get(parentId));
176
- if (!repToGroup.has(rep)) {
177
- repToGroup.set(rep, []);
178
- groupOrder.push(rep);
179
- }
180
- repToGroup.get(rep).push(parentId);
181
- }
182
-
183
- return groupOrder.map((rep) => repToGroup.get(rep));
184
- }
185
-
186
- /**
187
- * Dispatches cascade work across disjoint shared-ancestor groups in
188
- * parallel while running each within-group parent sequentially in input
189
- * order. Per-parent output is captured into a buffered logger so the
190
- * visible log stream is byte-identical to a serial baseline; the buffer
191
- * is flushed to `flushLogger` in the original `parsedParents` order
192
- * after every group resolves.
193
- *
194
- * The actual per-parent work is supplied by `processParent` so this
195
- * helper stays free of cascade-specific dependencies — its only job is
196
- * the parallel-dispatch + ordered-flush scaffolding.
197
- *
198
- * @template R
199
- * @param {Object} args
200
- * @param {Array<number>} args.parsedParents - Parent ids in their
201
- * original input order. Drives both the group-membership lookup and
202
- * the post-dispatch log flush order.
203
- * @param {Array<Array<number>>} args.groups - Disjoint groups returned
204
- * by {@link groupByAncestor}.
205
- * @param {(parentId: number, bufferedLogger: object) => Promise<R>} args.processParent
206
- * Per-parent worker. Receives the parent id and a buffered logger.
207
- * Its resolved value is collected into `args.parsedParents`-ordered
208
- * results.
209
- * @param {{ debug: Function, info: Function, warn: Function, error: Function }} args.flushLogger
210
- * Real logger that receives the buffered output after dispatch.
211
- * @returns {Promise<Array<R>>} per-parent results in `parsedParents`
212
- * order.
213
- */
214
- export async function dispatchCascadeGroups({
215
- parsedParents,
216
- groups,
217
- processParent,
218
- flushLogger,
219
- }) {
220
- const parentLoggers = new Map();
221
- const parentResults = new Map();
222
- for (const parentId of parsedParents) {
223
- parentLoggers.set(parentId, createBufferedLogger());
224
- }
225
-
226
- await Promise.all(
227
- groups.map(async (group) => {
228
- for (const parentId of group) {
229
- const logger = parentLoggers.get(parentId);
230
- const result = await processParent(parentId, logger);
231
- parentResults.set(parentId, result);
232
- }
233
- }),
234
- );
235
-
236
- const results = [];
237
- for (const parentId of parsedParents) {
238
- const lg = parentLoggers.get(parentId);
239
- if (lg) {
240
- for (const entry of lg.buffer) {
241
- flushLogger[entry.level](entry.message);
242
- }
243
- }
244
- const result = parentResults.get(parentId);
245
- if (result !== undefined) results.push(result);
246
- }
247
- return results;
248
- }
249
-
250
- /**
251
- * Buffered logger shaped like the public `Logger` surface. Stores every
252
- * emitted line in `buffer[]` instead of writing to the console. Callers
253
- * flush the buffer to a real logger after the buffered region completes
254
- * so the visible log output is byte-identical to a serial run.
255
- *
256
- * @returns {{ buffer: Array<{ level: 'debug'|'info'|'warn'|'error', message: string }>, debug: Function, info: Function, warn: Function, error: Function }}
257
- */
258
- export function createBufferedLogger() {
259
- const buffer = [];
260
- return {
261
- buffer,
262
- debug(message) {
263
- buffer.push({ level: 'debug', message });
264
- },
265
- info(message) {
266
- buffer.push({ level: 'info', message });
267
- },
268
- warn(message) {
269
- buffer.push({ level: 'warn', message });
270
- },
271
- error(message) {
272
- buffer.push({ level: 'error', message });
273
- },
274
- };
275
- }
@@ -1,69 +0,0 @@
1
- /**
2
- * progress-reporter.js — facade module for the /epic-deliver progress
3
- * narrative. Story #1847 split the original 1158-LOC monolith into three
4
- * sibling sub-modules under `progress-reporter/`:
5
- *
6
- * - `composition.js` — structured-comment body builders and the pure
7
- * rendering helpers (the legacy ProgressReporter class used these).
8
- * - `transport.js` — the curated webhook emit surface (epic-started,
9
- * epic-progress, epic-blocked, epic-unblocked).
10
- * - `signals.js` — pure parse/aggregate over `story-run-progress` and
11
- * `phase-timings` structured comments + the shared state lookup
12
- * tables (PHASE_TO_STATE, PHASE_ORDER, STATE_EMOJI).
13
- *
14
- * Epic #2646 Story C (Task #2699) — the tick-based polling
15
- * `ProgressReporter` class that used to live here was deleted in favour
16
- * of the bus-driven `lifecycle/listeners/progress-reporter.js` which
17
- * already consumes `story.dispatch.end` + `wave.end` to compose the
18
- * `epic-run-progress` body. The webhook helpers and parse/aggregate
19
- * exports remain at this path so existing importers
20
- * (`epic-execute-record-wave.js`, `wave-record-notifications.js`,
21
- * `crap-remediation-1641.test.js`) keep resolving — only the periodic
22
- * emission shell went away.
23
- */
24
-
25
- import {
26
- deriveState as deriveStateFromComposition,
27
- renderProgressBody as renderProgressBodyFromComposition,
28
- truncate as truncateFromComposition,
29
- upsertEpicRunProgress as upsertEpicRunProgressFromComposition,
30
- } from './progress-reporter/composition.js';
31
- import {
32
- aggregatePhaseTimings as aggregatePhaseTimingsFromSignals,
33
- EPIC_RUN_PROGRESS_TYPE as EPIC_RUN_PROGRESS_TYPE_FROM_SIGNALS,
34
- PHASE_TIMINGS_TYPE as PHASE_TIMINGS_TYPE_FROM_SIGNALS,
35
- parsePhaseTimingsComment as parsePhaseTimingsCommentFromSignals,
36
- parseStoryRunProgressComment as parseStoryRunProgressCommentFromSignals,
37
- phaseToState as phaseToStateFromSignals,
38
- renderPhaseTimingsSection as renderPhaseTimingsSectionFromSignals,
39
- STORY_RUN_PROGRESS_TYPE as STORY_RUN_PROGRESS_TYPE_FROM_SIGNALS,
40
- } from './progress-reporter/signals.js';
41
- import {
42
- EPIC_PROGRESS_EVENT as EPIC_PROGRESS_EVENT_FROM_TRANSPORT,
43
- emitEpicBlocked as emitEpicBlockedFromTransport,
44
- emitEpicProgress as emitEpicProgressFromTransport,
45
- emitEpicStarted as emitEpicStartedFromTransport,
46
- emitEpicUnblocked as emitEpicUnblockedFromTransport,
47
- } from './progress-reporter/transport.js';
48
-
49
- // Re-exports — sub-module surfaces are aliased back to the parent path so
50
- // existing imports (epic-execute-record-wave.js,
51
- // wave-record-notifications.js) keep resolving.
52
- export const EPIC_RUN_PROGRESS_TYPE = EPIC_RUN_PROGRESS_TYPE_FROM_SIGNALS;
53
- export const PHASE_TIMINGS_TYPE = PHASE_TIMINGS_TYPE_FROM_SIGNALS;
54
- export const STORY_RUN_PROGRESS_TYPE = STORY_RUN_PROGRESS_TYPE_FROM_SIGNALS;
55
- export const EPIC_PROGRESS_EVENT = EPIC_PROGRESS_EVENT_FROM_TRANSPORT;
56
- export const emitEpicProgress = emitEpicProgressFromTransport;
57
- export const emitEpicStarted = emitEpicStartedFromTransport;
58
- export const emitEpicBlocked = emitEpicBlockedFromTransport;
59
- export const emitEpicUnblocked = emitEpicUnblockedFromTransport;
60
- export const parseStoryRunProgressComment =
61
- parseStoryRunProgressCommentFromSignals;
62
- export const parsePhaseTimingsComment = parsePhaseTimingsCommentFromSignals;
63
- export const aggregatePhaseTimings = aggregatePhaseTimingsFromSignals;
64
- export const renderPhaseTimingsSection = renderPhaseTimingsSectionFromSignals;
65
- export const phaseToState = phaseToStateFromSignals;
66
- export const upsertEpicRunProgress = upsertEpicRunProgressFromComposition;
67
- export const deriveState = deriveStateFromComposition;
68
- export const renderProgressBody = renderProgressBodyFromComposition;
69
- export const truncate = truncateFromComposition;
@@ -1,137 +0,0 @@
1
- /**
2
- * lib/orchestration/reconciler.js — Ticket Hierarchy Reconciliation
3
- */
4
-
5
- import { Logger } from '../Logger.js';
6
- import { AGENT_LABELS, TYPE_LABELS } from '../label-constants.js';
7
- import { concurrentMap } from '../util/concurrent-map.js';
8
- import { STATE_LABELS } from './ticketing.js';
9
-
10
- const AGENT_DONE_LABEL = STATE_LABELS.DONE;
11
-
12
- // Inlined parent-id parser. The reconciler only needs the direct parent
13
- // reference scraped from a ticket body's `parent: #N` trailer; pulling the
14
- // helper inline keeps reconciler.js self-contained for the 3-tier
15
- // hierarchy walk (Stories → Features).
16
- const PARENT_ID_PATTERN = /^parent:\s*#(\d+)/m;
17
-
18
- function parseParentIdFromBody(body) {
19
- const match = (body ?? '').match(PARENT_ID_PATTERN);
20
- return match ? Number.parseInt(match[1], 10) : null;
21
- }
22
-
23
- // Cap=4 — bounded parallelism for ticket-update fan-outs. Reconciliation
24
- // iterates an Epic-sized set of independent GitHub mutations; cap matches
25
- // the established pattern across the orchestration layer (wave-gate,
26
- // progress-reporter, sub-issue link reconcile) and stays well under the
27
- // secondary rate-limit ceiling observed for issue PATCHes.
28
- const RECONCILE_CONCURRENCY = 4;
29
-
30
- /**
31
- * Reconcile the ticket hierarchy bottom-up (Stories → Features).
32
- *
33
- * Walks every Story and Feature under the Epic; if all children of a
34
- * container are done, closes the container and applies `agent::done`.
35
- *
36
- * Epic auto-closure is intentionally excluded — Epics close only through
37
- * the formal `/epic-deliver` workflow.
38
- *
39
- * Per-ticket provider failures are logged and swallowed so a single bad
40
- * ticket cannot halt reconciliation across the rest of the graph.
41
- *
42
- * @param {import('../ITicketingProvider.js').ITicketingProvider} provider Ticketing provider.
43
- * @param {number} _epicId Epic id (reserved — currently unused; kept for call-site stability).
44
- * @param {object} _epic Epic ticket record (reserved — currently unused).
45
- * @param {object[]} allTickets Every ticket under the Epic.
46
- * @param {boolean} dryRun When true, mutate nothing.
47
- * @returns {Promise<void>}
48
- */
49
- export async function reconcileHierarchy(
50
- provider,
51
- _epicId,
52
- _epic,
53
- allTickets,
54
- dryRun,
55
- ) {
56
- const ticketMap = new Map(allTickets.map((t) => [t.id, t]));
57
-
58
- const childrenOf = new Map();
59
- for (const ticket of allTickets) {
60
- const parentId = parseParentIdFromBody(ticket.body);
61
- if (parentId != null) {
62
- if (!childrenOf.has(parentId)) childrenOf.set(parentId, []);
63
- childrenOf.get(parentId).push(ticket.id);
64
- }
65
- }
66
-
67
- function isDone(ticketId) {
68
- const t = ticketMap.get(ticketId);
69
- if (!t) return false;
70
- return (
71
- t.state === 'closed' ||
72
- (t.labelSet ?? new Set(t.labels)).has(AGENT_DONE_LABEL)
73
- );
74
- }
75
-
76
- function shouldClose(id) {
77
- const ticket = ticketMap.get(id);
78
- if (!ticket || ticket.state === 'closed') return null;
79
- const children = childrenOf.get(id) ?? [];
80
- if (children.length === 0) return null;
81
- if (!children.every((cid) => isDone(cid))) return null;
82
- return ticket;
83
- }
84
-
85
- async function applyClose(id, typeName, ticket) {
86
- try {
87
- await provider.updateTicket(id, {
88
- labels: {
89
- add: [AGENT_DONE_LABEL],
90
- remove: [AGENT_LABELS.READY, AGENT_LABELS.EXECUTING],
91
- },
92
- state: 'closed',
93
- state_reason: 'completed',
94
- });
95
- ticket.state = 'closed';
96
- Logger.info(`✅ ${typeName} #${id} closed and marked agent::done.`);
97
- } catch (err) {
98
- Logger.warn(`Failed to close ${typeName} #${id}: ${err.message}`);
99
- }
100
- }
101
-
102
- async function maybeClose(id, typeName) {
103
- const ticket = shouldClose(id);
104
- if (!ticket) return;
105
- Logger.info(
106
- `All children of ${typeName} #${id} "${ticket.title}" are done. Closing...`,
107
- );
108
- if (dryRun) {
109
- Logger.info(
110
- `[DRY-RUN] Would close ${typeName} #${id} and set agent::done.`,
111
- );
112
- ticket.state = 'closed';
113
- return;
114
- }
115
- await applyClose(id, typeName, ticket);
116
- }
117
-
118
- const storyIds = allTickets
119
- .filter((t) => (t.labelSet ?? new Set(t.labels)).has(TYPE_LABELS.STORY))
120
- .map((t) => t.id);
121
- const featureIds = allTickets
122
- .filter((t) => (t.labelSet ?? new Set(t.labels)).has(TYPE_LABELS.FEATURE))
123
- .map((t) => t.id);
124
-
125
- // cap=4 — Stories are container leaves of this reconcile (their children
126
- // are Tasks already settled by reconcileClosedTasks); independent close
127
- // mutations can fan out without ordering. Features stay sequential because
128
- // a Feature may parent another Feature, and bottom-up close depends on
129
- // child-Feature state already being mutated in the same pass.
130
- await concurrentMap(storyIds, (id) => maybeClose(id, 'Story'), {
131
- concurrency: RECONCILE_CONCURRENCY,
132
- });
133
- for (const id of featureIds) await maybeClose(id, 'Feature');
134
-
135
- // EXCLUSION: Epic auto-closure removed.
136
- // The Epic ticket now stays open until the formal /epic-deliver workflow is executed.
137
- }