mandrel 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/.agents/README.md +59 -28
  2. package/.agents/agents/acceptance-critic.md +9 -7
  3. package/.agents/agents/story-worker.md +41 -46
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +51 -44
  6. package/.agents/docs/agentrc-reference.json +8 -13
  7. package/.agents/docs/configuration.md +32 -56
  8. package/.agents/docs/execution-reference.md +39 -10
  9. package/.agents/docs/quality-gates.md +14 -16
  10. package/.agents/docs/workflows.md +6 -6
  11. package/.agents/instructions.md +64 -79
  12. package/.agents/rules/ci-remediation.md +3 -3
  13. package/.agents/rules/git-conventions-reference.md +42 -51
  14. package/.agents/schemas/agentrc.schema.json +34 -45
  15. package/.agents/schemas/audit-rules.json +59 -1
  16. package/.agents/schemas/audit-rules.schema.json +33 -1
  17. package/.agents/schemas/lifecycle/README.md +1 -2
  18. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  20. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  21. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  22. package/.agents/schemas/signal-event.schema.json +3 -3
  23. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  24. package/.agents/schemas/validation-evidence.schema.json +1 -1
  25. package/.agents/scripts/acceptance-eval.js +22 -66
  26. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  27. package/.agents/scripts/bootstrap.js +3 -3
  28. package/.agents/scripts/check-dead-exports.js +43 -104
  29. package/.agents/scripts/check-doc-links.js +2 -2
  30. package/.agents/scripts/check-lifecycle-lint.js +1 -1
  31. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  32. package/.agents/scripts/deliver-recover.js +122 -0
  33. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  34. package/.agents/scripts/evidence-gate.js +20 -50
  35. package/.agents/scripts/generate-skills-index.js +17 -1
  36. package/.agents/scripts/generate-workflows-doc.js +4 -4
  37. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  38. package/.agents/scripts/lib/audit-suite/selector.js +323 -23
  39. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -11
  40. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  41. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  42. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  43. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  44. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -1
  45. package/.agents/scripts/lib/checks/index.js +1 -1
  46. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  47. package/.agents/scripts/lib/checks/state.js +17 -248
  48. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +3 -3
  49. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  50. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  51. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  52. package/.agents/scripts/lib/cli-args.js +23 -2
  53. package/.agents/scripts/lib/close-validation/gates.js +13 -13
  54. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  55. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  56. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  57. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  58. package/.agents/scripts/lib/config/delivery-routing.js +7 -6
  59. package/.agents/scripts/lib/config/explain.js +10 -16
  60. package/.agents/scripts/lib/config/github.js +7 -5
  61. package/.agents/scripts/lib/config/limits.js +15 -25
  62. package/.agents/scripts/lib/config/quality.js +11 -14
  63. package/.agents/scripts/lib/config/runners.js +8 -21
  64. package/.agents/scripts/lib/config/temp-paths.js +18 -56
  65. package/.agents/scripts/lib/config-settings-schema-delivery.js +31 -13
  66. package/.agents/scripts/lib/config-settings-schema-quality.js +9 -2
  67. package/.agents/scripts/lib/config-settings-schema.js +48 -22
  68. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  69. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  70. package/.agents/scripts/lib/duplicate-search.js +38 -7
  71. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  72. package/.agents/scripts/lib/format-generated-json.js +97 -0
  73. package/.agents/scripts/lib/framework-version.js +19 -189
  74. package/.agents/scripts/lib/gh-exec.js +8 -0
  75. package/.agents/scripts/lib/git-branch-lifecycle.js +0 -158
  76. package/.agents/scripts/lib/git-utils.js +0 -14
  77. package/.agents/scripts/lib/json-utils.js +1 -2
  78. package/.agents/scripts/lib/label-constants.js +0 -15
  79. package/.agents/scripts/lib/label-taxonomy.js +1 -12
  80. package/.agents/scripts/lib/observability/active-story-env.js +42 -163
  81. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  82. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  83. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  84. package/.agents/scripts/lib/observability/source-classifier.js +2 -2
  85. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  86. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  87. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  88. package/.agents/scripts/lib/orchestration/ceremony-routing.js +43 -45
  89. package/.agents/scripts/lib/orchestration/code-review.js +58 -168
  90. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +3 -3
  91. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  92. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  93. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  94. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  95. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  96. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +9 -11
  97. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  98. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  99. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +7 -3
  100. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  101. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  102. package/.agents/scripts/lib/orchestration/merge-block-class.js +76 -20
  103. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  104. package/.agents/scripts/lib/orchestration/plan-context.js +114 -24
  105. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
  106. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +3 -7
  107. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  108. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +16 -6
  109. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +173 -25
  110. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  111. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +280 -75
  112. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +472 -55
  113. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +21 -16
  114. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  115. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +41 -40
  116. package/.agents/scripts/lib/orchestration/planning/spec-authoring-grounding.js +1 -1
  117. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  118. package/.agents/scripts/lib/orchestration/retro-proposals.js +7 -7
  119. package/.agents/scripts/lib/orchestration/review-depth.js +105 -40
  120. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  121. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  122. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  123. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  124. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  125. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  126. package/.agents/scripts/lib/orchestration/run-epilogue.js +374 -16
  127. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +24 -0
  128. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  129. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  130. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +3 -12
  131. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  132. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +72 -30
  133. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  134. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  135. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +12 -8
  136. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  137. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  138. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +264 -43
  139. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  140. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  141. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -32
  142. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  143. package/.agents/scripts/lib/orchestration/story-follow-ups.js +75 -14
  144. package/.agents/scripts/lib/orchestration/story-init-remote.js +12 -8
  145. package/.agents/scripts/lib/orchestration/story-plan-state.js +14 -29
  146. package/.agents/scripts/lib/orchestration/task-body-validator.js +52 -7
  147. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  148. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +119 -14
  149. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +3 -4
  150. package/.agents/scripts/lib/orchestration/ticket-validator.js +121 -18
  151. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -47
  152. package/.agents/scripts/lib/orchestration/ticketing/reads.js +19 -32
  153. package/.agents/scripts/lib/orchestration/ticketing/transition.js +61 -1
  154. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  155. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  156. package/.agents/scripts/lib/planning-corpus.js +12 -286
  157. package/.agents/scripts/lib/preflight-runner.js +2 -2
  158. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  159. package/.agents/scripts/lib/signals/index.js +4 -17
  160. package/.agents/scripts/lib/signals/read.js +35 -35
  161. package/.agents/scripts/lib/signals/schema.js +8 -11
  162. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  163. package/.agents/scripts/lib/signals/write.js +0 -1
  164. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  165. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  166. package/.agents/scripts/lib/story-adjacency.js +8 -7
  167. package/.agents/scripts/lib/story-body/story-body.js +6 -5
  168. package/.agents/scripts/lib/templates/decomposer-prompts.js +7 -3
  169. package/.agents/scripts/lib/test-env.js +14 -1
  170. package/.agents/scripts/lib/test-tiers.js +0 -3
  171. package/.agents/scripts/lib/ticket-body-sections.js +0 -14
  172. package/.agents/scripts/lib/validation-evidence.js +31 -59
  173. package/.agents/scripts/lib/wave-runner/ready-set.js +32 -6
  174. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  175. package/.agents/scripts/lib/worktree/lifecycle/reap.js +68 -19
  176. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  177. package/.agents/scripts/plan-context.js +38 -6
  178. package/.agents/scripts/plan-persist.js +145 -35
  179. package/.agents/scripts/plan-run-epilogue.js +83 -38
  180. package/.agents/scripts/post-structured-comment.js +0 -38
  181. package/.agents/scripts/pr-watch-with-update.js +43 -22
  182. package/.agents/scripts/providers/github/compose.js +0 -1
  183. package/.agents/scripts/providers/github/errors.js +0 -19
  184. package/.agents/scripts/providers/github/issues.js +1 -11
  185. package/.agents/scripts/providers/github/mappers.js +5 -0
  186. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  187. package/.agents/scripts/providers/github/tickets.js +33 -153
  188. package/.agents/scripts/providers/github.js +17 -6
  189. package/.agents/scripts/resolve-stories.js +236 -0
  190. package/.agents/scripts/run-coverage.js +4 -1
  191. package/.agents/scripts/run-lint.js +2 -2
  192. package/.agents/scripts/run-verify.js +31 -2
  193. package/.agents/scripts/signals-view.js +9 -10
  194. package/.agents/scripts/single-story-close.js +173 -18
  195. package/.agents/scripts/single-story-confirm-merge.js +288 -15
  196. package/.agents/scripts/single-story-init.js +6 -10
  197. package/.agents/scripts/stories-wave-tick.js +79 -4
  198. package/.agents/scripts/story-plan.js +3 -3
  199. package/.agents/scripts/update-ticket-state.js +8 -50
  200. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  201. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  202. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  203. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  204. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  205. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  206. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  207. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  208. package/.agents/skills/core/idea-refinement/SKILL.md +3 -3
  209. package/.agents/skills/core/scope-triage/SKILL.md +3 -0
  210. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  211. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  212. package/.agents/skills/skills.index.json +2 -12
  213. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  214. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  215. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  216. package/.agents/workflows/audit-architecture.md +3 -4
  217. package/.agents/workflows/audit-clean-code.md +4 -4
  218. package/.agents/workflows/audit-documentation.md +4 -5
  219. package/.agents/workflows/audit-lighthouse.md +8 -0
  220. package/.agents/workflows/audit-navigability.md +10 -0
  221. package/.agents/workflows/audit-performance.md +2 -3
  222. package/.agents/workflows/audit-quality.md +8 -9
  223. package/.agents/workflows/audit-security.md +1 -2
  224. package/.agents/workflows/audit-seo.md +10 -0
  225. package/.agents/workflows/audit-ux-ui.md +7 -0
  226. package/.agents/workflows/deliver.md +98 -45
  227. package/.agents/workflows/git-cleanup.md +2 -2
  228. package/.agents/workflows/git-deliver.md +1 -1
  229. package/.agents/workflows/helpers/acceptance-self-eval.md +21 -13
  230. package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
  231. package/.agents/workflows/helpers/code-review.md +12 -10
  232. package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
  233. package/.agents/workflows/helpers/deliver-story.md +193 -118
  234. package/.agents/workflows/helpers/parallel-tooling.md +2 -2
  235. package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
  236. package/.agents/workflows/plan.md +184 -19
  237. package/.agents/workflows/qa-assist.md +6 -6
  238. package/.agents/workflows/qa-explore.md +3 -3
  239. package/.agents/workflows/qa-run.md +1 -5
  240. package/bin/mandrel.js +12 -1
  241. package/docs/CHANGELOG.md +40 -0
  242. package/lib/cli/registry.js +262 -19
  243. package/lib/cli/sync-agents.js +157 -0
  244. package/lib/cli/sync-commands.js +115 -6
  245. package/lib/cli/sync.js +168 -6
  246. package/lib/cli/update.js +105 -8
  247. package/lib/cli/version-helpers.js +131 -0
  248. package/lib/migrations/README.md +7 -5
  249. package/lib/migrations/index.js +12 -9
  250. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  251. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  252. package/package.json +1 -1
  253. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  254. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  255. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  256. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  257. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  258. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  259. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  260. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  261. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  262. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  263. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  264. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  265. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  266. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  267. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  268. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  269. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  270. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  271. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  272. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  273. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  274. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  275. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  276. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  277. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  278. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  279. package/.agents/schemas/risk-verdict.schema.json +0 -53
  280. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  281. package/.agents/scripts/analyze-execution.js +0 -444
  282. package/.agents/scripts/check-prepush-recovery.js +0 -90
  283. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  284. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  285. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -187
  286. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  287. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  288. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  289. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +0 -128
  290. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -273
  291. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  292. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  293. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  294. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  295. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  296. package/.agents/scripts/lib/orchestration/planning/risk-verdict.js +0 -104
  297. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  298. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  299. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  300. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -21
  301. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  302. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  303. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  304. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -397
  305. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  306. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +0 -155
  307. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  308. package/.agents/scripts/lib/orchestration/story-progress/story-run-progress-writer.js +0 -400
  309. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +0 -36
  310. package/.agents/scripts/resolve-plan-run.js +0 -117
  311. package/.agents/skills/core/analyze-execution/SKILL.md +0 -101
