mandrel 1.93.0 → 2.0.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 (463) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/acceptance-critic.md +129 -0
  3. package/.agents/agents/story-worker.md +161 -0
  4. package/.agents/docs/SDLC.md +489 -1285
  5. package/.agents/docs/agentrc-reference.json +177 -67
  6. package/.agents/docs/configuration.md +108 -136
  7. package/.agents/docs/execution-reference.md +44 -22
  8. package/.agents/docs/quality-gates.md +13 -19
  9. package/.agents/docs/workflows.md +3 -3
  10. package/.agents/instructions.md +107 -108
  11. package/.agents/rules/ci-remediation.md +8 -12
  12. package/.agents/rules/git-conventions-reference.md +224 -0
  13. package/.agents/rules/git-conventions.md +42 -223
  14. package/.agents/rules/security-baseline.md +5 -0
  15. package/.agents/rules/testing-standards.md +106 -13
  16. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  17. package/.agents/schemas/agentrc.schema.json +71 -201
  18. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  20. package/.agents/schemas/risk-verdict.schema.json +0 -13
  21. package/.agents/scripts/acceptance-eval.js +62 -18
  22. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  23. package/.agents/scripts/analyze-execution.js +1 -1
  24. package/.agents/scripts/audit-to-stories.js +7 -7
  25. package/.agents/scripts/boot-sweep.js +1 -1
  26. package/.agents/scripts/check-context-budget.js +62 -5
  27. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  28. package/.agents/scripts/check-prepush-recovery.js +1 -1
  29. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  30. package/.agents/scripts/diagnose-friction.js +0 -6
  31. package/.agents/scripts/lib/Logger.js +6 -10
  32. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  33. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  34. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  35. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  36. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  37. package/.agents/scripts/lib/baselines/reader.js +1 -6
  38. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  39. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  40. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
  41. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  42. package/.agents/scripts/lib/checks/index.js +2 -1
  43. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  44. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  45. package/.agents/scripts/lib/cli-args.js +16 -7
  46. package/.agents/scripts/lib/close-validation/gates.js +160 -22
  47. package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
  48. package/.agents/scripts/lib/config/ci.js +6 -31
  49. package/.agents/scripts/lib/config/delivery-routing.js +103 -0
  50. package/.agents/scripts/lib/config/explain.js +57 -36
  51. package/.agents/scripts/lib/config/limits.js +17 -58
  52. package/.agents/scripts/lib/config/paths.js +0 -2
  53. package/.agents/scripts/lib/config/quality.js +1 -1
  54. package/.agents/scripts/lib/config/runners.js +17 -50
  55. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  56. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  57. package/.agents/scripts/lib/config-resolver.js +3 -8
  58. package/.agents/scripts/lib/config-settings-schema-delivery.js +46 -136
  59. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -14
  60. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  61. package/.agents/scripts/lib/dependency-parser.js +3 -2
  62. package/.agents/scripts/lib/doc-tiers.js +39 -4
  63. package/.agents/scripts/lib/duplicate-search.js +211 -41
  64. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  65. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  66. package/.agents/scripts/lib/framework-version.js +2 -3
  67. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  68. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  69. package/.agents/scripts/lib/git-utils.js +32 -6
  70. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  71. package/.agents/scripts/lib/label-constants.js +10 -23
  72. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  73. package/.agents/scripts/lib/observability/active-story-env.js +112 -3
  74. package/.agents/scripts/lib/observability/hook-heartbeat.js +187 -0
  75. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  76. package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
  77. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  78. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
  79. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
  80. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  81. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +273 -0
  82. package/.agents/scripts/lib/orchestration/ceremony-routing.js +204 -0
  83. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  84. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  85. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  86. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  87. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  88. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  89. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  90. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  91. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  92. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  93. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  94. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  95. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  96. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  97. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  98. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
  99. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  100. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  101. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  102. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  103. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  104. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  105. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  106. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  107. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  108. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +14 -14
  109. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  110. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  111. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  112. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  113. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  114. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  115. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  116. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  117. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  118. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  119. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  120. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  121. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  122. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  123. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  124. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  125. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  126. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
  127. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  128. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  129. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  130. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  131. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  132. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  133. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  134. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  135. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  136. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  137. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  138. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  139. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  140. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  141. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  142. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  143. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  144. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  145. package/.agents/scripts/lib/orchestration/ticket-validator.js +3 -8
  146. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  147. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  148. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  149. package/.agents/scripts/lib/planning-corpus.js +16 -11
  150. package/.agents/scripts/lib/preflight-runner.js +2 -2
  151. package/.agents/scripts/lib/provider-factory.js +1 -1
  152. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  153. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  154. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  155. package/.agents/scripts/lib/story-adjacency.js +11 -14
  156. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  157. package/.agents/scripts/lib/story-plan.js +2 -4
  158. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  159. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  160. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  161. package/.agents/scripts/lib/validation-evidence.js +1 -1
  162. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  163. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  164. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  165. package/.agents/scripts/lint-issue-body.js +71 -40
  166. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  167. package/.agents/scripts/notify.js +4 -3
  168. package/.agents/scripts/plan-context.js +64 -74
  169. package/.agents/scripts/plan-persist.js +121 -280
  170. package/.agents/scripts/plan-run-epilogue.js +97 -0
  171. package/.agents/scripts/post-structured-comment.js +38 -0
  172. package/.agents/scripts/providers/github/issues.js +17 -33
  173. package/.agents/scripts/providers/github/mappers.js +0 -12
  174. package/.agents/scripts/providers/github/tickets.js +2 -5
  175. package/.agents/scripts/resolve-plan-run.js +117 -0
  176. package/.agents/scripts/signals-view.js +24 -19
  177. package/.agents/scripts/single-story-close.js +11 -14
  178. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  179. package/.agents/scripts/single-story-init.js +29 -20
  180. package/.agents/scripts/stories-wave-tick.js +6 -6
  181. package/.agents/scripts/story-plan.js +26 -47
  182. package/.agents/scripts/sync-claude-agents.js +165 -0
  183. package/.agents/scripts/update-ticket-state.js +37 -15
  184. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  185. package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
  186. package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
  187. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
  188. package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
  189. package/.agents/skills/core/idea-refinement/SKILL.md +8 -14
  190. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
  191. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  192. package/.agents/skills/skills.index.json +8 -418
  193. package/.agents/starter-agentrc.json +0 -5
  194. package/.agents/templates/agent-protocol.md +9 -10
  195. package/.agents/workflows/audit-architecture.md +3 -3
  196. package/.agents/workflows/audit-clean-code.md +3 -3
  197. package/.agents/workflows/audit-dependencies.md +3 -3
  198. package/.agents/workflows/audit-devops.md +3 -3
  199. package/.agents/workflows/audit-documentation.md +5 -5
  200. package/.agents/workflows/audit-lighthouse.md +3 -3
  201. package/.agents/workflows/audit-navigability.md +3 -2
  202. package/.agents/workflows/audit-performance.md +3 -3
  203. package/.agents/workflows/audit-privacy.md +3 -3
  204. package/.agents/workflows/audit-quality.md +3 -3
  205. package/.agents/workflows/audit-security.md +3 -3
  206. package/.agents/workflows/audit-seo.md +3 -3
  207. package/.agents/workflows/audit-sre.md +3 -3
  208. package/.agents/workflows/audit-to-stories.md +20 -20
  209. package/.agents/workflows/audit-ux-ui.md +3 -3
  210. package/.agents/workflows/deliver.md +122 -131
  211. package/.agents/workflows/git-cleanup.md +3 -4
  212. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  213. package/.agents/workflows/helpers/acceptance-self-eval.md +52 -40
  214. package/.agents/workflows/helpers/code-review.md +70 -193
  215. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  216. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  217. package/.agents/workflows/helpers/diagnose.md +10 -10
  218. package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
  219. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  220. package/.agents/workflows/helpers/signals.md +16 -16
  221. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  222. package/.agents/workflows/mandrel-update.md +3 -2
  223. package/.agents/workflows/plan.md +112 -145
  224. package/.agents/workflows/qa-assist.md +24 -30
  225. package/.agents/workflows/qa-explore.md +29 -38
  226. package/.agents/workflows/qa-run.md +2 -2
  227. package/README.md +9 -8
  228. package/docs/CHANGELOG.md +46 -0
  229. package/lib/cli/registry.js +95 -0
  230. package/lib/migrations/index.js +6 -5
  231. package/package.json +5 -3
  232. package/.agents/personas/architect.md +0 -113
  233. package/.agents/personas/devops-engineer.md +0 -38
  234. package/.agents/personas/engineer-mobile.md +0 -120
  235. package/.agents/personas/engineer-web.md +0 -111
  236. package/.agents/personas/engineer.md +0 -119
  237. package/.agents/personas/product.md +0 -94
  238. package/.agents/personas/project-manager.md +0 -114
  239. package/.agents/personas/qa-engineer.md +0 -95
  240. package/.agents/personas/refactorer.md +0 -113
  241. package/.agents/personas/security-engineer.md +0 -112
  242. package/.agents/personas/sre.md +0 -86
  243. package/.agents/personas/technical-writer.md +0 -101
  244. package/.agents/personas/ux-designer.md +0 -95
  245. package/.agents/schemas/dispatch-manifest.json +0 -232
  246. package/.agents/schemas/epic-spec.schema.json +0 -153
  247. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  248. package/.agents/scripts/dispatcher.js +0 -295
  249. package/.agents/scripts/epic-audit-prepare.js +0 -497
  250. package/.agents/scripts/epic-audit-recheck.js +0 -274
  251. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  252. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  253. package/.agents/scripts/epic-deliver-prepare.js +0 -590
  254. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  255. package/.agents/scripts/epic-plan-clarity.js +0 -211
  256. package/.agents/scripts/epic-plan-decompose.js +0 -54
  257. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  258. package/.agents/scripts/epic-plan-spec.js +0 -64
  259. package/.agents/scripts/epic-reconcile.js +0 -625
  260. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  261. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  262. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  263. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  264. package/.agents/scripts/lib/config/preflight.js +0 -58
  265. package/.agents/scripts/lib/config/retro.js +0 -77
  266. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  267. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  268. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  269. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -660
  270. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  271. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  272. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  273. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  274. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  275. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  276. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  277. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  278. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  279. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  280. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  281. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  282. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  283. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  284. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  285. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  286. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  287. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  288. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -388
  289. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  290. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  291. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  292. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  293. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  294. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  295. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  296. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  297. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  298. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  299. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  300. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  301. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  302. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  303. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  304. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  305. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  306. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  307. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  308. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  309. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  310. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  311. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  313. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -384
  314. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  315. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  316. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  317. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -278
  318. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  319. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  320. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  321. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  322. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  323. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  324. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  325. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  326. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  327. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  328. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  329. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  330. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  331. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  332. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  333. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  334. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  335. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
  336. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  337. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  338. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  339. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  340. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  341. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  342. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  343. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  344. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  345. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  346. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  347. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  348. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  349. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  350. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  351. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  352. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  353. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  354. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  355. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  356. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  357. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  358. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  359. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  360. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  361. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -301
  362. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  363. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  364. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  365. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  366. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  367. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  368. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  369. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  370. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  371. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  372. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  373. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  374. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  375. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  376. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  377. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  378. package/.agents/scripts/lib/spec/index.js +0 -36
  379. package/.agents/scripts/lib/spec/loader.js +0 -425
  380. package/.agents/scripts/lib/spec/state.js +0 -208
  381. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  382. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  383. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  384. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  385. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  386. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  387. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  388. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  389. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  390. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  391. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  392. package/.agents/scripts/lifecycle-emit.js +0 -510
  393. package/.agents/scripts/plan-critics.js +0 -199
  394. package/.agents/scripts/retro-run.js +0 -218
  395. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  396. package/.agents/scripts/story-close.js +0 -294
  397. package/.agents/scripts/story-init.js +0 -599
  398. package/.agents/scripts/story-phase.js +0 -369
  399. package/.agents/scripts/wave-tick.js +0 -335
  400. package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
  401. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
  402. package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
  403. package/.agents/skills/core/code-simplification/SKILL.md +0 -389
  404. package/.agents/skills/core/context-engineering/SKILL.md +0 -309
  405. package/.agents/skills/core/context-engineering/examples.md +0 -58
  406. package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
  407. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  408. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  409. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  410. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  411. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  412. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  413. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -413
  414. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  415. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
  416. package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
  417. package/.agents/skills/core/idea-refinement/examples.md +0 -437
  418. package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
  419. package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
  420. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
  421. package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
  422. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
  423. package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
  424. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
  425. package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
  426. package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
  427. package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
  428. package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
  429. package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
  430. package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
  431. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
  432. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
  433. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
  434. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
  435. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
  436. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
  437. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
  438. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
  439. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
  440. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
  441. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
  442. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
  443. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
  444. package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
  445. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
  446. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
  447. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
  448. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
  449. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
  450. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
  451. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
  452. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
  453. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -534
  454. package/.agents/workflows/helpers/deliver-epic.md +0 -955
  455. package/.agents/workflows/helpers/deliver-stories.md +0 -440
  456. package/.agents/workflows/helpers/epic-audit.md +0 -189
  457. package/.agents/workflows/helpers/epic-deliver-story.md +0 -427
  458. package/.agents/workflows/helpers/epic-testing.md +0 -125
  459. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  460. package/.agents/workflows/helpers/plan-epic.md +0 -351
  461. package/.agents/workflows/helpers/plan-story.md +0 -251
  462. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  463. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -2,10 +2,12 @@