@@ -11,12 +11,15 @@
11
11
  * adapter's `runReview()` to collect a `Finding[]`, render the
12
12
  * structured-comment body via `findings-renderer`, and post the
13
13
  * comment through the GitHub provider here (the adapter is post-free
14
- * by design). The lifecycle events (`code-review.start`/`.end`)
15
- * preserve their previous payload shape so the ledger and listener
16
- * chain are unchanged.
14
+ * by design).
15
+ *
16
+ * v2.0.0 removed the Epic tier. The Epic-scope envelope and the
17
+ * Epic-scoped `code-review.start` / `.end` lifecycle emits (whose schema
18
+ * requires `epicId`) went with it; Story scope is the only scope and the
19
+ * module no longer touches the lifecycle bus.
17
20
  *
18
21
  * Public API:
19
- * - `runCodeReview({ scope, ticketId, provider, logger, bus, ... })` →
22
+ * - `runCodeReview({ ticketId, headRef, provider, logger, ... })` →
20
23
  * `{ status, severity, posted, report, halted, blockerReason }`.
21
24
  *
22
25
  * Behaviour:
@@ -24,7 +27,7 @@
24
27
  * a single `native` chain entry when `delivery.codeReview.providers`
25
28
  * is unset or empty.
26
29
  * - Always posts the unified `verification-results` structured comment on
27
- * the Epic issue (the adapter never posts; the orchestrator owns
30
+ * the target issue/PR (the adapter never posts; the orchestrator owns
28
31
  * persistence). Story #4411 (Epic #4405) unified the former
29
32
  * `code-review` and `audit-results` findings contracts into this one
30
33
  * `verification-results` marker.
@@ -39,7 +42,7 @@
39
42
  import { hasSurvivingCritical } from '../audit-suite/findings.js';
40
43
  import { resolveConfig } from '../config-resolver.js';
41
44
  import { gitSpawn } from '../git-utils.js';
42
- import { resolveDepth } from './review-depth.js';
45
+ import { deriveChangeLevel, resolveDepth } from './review-depth.js';
43
46
  import {
44
47
  countBySeverity,
45
48
  renderFindings,
@@ -49,29 +52,30 @@ import { upsertStructuredComment } from './ticketing.js';
49
52
 
50
53
  /**
51
54
  * Review depth tiers, ordered light → standard → deep. The depth is resolved
52
- * by the shared {@link resolveDepth} resolver from the judged risk envelope's
53
- * `overallLevel` **and** the mechanical changed-file count of the diff under
54
- * review, then threaded into the review provider's `runReview` input so a
55
- * high-risk *or* wide-footprint change gets a deeper pass than a low-risk
56
- * small one. Depth is an **input** signal only it never changes the
55
+ * by the shared {@link resolveDepth} resolver from two observable properties of
56
+ * the diff under review — whether its changed files touch a registered
57
+ * sensitive path ({@link deriveChangeLevel}) and their mechanical count then
58
+ * threaded into the review provider's `runReview` input so a sensitive *or*
59
+ * wide-footprint change gets a deeper pass than a small, unremarkable one.
60
+ * Depth is an **input** signal only — it never changes the
57
61
  * `{ status, severity, posted, report, halted, blockerReason }` output
58
- * envelope nor the `code-review` structured-comment body (Story #3876,
59
- * extended by Story #3938).
62
+ * envelope nor the `verification-results` structured-comment body (Story #3876,
63
+ * extended by Story #3938; re-based off the diff by Story #4542).
60
64
  *
61
65
  * @typedef {import('./review-depth.js').ReviewDepth} ReviewDepth
62
66
  */
63
67
 
64
68
  /**
65
- * Count the files changed in the `baseRef...headRef` diff via
66
- * `git diff --name-only`. Returns the file count, or `null` when the diff
67
- * cannot be enumerated (git failure, missing ref). A `null` count is the
68
- * neutral "width unknown" signal {@link resolveDepth} tolerates without
69
- * downgrading or escalating the depth. Best-effort — never throws.
69
+ * Enumerate the files changed in the `baseRef...headRef` diff via
70
+ * `git diff --name-only`. Returns the file list, or `null` when the diff
71
+ * cannot be enumerated (git failure, missing ref). A `null` list is the neutral
72
+ * "diff unknown" signal both {@link deriveChangeLevel} and {@link resolveDepth}
73
+ * tolerate by failing safe to `standard`. Best-effort — never throws.
70
74
  *
71
75
  * @param {{ baseRef: string, headRef: string, gitSpawnFn?: typeof gitSpawn }} args
72
- * @returns {number|null}
76
+ * @returns {string[]|null}
73
77
  */
74
- function countChangedFiles({ baseRef, headRef, gitSpawnFn = gitSpawn }) {
78
+ function listChangedFiles({ baseRef, headRef, gitSpawnFn = gitSpawn }) {
75
79
  try {
76
80
  const result = gitSpawnFn(
77
81
  process.cwd(),
@@ -83,50 +87,14 @@ function countChangedFiles({ baseRef, headRef, gitSpawnFn = gitSpawn }) {
83
87
  return null;
84
88
  }
85
89
  return result.stdout
86
- .trim()
87
90
  .split('\n')
88
- .filter((line) => line.length > 0).length;
91
+ .map((line) => line.trim())
92
+ .filter((line) => line.length > 0);
89
93
  } catch {
90
94
  return null;
91
95
  }
92
96
  }
93
97
 
94
- /**
95
- * Build the `code-review.end` payload from the normalized result envelope.
96
- * The runner result may carry a `report` field (full markdown body) which
97
- * is NOT included in the lifecycle payload: the schema's
98
- * `additionalProperties: false` forbids it, and the body can carry inline
99
- * severity counts that drift from the structured `severity` field. The
100
- * lifecycle ledger is the structured surface; the report is GitHub's
101
- * surface (posted via the structured comment).
102
- *
103
- * Story #2839: `epicId` is preserved verbatim in the lifecycle payload so
104
- * the `code-review.end` schema (additionalProperties: false, requires
105
- * `epicId`) stays unchanged. Story-scope invocations never reach this
106
- * helper — `runCodeReview` short-circuits the bus emit for `scope: 'story'`
107
- * because story-scope review sits outside the Epic lifecycle ledger.
108
- */
109
- function buildCodeReviewEndPayload({ epicId, result, durationMs }) {
110
- const payload = {
111
- epicId,
112
- status: result.status,
113
- };
114
- if (result.severity && typeof result.severity === 'object') {
115
- payload.severity = {
116
- critical: result.severity.critical ?? 0,
117
- high: result.severity.high ?? 0,
118
- medium: result.severity.medium ?? 0,
119
- suggestion: result.severity.suggestion ?? 0,
120
- };
121
- }
122
- if (typeof result.halted === 'boolean') payload.halted = result.halted;
123
- if (typeof result.posted === 'boolean') payload.posted = result.posted;
124
- if (Number.isFinite(durationMs) && durationMs >= 0) {
125
- payload.durationMs = Math.floor(durationMs);
126
- }
127
- return payload;
128
- }
129
-
130
98
  /**
131
99
  * Resolve the project base branch fallback used when a caller omits
132
100
  * `baseRef`.
@@ -152,7 +120,6 @@ function resolveCommentTargetId(commentTargetId, fallback) {
152
120
  * baseRef: string,
153
121
  * headRef: string,
154
122
  * commentTargetId: number,
155
- * epicIdForLedger: null,
156
123
  * }}
157
124
  */
158
125
  function resolveStoryScope(opts, config) {
@@ -175,53 +142,16 @@ function resolveStoryScope(opts, config) {
175
142
  opts.commentTargetId,
176
143
  opts.ticketId,
177
144
  ),
178
- epicIdForLedger: null,
179
- };
180
- }
181
-
182
- /**
183
- * Resolve the Epic-scope envelope from the parameterized
184
- * `{ scope: 'epic', ticketId, baseRef, headRef, commentTargetId }` shape.
185
- * `headRef` defaults to `epic/<ticketId>` and `baseRef` to the project
186
- * base branch.
187
- *
188
- * @returns {{
189
- * scope: 'epic',
190
- * ticketId: number,
191
- * baseRef: string,
192
- * headRef: string,
193
- * commentTargetId: number,
194
- * epicIdForLedger: number,
195
- * }}
196
- */
197
- function resolveEpicScope(opts, config) {
198
- if (!Number.isInteger(opts.ticketId) || opts.ticketId <= 0) {
199
- throw new TypeError(
200
- 'runCodeReview: ticketId is required (positive integer) when scope="epic".',
201
- );
202
- }
203
- return {
204
- scope: 'epic',
205
- ticketId: opts.ticketId,
206
- baseRef: opts.baseRef ?? resolveConfigBase(config),
207
- headRef: opts.headRef ?? `epic/${opts.ticketId}`,
208
- commentTargetId: resolveCommentTargetId(
209
- opts.commentTargetId,
210
- opts.ticketId,
211
- ),
212
- epicIdForLedger: opts.ticketId,
213
145
  };
214
146
  }
215
147
 
216
148
  /**
217
- * Dispatch the parameterized scope envelope
218
- * (`{ scope, ticketId, baseRef, headRef, commentTargetId }`) to the
219
- * matching pure resolver. `scope` defaults to `'epic'`.
149
+ * Resolve the scope envelope
150
+ * (`{ scope, ticketId, baseRef, headRef, commentTargetId }`). v2.0.0
151
+ * removed the Epic tier, so `'story'` is the only scope.
220
152
  */
221
153
  function resolveScopeEnvelope(opts, config) {
222
- return opts.scope === 'story'
223
- ? resolveStoryScope(opts, config)
224
- : resolveEpicScope(opts, config);
154
+ return resolveStoryScope(opts, config);
225
155
  }
226
156
 
227
157
  /**
@@ -239,36 +169,28 @@ function resolveScopeEnvelope(opts, config) {
239
169
  * derived from the `Finding[]` returned by the adapter (no separate
240
170
  * severity field on the runner result).
241
171
  *
242
- * Story #2839 (Epic #2815) — accepts a parameterized scope envelope
243
- * so the standalone Story closer can request a Story-scope review
244
- * against `main`, post the structured findings comment to the PR
245
- * (via `commentTargetId`), and surface critical findings to the
246
- * caller as `halted: true`. Lifecycle bus emits are confined to
247
- * `scope: 'epic'` because the `code-review.end` schema requires
248
- * `epicId` and the ledger only spans Epic lifecycles.
172
+ * Story #2839 (Epic #2815) — the Story closer requests a Story-scope
173
+ * review against `main`, posts the structured findings comment to the PR
174
+ * (via `commentTargetId`), and surfaces critical findings to the caller
175
+ * as `halted: true`.
249
176
  *
250
- * Argument shape (parameterized, Epic or Story):
251
- * `{ scope, ticketId, baseRef, headRef, [commentTargetId],
252
- * provider, bus }`
253
- * `scope` defaults to `'epic'`; `baseRef` defaults to the project base
254
- * branch and (Epic scope only) `headRef` defaults to `epic/<ticketId>`.
255
- * For `scope === 'story'`, `commentTargetId` overrides the post
256
- * target (e.g. PR number) while `ticketId` continues to label the
257
- * rendered header ("Story #N").
177
+ * Argument shape:
178
+ * `{ ticketId, baseRef, headRef, [commentTargetId], provider }`
179
+ * `baseRef` defaults to the project base branch; `headRef` is required.
180
+ * `commentTargetId` overrides the post target (e.g. PR number) while
181
+ * `ticketId` continues to label the rendered header ("Story #N").
258
182
  *
259
183
  * @param {{
260
- * scope?: 'epic'|'story',
184
+ * scope?: 'story',
261
185
  * ticketId: number,
262
186
  * baseRef?: string|null,
263
187
  * headRef?: string|null,
264
188
  * commentTargetId?: number|null,
265
189
  * provider: object,
266
190
  * logger?: { info?: Function, warn?: Function, error?: Function, fatal?: Function, createProgress?: Function },
267
- * planningRisk?: { overallLevel?: ('low'|'medium'|'high'), axes?: Array<{ axis?: string, level?: string }> }|null,
191
+ * changedFiles?: string[]|null,
268
192
  * changedFileCount?: number|null,
269
193
  * storyId?: number|null,
270
- * bus?: object|null,
271
- * now?: () => number,
272
194
  * reviewProvider?: { runReview: Function },
273
195
  * gitSpawnFn?: typeof gitSpawn,
274
196
  * resolveConfigFn?: typeof resolveConfig,
@@ -309,22 +231,26 @@ function resolveProviderName(codeReviewConfig) {
309
231
 
310
232
  /**
311
233
  * Build the provider `runReview` input, resolving the review depth from the
312
- * judged risk envelope's `overallLevel` and the mechanical changed-file
313
- * count of the diff under review (Story #3876 / #3938). The depth is an
314
- * input-only signal (light → standard → deep) and never touches the output
315
- * envelope or the posted comment. Absent risk envelope + unknown width →
316
- * `standard`. Story #4075 — extracted from `runCodeReview`.
234
+ * diff under review: its changed files derive the change level (sensitive path
235
+ * touched or not Story #4542) and their count supplies the width. The depth
236
+ * is an input-only signal (light → standard → deep) and never touches the
237
+ * output envelope or the posted comment. An unenumerable diff `standard`.
238
+ * Story #4075 — extracted from `runCodeReview`.
317
239
  */
318
240
  function buildReviewInput({ opts, scope, ticketId, baseRef, headRef }) {
241
+ const changedFiles = Array.isArray(opts.changedFiles)
242
+ ? opts.changedFiles
243
+ : listChangedFiles({ baseRef, headRef, gitSpawnFn: opts.gitSpawnFn });
319
244
  const changedFileCount =
320
245
  typeof opts.changedFileCount === 'number'
321
246
  ? opts.changedFileCount
322
- : countChangedFiles({ baseRef, headRef, gitSpawnFn: opts.gitSpawnFn });
247
+ : (changedFiles?.length ?? null);
323
248
  // v2 Stage 2: review depth uses DEFAULT_DIFF_WIDTH (mechanical file count
324
249
  // of the diff under review). It is deliberately decoupled from the
325
250
  // planning model-capacity advisory (`DEFAULT_MODEL_CAPACITY`).
251
+ const { level } = deriveChangeLevel({ changedFiles });
326
252
  const depth = resolveDepth({
327
- overallLevel: opts.planningRisk?.overallLevel,
253
+ derivedLevel: level,
328
254
  changedFileCount,
329
255
  });
330
256
  return {
@@ -418,7 +344,7 @@ async function executeReviewPipeline({ opts, config, envelope }) {
418
344
  injectedReviewProvider ?? createReviewProviderFn(codeReviewConfig);
419
345
 
420
346
  logger?.info?.(
421
- `[code-review] Running ${providerName} adapter for ${scope === 'epic' ? 'Epic' : 'Story'} #${ticketId} (${baseRef}...${headRef})...`,
347
+ `[code-review] Running ${providerName} adapter for Story #${ticketId} (${baseRef}...${headRef})...`,
422
348
  );
423
349
 
424
350
  const reviewInput = buildReviewInput({
@@ -477,49 +403,13 @@ async function executeReviewPipeline({ opts, config, envelope }) {
477
403
  }
478
404
 
479
405
  export async function runCodeReview(opts = {}) {
480
- const { bus, now = Date.now, resolveConfigFn = resolveConfig } = opts;
406
+ const { resolveConfigFn = resolveConfig } = opts;
481
407
 
482
408
  const config = resolveConfigFn();
483
409
  const envelope = resolveScopeEnvelope(opts, config);
484
- const { scope } = envelope;
485
410
 
486
- // Epic-scope lifecycle ledger requires `bus`; Story-scope sits outside
487
- // the Epic lifecycle so the bus is optional there. A caller without a
488
- // bus on the Story path still gets the full review semantics — only the
489
- // `code-review.start`/`.end` events are suppressed.
490
- if (scope === 'epic' && (!bus || typeof bus.emit !== 'function')) {
491
- throw new TypeError('runCodeReview: bus is required (object with emit()).');
492
- }
493
- const ledgerEnabled =
494
- scope === 'epic' && bus && typeof bus.emit === 'function';
495
-
496
- const startedAt = typeof now === 'function' ? now() : Date.now();
497
- // Emit the matched `code-review.end` boundary; the ledger must always
498
- // show a start/end pair (even on adapter throw, where `result` is the
499
- // canonical `{ status: 'invalid' }`).
500
- const emitEnd = async (result) => {
501
- if (!ledgerEnabled) return;
502
- const endedAt = typeof now === 'function' ? now() : Date.now();
503
- await bus.emit(
504
- 'code-review.end',
505
- buildCodeReviewEndPayload({
506
- epicId: envelope.epicIdForLedger,
507
- result,
508
- durationMs: Math.max(0, endedAt - startedAt),
509
- }),
510
- );
511
- };
512
-
513
- if (ledgerEnabled) {
514
- await bus.emit('code-review.start', { epicId: envelope.epicIdForLedger });
515
- }
516
-
517
- try {
518
- const result = await executeReviewPipeline({ opts, config, envelope });
519
- await emitEnd(result);
520
- return result;
521
- } catch (err) {
522
- await emitEnd({ status: 'invalid' });
523
- throw err;
524
- }
411
+ // No lifecycle-bus emit: the `code-review.start` / `.end` ledger pair was
412
+ // Epic-scoped (its schema requires `epicId`), and v2.0.0 removed the Epic
413
+ // tier. Story-scope review sits outside the lifecycle ledger entirely.
414
+ return executeReviewPipeline({ opts, config, envelope });
525
415
  }
@@ -12,7 +12,7 @@
12
12
  * reconcile — dispatching it is pure token spend for a no-op. This module
13
13
  * computes that decision **deterministically**, off the same two inputs the
14
14
  * critic itself reads (the draft array and the Epic body's Delivery Slicing
15
- * table), so `helpers/plan-epic.md` Phase 8.3 can skip the sub-agent
15
+ * table), so the planning workflow can skip the sub-agent
16
16
  * dispatch when it is provably safe to.
17
17
  *
18
18
  * **Fail-open by design.** Every ambiguous case — a missing or unparseable
@@ -123,7 +123,7 @@ export function parseDeliverySlicingTable(epicBody) {
123
123
 
124
124
  /**
125
125
  * True when `story` is the recognized wave-0 BDD scaffold Story — identified
126
- * by the literal `bdd-scaffold` goal token the `epic-plan-decompose-author`
126
+ * by the literal `bdd-scaffold` goal token the decomposer prompt
127
127
  * skill's WAVE-0 BDD SCAFFOLD STORY section requires. Scaffold Stories are
128
128
  * not a Delivery Slicing slice, so they are excluded from the count
129
129
  * comparison — BDD-adopting consumer repos still benefit from the
@@ -145,7 +145,7 @@ function isBddScaffoldStory(story) {
145
145
  *
146
146
  * @param {object} input
147
147
  * @param {object[]} input.draftStories - The draft `tickets.json` array
148
- * (`epic-plan-decompose-author`'s output) — raw Story ticket objects with
148
+ * (the decomposer's output) — raw Story ticket objects with
149
149
  * top-level `slug` / `depends_on` / `body` (serialized string).
150
150
  * @param {string} input.epicBody - The Epic body carrying the folded Tech
151
151
  * Spec sections (`## Delivery Slicing` onward).