2
2
  * phases/code-review.js — Story-scope code-review phase
3
3
  * (Story #2840, Epic #2815 — Pluggable Code Review + Story-Level Review).
4
4
  *
5
- * Sits between the close-validation gate chain and the merge into
6
- * `epic/<id>` inside `runStoryCloseLocked` (locked-pipeline.js). The
7
- * configured ReviewProvider runs against the
8
- * `epic/<id>`…`story-<id>` diff. The unified `verification-results`
5
+ * Sits between the close-validation gate chain and merge in the deleted
6
+ * pre-v2 Epic close path (`runStoryCloseLocked` / `locked-pipeline.js`,
7
+ * merge target `epic/<id>`). The v2 `/deliver` path
8
+ * (`single-story-close.js`) reviews `main`…`story-<id>` instead. The
9
+ * configured ReviewProvider runs against the supplied base…head diff. The
10
+ * unified `verification-results`
9
11
  * structured comment is posted to the Story issue (default
10
12
  * `commentTargetId === ticketId` inside `runCodeReview`). Outcomes:
11
13
  *
@@ -39,7 +41,7 @@ import {
39
41
  import { gitSpawn } from '../../../git-utils.js';
40
42
  import { Logger } from '../../../Logger.js';
41
43
  import { runCodeReview } from '../../code-review.js';
42
- import { emitBlockedCloseResult } from '../merge-runner.js';
44
+ import { emitBlockedCloseResult } from '../emit-blocked.js';
43
45
 
44
46
  /**
45
47
  * The review depth the Story-scope local-lens pass runs at. Shift-left
@@ -282,17 +284,18 @@ export async function runStoryReviewCore({
282
284
  }
283
285
 
284
286
  /**
285
- * Run a Story-scope code review against the `epic/<id>`…`story-<id>`
286
- * diff and post the structured `code-review` comment to the Story
287
- * issue. Returns `{ blocked }` where `blocked` is either `null`
288
- * (caller proceeds to merge) or the blocked-envelope (caller returns
289
- * it verbatim and the CLI exits 1).
287
+ * Run a Story-scope code review against the supplied base…head diff
288
+ * (v2: `main`…`story-<id>` via `single-story-close.js`; pre-v2 Epic
289
+ * close: `epic/<id>`…`story-<id>`) and post the structured
290
+ * `code-review` comment to the Story issue. Returns `{ blocked }` where
291
+ * `blocked` is either `null` (caller proceeds to open/merge the PR) or the
292
+ * blocked-envelope (caller returns it verbatim and the CLI exits 1).
290
293
  *
291
294
  * The optional `planningRisk` envelope (Story #3940) is the parent Epic's
292
295
  * judged risk, read best-effort off the `epic-plan-state` checkpoint by the
293
296
  * locked pipeline. It is forwarded into `runCodeReview` so the review depth is
294
- * resolved from BOTH the Epic-judged risk and the Story's own
295
- * `epic/<id>...story-<id>` changed-file count — a small Story under a
297
+ * resolved from BOTH the parent Epic's judged risk (pre-v2) and the Story's own
298
+ * base…head changed-file count — a small Story under a
296
299
  * high-risk Epic still earns `deep`, a small Story under a low-risk Epic gets
297
300
  * `light`, and an absent envelope resolves `standard` (today's behaviour).
298
301
  * Depth is input-only: it never changes `{ blocked }` or the posted comment.
@@ -0,0 +1,237 @@
1
+ /**
2
+ * story-follow-ups.js — capture actionable follow-ups from a landed Story.
3
+ *
4
+ * Replaces the unwired Epic retro as the default closeout for v2: after a
5
+ * Story merges, read its standalone `signals.ndjson` friction stream, compose
6
+ * routed proposals, auto-file follow-up issues (when enabled), and upsert a
7
+ * structured `follow-ups` comment on the Story.
8
+ *
9
+ * @module lib/orchestration/story-follow-ups
10
+ */
11
+
12
+ import { graduateRetroProposals } from '../feedback-loop/retro-proposals-graduator.js';
13
+ import { DEFAULT_FRAMEWORK_REPO } from '../github/framework-repo.js';
14
+ import { Logger } from '../Logger.js';
15
+ import { forEachLine } from '../observability/signals-writer.js';
16
+ import { composeRoutedProposals } from './retro-proposals.js';
17
+ import { upsertStructuredComment } from './ticketing.js';
18
+
19
+ export const FOLLOW_UPS_COMMENT_TYPE = 'follow-ups';
20
+
21
+ /**
22
+ * @param {object} [config]
23
+ * @returns {{ frameworkRepo: string, consumerRepo: string, currentRepo: { owner: string, repo: string } }}
24
+ */
25
+ export function resolveFollowUpRepos(config) {
26
+ const owner =
27
+ typeof config?.github?.owner === 'string' ? config.github.owner.trim() : '';
28
+ const repo =
29
+ typeof config?.github?.repo === 'string' ? config.github.repo.trim() : '';
30
+ const consumerRepo =
31
+ owner && repo ? `${owner}/${repo}` : DEFAULT_FRAMEWORK_REPO;
32
+ const frameworkRepo =
33
+ typeof config?.github?.frameworkRepo === 'string' &&
34
+ config.github.frameworkRepo.trim()
35
+ ? config.github.frameworkRepo.trim()
36
+ : DEFAULT_FRAMEWORK_REPO;
37
+ const [cOwner, cRepo] = consumerRepo.split('/');
38
+ return {
39
+ frameworkRepo,
40
+ consumerRepo,
41
+ currentRepo: {
42
+ owner: cOwner || 'unknown',
43
+ repo: cRepo || 'unknown',
44
+ },
45
+ };
46
+ }
47
+
48
+ /**
49
+ * @param {number} storyId
50
+ * @param {object} [config]
51
+ * @returns {Promise<Array<{ category: string, source: 'framework'|'consumer' }>>}
52
+ */
53
+ export async function gatherStoryFrictionSignals(storyId, config) {
54
+ const signals = [];
55
+ await forEachLine(
56
+ null,
57
+ storyId,
58
+ (parsed) => {
59
+ if (!parsed || typeof parsed !== 'object') return;
60
+ const kind = parsed.kind;
61
+ if (kind !== 'friction' && kind !== undefined) {
62
+ // Prefer friction records; also accept category-bearing rows.
63
+ }
64
+ const category =
65
+ typeof parsed.category === 'string' ? parsed.category.trim() : '';
66
+ if (!category) return;
67
+ const source = parsed.source === 'framework' ? 'framework' : 'consumer';
68
+ signals.push({ category, source });
69
+ },
70
+ config,
71
+ );
72
+ return signals;
73
+ }
74
+
75
+ /**
76
+ * @param {{
77
+ * storyId: number,
78
+ * proposals: object,
79
+ * graduated: object,
80
+ * }} args
81
+ * @returns {string}
82
+ */
83
+ export function buildFollowUpsCommentBody({ storyId, proposals, graduated }) {
84
+ const filed = Array.isArray(graduated?.filed) ? graduated.filed : [];
85
+ const framework = proposals?.framework ?? [];
86
+ const consumer = proposals?.consumer ?? [];
87
+ const discarded = proposals?.discarded ?? [];
88
+ const lines = [
89
+ '### follow-ups',
90
+ '',
91
+ `Actionable follow-ups captured from Story #${storyId} after merge.`,
92
+ '',
93
+ ];
94
+ if (filed.length > 0) {
95
+ lines.push('**Filed**');
96
+ for (const item of filed) {
97
+ lines.push(
98
+ `- ${item.source}: ${item.title}${item.url ? ` — ${item.url}` : ''}`,
99
+ );
100
+ }
101
+ lines.push('');
102
+ }
103
+ if (framework.length + consumer.length > 0 && filed.length === 0) {
104
+ lines.push('**Actionable (not auto-filed)**');
105
+ for (const item of [...framework, ...consumer]) {
106
+ lines.push(`- ${item.source}: ${item.title}`);
107
+ lines.push('');
108
+ lines.push('```bash');
109
+ lines.push(item.command);
110
+ lines.push('```');
111
+ }
112
+ lines.push('');
113
+ }
114
+ if (discarded.length > 0) {
115
+ lines.push('**Single-occurrence (not filed)**');
116
+ for (const item of discarded) {
117
+ lines.push(`- ${item.source}: \`${item.category}\` ×${item.occurrences}`);
118
+ }
119
+ lines.push('');
120
+ }
121
+ if (
122
+ filed.length === 0 &&
123
+ framework.length === 0 &&
124
+ consumer.length === 0 &&
125
+ discarded.length === 0
126
+ ) {
127
+ lines.push('_No friction signals — nothing to follow up._');
128
+ lines.push('');
129
+ }
130
+ lines.push('```json');
131
+ lines.push(
132
+ JSON.stringify(
133
+ {
134
+ storyId,
135
+ framework: framework.map((i) => i.category),
136
+ consumer: consumer.map((i) => i.category),
137
+ discarded: discarded.map((i) => i.category),
138
+ filed: filed.map((i) => ({
139
+ category: i.category,
140
+ url: i.url ?? null,
141
+ })),
142
+ },
143
+ null,
144
+ 2,
145
+ ),
146
+ );
147
+ lines.push('```');
148
+ return lines.join('\n');
149
+ }
150
+
151
+ /**
152
+ * Capture and persist Story follow-ups. Never throws — close must not fail
153
+ * because follow-up filing flaked.
154
+ *
155
+ * @param {object} args
156
+ * @param {number} args.storyId
157
+ * @param {object} args.provider
158
+ * @param {object} [args.config]
159
+ * @param {string} [args.cwd]
160
+ * @param {(tag: string, msg: string) => void} [args.progress]
161
+ * @returns {Promise<object>}
162
+ */
163
+ /**
164
+ * Capture follow-ups only when merge confirm landed (`action === 'done'`).
165
+ * One-liner seam for the confirm-merge CLI.
166
+ */
167
+ export async function captureFollowUpsAfterConfirm(confirmation, ctx) {
168
+ if (confirmation?.action !== 'done') return null;
169
+ return captureStoryFollowUps(ctx);
170
+ }
171
+
172
+ export async function captureStoryFollowUps({
173
+ storyId,
174
+ provider,
175
+ config,
176
+ cwd,
177
+ progress,
178
+ }) {
179
+ const sid = Number(storyId);
180
+ if (!Number.isInteger(sid) || sid <= 0) {
181
+ return { ok: false, reason: 'invalid-story-id' };
182
+ }
183
+ try {
184
+ const signals = await gatherStoryFrictionSignals(sid, config);
185
+ const repos = resolveFollowUpRepos(config);
186
+ const proposals = composeRoutedProposals({
187
+ anchorId: sid,
188
+ anchorKind: 'story',
189
+ frameworkRepo: repos.frameworkRepo,
190
+ consumerRepo: repos.consumerRepo,
191
+ signals,
192
+ unresolvedBlockedEvents: [],
193
+ });
194
+ const graduated = await graduateRetroProposals({
195
+ epicId: sid,
196
+ provider,
197
+ config,
198
+ currentRepo: repos.currentRepo,
199
+ frameworkRepo: (() => {
200
+ const [owner, repo] = repos.frameworkRepo.split('/');
201
+ return { owner, repo };
202
+ })(),
203
+ routedProposals: proposals,
204
+ cwd,
205
+ });
206
+ const body = buildFollowUpsCommentBody({
207
+ storyId: sid,
208
+ proposals,
209
+ graduated,
210
+ });
211
+ await upsertStructuredComment(provider, sid, FOLLOW_UPS_COMMENT_TYPE, body);
212
+ progress?.(
213
+ 'FOLLOW-UPS',
214
+ `Captured follow-ups for Story #${sid} (filed=${graduated.filed?.length ?? 0}).`,
215
+ );
216
+ return {
217
+ ok: true,
218
+ storyId: sid,
219
+ proposals,
220
+ graduated,
221
+ signalCount: signals.length,
222
+ };
223
+ } catch (err) {
224
+ Logger.warn(
225
+ `[story-follow-ups] capture failed for #${sid}: ${err?.message ?? err}`,
226
+ );
227
+ progress?.(
228
+ 'FOLLOW-UPS',
229
+ `⚠️ Follow-up capture failed (close continues): ${err?.message ?? err}`,
230
+ );
231
+ return {
232
+ ok: false,
233
+ reason: 'capture-failed',
234
+ error: String(err?.message ?? err),
235
+ };
236
+ }
237
+ }
@@ -0,0 +1,47 @@
1
+ import { Logger } from '../Logger.js';
2
+ import { AGENT_LABELS } from '../label-constants.js';
3
+ import { upsertStructuredComment } from './ticketing.js';
4
+
5
+ /**
6
+ * Fail closed when the repository remote cannot be verified. The Story is
7
+ * blocked before lease/branch/worktree mutation so a host that misses the
8
+ * result envelope cannot strand an executing Story.
9
+ */
10
+ export async function handleRemoteVerificationFailure({
11
+ provider,
12
+ storyId,
13
+ remote,
14
+ dryRun = false,
15
+ }) {
16
+ if (remote?.remoteVerified) return;
17
+ const message =
18
+ `[single-story-init] remote verification failed for Story #${storyId}: ` +
19
+ `${remote?.detail ?? 'origin is unavailable'}`;
20
+ if (!dryRun) {
21
+ try {
22
+ await upsertStructuredComment(
23
+ provider,
24
+ storyId,
25
+ 'friction',
26
+ `### Remote verification blocked delivery\n\n${message}`,
27
+ );
28
+ } catch (err) {
29
+ Logger.warn(
30
+ `[single-story-init] failed to post remote-verification friction: ${err?.message ?? err}`,
31
+ );
32
+ }
33
+ try {
34
+ await provider.updateTicket(storyId, {
35
+ labels: {
36
+ add: [AGENT_LABELS.BLOCKED],
37
+ remove: [AGENT_LABELS.READY, AGENT_LABELS.EXECUTING],
38
+ },
39
+ });
40
+ } catch (err) {
41
+ Logger.warn(
42
+ `[single-story-init] failed to block Story after remote verification: ${err?.message ?? err}`,
43
+ );
44
+ }
45
+ }
46
+ throw new Error(message);
47
+ }
@@ -0,0 +1,48 @@
1
+ import { parseFencedJsonComment } from './structured-comment-parser.js';
2
+ import { findStructuredComment } from './ticketing.js';
3
+
4
+ /**
5
+ * Read the v2 Story planning checkpoint. Missing/malformed comments degrade
6
+ * to null so unplanned Stories still receive the neutral review posture.
7
+ */
8
+ export async function readStoryPlanState({
9
+ provider,
10
+ storyId,
11
+ findCommentFn = findStructuredComment,
12
+ }) {
13
+ const comment = await findCommentFn(
14
+ provider,
15
+ Number(storyId),
16
+ 'story-plan-state',
17
+ );
18
+ const state = parseFencedJsonComment(comment);
19
+ return state && typeof state === 'object' ? state : null;
20
+ }
21
+
22
+ export async function readStoryPlanningRisk(args) {
23
+ const state = await readStoryPlanState(args);
24
+ return state?.planningRisk ?? null;
25
+ }
26
+
27
+ export async function readStoryPlanningRiskSafe(args) {
28
+ try {
29
+ return await readStoryPlanningRisk(args);
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Prefer an explicit `planningRisk` override; otherwise load the Story
37
+ * checkpoint. Callers that omit the field (or pass `undefined`) get the
38
+ * persisted plan risk; callers that pass `null` keep the neutral posture.
39
+ */
40
+ export async function resolveStoryPlanningRisk({
41
+ provider,
42
+ storyId,
43
+ planningRisk,
44
+ findCommentFn,
45
+ }) {
46
+ if (planningRisk !== undefined) return planningRisk;
47
+ return readStoryPlanningRiskSafe({ provider, storyId, findCommentFn });
48
+ }
@@ -13,9 +13,9 @@
13
13
  *
14
14
  * The renderer survives because its `{ body, payload }` output still feeds
15
15
  * two non-comment contracts: the `renderedBody` markdown the `/deliver`
16
- * and `single-story-deliver` CLIs (`story-phase.js`, the inline `story-init.js` prepare step)
17
- * relay to chat so the operator sees the phase table inline, and the snapshot
18
- * payload returned in those CLIs' JSON envelopes. `upsertStoryRunProgress`
16
+ * workflow (`helpers/deliver-story.md`, `story-phase.js`) relays to chat so
17
+ * the operator sees the phase table inline, and the snapshot payload returned
18
+ * in those CLIs' JSON envelopes. `upsertStoryRunProgress`
19
19
  * therefore renders-only: it computes the body/payload and (optionally) mirrors
20
20
  * a low-severity webhook event, but writes no GitHub comment.
21
21
  *
@@ -2,7 +2,7 @@
2
2
  * structured-comment-parser.js — shared parser for fenced-JSON structured
3
3
  * comments.
4
4
  *
5
- * Several callers (epic-runner Checkpointer, ProgressReporter
5
+ * Several callers (the deleted epic-runner Checkpointer/ProgressReporter,
6
6
  * `parseStoryRunProgressComment` / `parsePhaseTimingsComment`, wave-gate's
7
7
  * local `extractJsonBlock`) need to extract the `{...}` payload from the
8
8
  * fenced ```json``` block of a structured comment body. They had each open-
@@ -24,16 +24,14 @@
24
24
  * name at least one path-shaped token so vague verbs ("clean up",
25
25
  * "refactor") can't slip through.
26
26
  *
27
- * `body.changes` items may be either:
28
- * 1. A string bullet (legacy shape, e.g. `"src/foo.ts: extract handler"`).
29
- * 2. An object `{ path: string, assumption: enum }` (Story #2636 shape).
27
+ * `body.changes` items must be object-form `{ path: string, assumption: enum }`
28
+ * entries (Story #2636 shape). Plain string bullets are rejected at parse
29
+ * time and by this validator.
30
30
  *
31
31
  * Object-form items must declare an `assumption` ∈ `creates |
32
32
  * refactors-existing | exists | deletes`. The optional `body.references`
33
33
  * array uses the same object shape and is the home for paths the Story
34
34
  * reads but does not modify (test fixtures, sibling modules, etc.).
35
- * String-form `changes` items remain legal so legacy plans keep parsing,
36
- * but they emit a deprecation signal via `validateStoryFileAssumptions`.
37
35
  *
38
36
  * `body.verify` entries must either name a testing tier in parentheses
39
37
  * drawn from `VERIFY_TIER_VALUES` (e.g. `npm run test (unit)`) or be the
@@ -248,25 +246,17 @@ function collectChangesErrors(prefix, rawChanges) {
248
246
  return [`${prefix}: body.changes must list at least one bullet.`];
249
247
  }
250
248
  const errors = [];
251
- // An entry "names a path" when it is either a path-shaped bullet
252
- // string OR an object-form entry that passed the assumption schema.
253
- const namesPath = (c) => {
254
- if (typeof c === 'string') return bulletNamesPath(c);
255
- return isObjectPathEntry(c);
256
- };
249
+ const namesPath = (c) => isObjectPathEntry(c);
257
250
  if (changes.every((c) => !namesPath(c))) {
258
251
  errors.push(
259
- `${prefix}: body.changes bullets name no path-shaped token. Use "<path>: <verb> <object>" — e.g. "src/components/Foo.tsx: extract handleSubmit". Object-form entries may also declare { path, assumption } directly.`,
252
+ `${prefix}: body.changes must declare at least one { path, assumption } object entry.`,
260
253
  );
261
254
  }
262
255
  for (const entry of changes) {
263
256
  if (typeof entry === 'string') {
264
- const verb = vagueVerbWithoutTarget(entry);
265
- if (verb) {
266
- errors.push(
267
- `${prefix}: body.changes bullet uses vague verb "${verb}" without a named target: "${entry}".`,
268
- );
269
- }
257
+ errors.push(
258
+ `${prefix}: body.changes entry must be a { path, assumption } object; plain string bullets are no longer accepted: "${entry}".`,
259
+ );
270
260
  continue;
271
261
  }
272
262
  if (isMalformedObjectPathEntry(entry)) {
@@ -10,8 +10,7 @@ import { computeStoryReachability } from './story-reachability.js';
10
10
  *
11
11
  * The decomposer emits `body` as the canonical serialized **string**, but
12
12
  * the conflict passes (`indexConsumers`, `indexAssumptionEntries`,
13
- * `computeMissingBddScaffoldFindings`, the sibling-create scan in
14
- * `computeRegistryFindings`, and the legacy-bullet branch of
13
+ * `computeMissingBddScaffoldFindings`, and the producer path scan in
15
14
  * `collectStoryProducerPaths`) historically read `story.body` only when it
16
15
  * was already an object — so on the production string shape the
17
16
  * `implicit-cross-story-dep`, `fan-out`, registry, and `missing-bdd-scaffold`
@@ -144,71 +143,26 @@ const WRITE_IMPLYING_ASSUMPTIONS = Object.freeze(
144
143
  new Set(['creates', 'refactors-existing', 'deletes']),
145
144
  );
146
145
 
147
- /**
148
- * Extract the path-shaped head from a single legacy string-form
149
- * `body.changes` bullet.
150
- *
151
- * Conventional shape is `"<path>: <verb> <object>"`; we slice on the first
152
- * colon and return the head when it contains a slash or a dot, otherwise
153
- * `null`. Mirrors the heuristic in `ticket-validator-sizing.js` so producer
154
- * extraction and `fileCount` accounting agree on what counts as a path.
155
- *
156
- * Object-form entries (`{ path, assumption }`) are *not* handled here — they
157
- * are extracted via `collectStoryAssumptionEntries` in `indexProducers`. This
158
- * helper only understands the legacy string shape and returns `null` for any
159
- * non-string input.
160
- */
161
- function extractChangeBulletPath(bullet) {
162
- if (typeof bullet !== 'string') return null;
163
- const colonIdx = bullet.indexOf(':');
164
- if (colonIdx <= 0) return null;
165
- const head = bullet.slice(0, colonIdx).trim();
166
- if (!/[\\/.]/.test(head)) return null;
167
- return head;
168
- }
169
-
170
146
  /**
171
147
  * Collect the write-implying producer paths a single Story declares.
172
148
  *
173
- * Two shapes are honoured so the modern object-form `changes` contract and
174
- * the legacy string-bullet contract both feed the producer index:
175
- *
176
- * - **Object form** (`{ path, assumption }`) — reuses
177
- * `collectStoryAssumptionEntries` (the same extractor the Phase-8
178
- * file-assumption gate uses), then keeps only `changes`-sourced entries
179
- * whose assumption writes the path (`creates` / `refactors-existing` /
180
- * `deletes`). `exists` reads and `references` entries are dropped.
181
- * - **Legacy string bullets** (`"<path>: <verb> ..."`) — slice the
182
- * colon-head via `extractChangeBulletPath`. Legacy bullets carry no
183
- * assumption, so they are treated as writes (preserving pre-migration
184
- * behaviour).
149
+ * Uses object-form `{ path, assumption }` entries via
150
+ * `collectStoryAssumptionEntries` (the same extractor the Phase-8
151
+ * file-assumption gate uses), keeping only `changes`-sourced entries
152
+ * whose assumption writes the path (`creates` / `refactors-existing` /
153
+ * `deletes`). `exists` reads and `references` entries are dropped.
185
154
  *
186
155
  * Returns a de-duplicated array of producer paths for the Story.
187
156
  */
188
157
  function collectStoryProducerPaths(story) {
189
158
  const paths = new Set();
190
159
 
191
- // Object-form entries via the shared extractor. Only `changes`-sourced
192
- // write-implying assumptions count as producers.
193
160
  for (const entry of collectStoryAssumptionEntries(story)) {
194
161
  if (entry.source !== 'changes') continue;
195
162
  if (!WRITE_IMPLYING_ASSUMPTIONS.has(entry.assumption)) continue;
196
163
  paths.add(entry.path);
197
164
  }
198
165
 
199
- // Legacy string bullets — extract the colon-head path. Skip non-string
200
- // entries (object-form already handled above).
201
- const body = story?.body;
202
- const changes =
203
- body && typeof body === 'object' && Array.isArray(body.changes)
204
- ? body.changes
205
- : [];
206
- for (const bullet of changes) {
207
- if (typeof bullet !== 'string') continue;
208
- const path = extractChangeBulletPath(bullet);
209
- if (path) paths.add(path);
210
- }
211
-
212
166
  return Array.from(paths);
213
167
  }
214
168
 
@@ -223,11 +177,9 @@ function storySlugOf(story) {
223
177
 
224
178
  /**
225
179
  * Build the producers index — `Map<path, Array<{storySlug, taskSlug}>>` —
226
- * by walking every Story's declared writes. Both object-form
227
- * `{ path, assumption }` entries and legacy `"<path>: <verb> ..."` string
228
- * bullets are honoured via `collectStoryProducerPaths`; only write-implying
229
- * assumptions (and legacy bullets, which carry no assumption) count as
230
- * producers.
180
+ * by walking every Story's declared writes. Only object-form
181
+ * `{ path, assumption }` entries count as producers via
182
+ * `collectStoryProducerPaths`; only write-implying assumptions count.
231
183
  *
232
184
  * `taskSlug` is retained in the entry shape for finding/render
233
185
  * compatibility; in the 2-tier model it carries the Story's own slug since
@@ -519,9 +471,8 @@ function computeRegistryFindings({
519
471
  existing.push(entry);
520
472
  perStory.set(entry.storySlug, existing);
521
473
  }
522
- // (a) direct registry edits — accept both legacy string-form producers
523
- // (from `indexProducers`) and modern object-form `{ path, assumption }`
524
- // entries (from `indexAssumptionEntries`).
474
+ // (a) direct registry edits — object-form `{ path, assumption }` entries
475
+ // from `indexAssumptionEntries` (and the producer index built from them).
525
476
  for (const [path, entries] of producers.entries()) {
526
477
  if (!isRegistryPath(path, patterns)) continue;
527
478
  for (const e of entries) {
@@ -778,7 +729,6 @@ export function renderHardConflictError(finding) {
778
729
 
779
730
  // Internal helpers exposed for unit tests; not part of the public surface.
780
731
  export const _internal = {
781
- extractChangeBulletPath,
782
732
  collectStoryProducerPaths,
783
733
  WRITE_IMPLYING_ASSUMPTIONS,
784
734
  indexProducers,