mandrel 2.0.0 → 2.2.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 (323) hide show
  1. package/.agents/README.md +59 -28
  2. package/.agents/agents/acceptance-critic.md +20 -9
  3. package/.agents/agents/story-worker.md +45 -48
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +60 -46
  6. package/.agents/docs/agentrc-reference.json +8 -13
  7. package/.agents/docs/configuration.md +33 -57
  8. package/.agents/docs/execution-reference.md +39 -10
  9. package/.agents/docs/quality-gates.md +17 -19
  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/gherkin-standards.md +10 -0
  14. package/.agents/rules/git-conventions-reference.md +42 -51
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +2 -2
  16. package/.agents/schemas/agentrc.schema.json +35 -46
  17. package/.agents/schemas/audit-rules.json +59 -1
  18. package/.agents/schemas/audit-rules.schema.json +33 -1
  19. package/.agents/schemas/lifecycle/README.md +1 -2
  20. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  21. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  22. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  23. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  24. package/.agents/schemas/signal-event.schema.json +3 -3
  25. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  26. package/.agents/schemas/validation-evidence.schema.json +1 -1
  27. package/.agents/scripts/acceptance-eval.js +24 -68
  28. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  29. package/.agents/scripts/bootstrap.js +3 -3
  30. package/.agents/scripts/check-dead-exports.js +43 -104
  31. package/.agents/scripts/check-doc-links.js +2 -2
  32. package/.agents/scripts/check-lifecycle-lint.js +1 -1
  33. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  34. package/.agents/scripts/deliver-recover.js +122 -0
  35. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  36. package/.agents/scripts/evidence-gate.js +20 -50
  37. package/.agents/scripts/generate-skills-index.js +17 -1
  38. package/.agents/scripts/generate-workflows-doc.js +4 -4
  39. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  40. package/.agents/scripts/lib/audit-suite/selector.js +323 -23
  41. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -11
  42. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  43. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  44. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  45. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  46. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -1
  47. package/.agents/scripts/lib/checks/index.js +1 -1
  48. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  49. package/.agents/scripts/lib/checks/state.js +17 -248
  50. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +3 -3
  51. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  52. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  53. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  54. package/.agents/scripts/lib/cli-args.js +23 -2
  55. package/.agents/scripts/lib/close-validation/gates.js +13 -13
  56. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  57. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  58. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  59. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  60. package/.agents/scripts/lib/config/acceptance-eval.js +2 -2
  61. package/.agents/scripts/lib/config/delivery-routing.js +7 -6
  62. package/.agents/scripts/lib/config/explain.js +10 -16
  63. package/.agents/scripts/lib/config/github.js +7 -5
  64. package/.agents/scripts/lib/config/limits.js +15 -25
  65. package/.agents/scripts/lib/config/quality.js +11 -14
  66. package/.agents/scripts/lib/config/runners.js +8 -21
  67. package/.agents/scripts/lib/config/temp-paths.js +18 -56
  68. package/.agents/scripts/lib/config-settings-schema-delivery.js +34 -16
  69. package/.agents/scripts/lib/config-settings-schema-quality.js +9 -2
  70. package/.agents/scripts/lib/config-settings-schema.js +48 -22
  71. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  72. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  73. package/.agents/scripts/lib/duplicate-search.js +38 -7
  74. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  75. package/.agents/scripts/lib/format-generated-json.js +97 -0
  76. package/.agents/scripts/lib/framework-version.js +19 -189
  77. package/.agents/scripts/lib/gh-exec.js +8 -0
  78. package/.agents/scripts/lib/git-branch-lifecycle.js +0 -158
  79. package/.agents/scripts/lib/git-utils.js +0 -14
  80. package/.agents/scripts/lib/json-utils.js +1 -2
  81. package/.agents/scripts/lib/label-constants.js +0 -15
  82. package/.agents/scripts/lib/label-taxonomy.js +1 -12
  83. package/.agents/scripts/lib/observability/active-story-env.js +42 -163
  84. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  85. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  86. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  87. package/.agents/scripts/lib/observability/source-classifier.js +2 -2
  88. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  89. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  90. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  91. package/.agents/scripts/lib/orchestration/ceremony-routing.js +43 -45
  92. package/.agents/scripts/lib/orchestration/change-set.js +103 -0
  93. package/.agents/scripts/lib/orchestration/code-review.js +70 -191
  94. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +3 -3
  95. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  96. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  97. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  98. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  99. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  100. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +9 -11
  101. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  102. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  103. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +7 -3
  104. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  105. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  106. package/.agents/scripts/lib/orchestration/merge-block-class.js +76 -20
  107. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  108. package/.agents/scripts/lib/orchestration/plan-context.js +116 -33
  109. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +26 -36
  110. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +31 -22
  111. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  112. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +16 -6
  113. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +173 -25
  114. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  115. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +280 -100
  116. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +472 -55
  117. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +21 -16
  118. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  119. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +230 -0
  120. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +41 -40
  121. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +1 -2
  122. package/.agents/scripts/lib/orchestration/planning/spec-authoring-grounding.js +1 -1
  123. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  124. package/.agents/scripts/lib/orchestration/retro-proposals.js +7 -7
  125. package/.agents/scripts/lib/orchestration/review-depth.js +105 -40
  126. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  127. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  128. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  129. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  130. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  131. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  132. package/.agents/scripts/lib/orchestration/run-epilogue.js +374 -16
  133. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +24 -0
  134. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  135. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  136. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +4 -13
  137. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  138. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +72 -30
  139. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  140. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  141. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +12 -8
  142. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  143. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  144. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +264 -43
  145. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  146. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  147. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +104 -279
  148. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +191 -0
  149. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +120 -0
  150. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  151. package/.agents/scripts/lib/orchestration/story-follow-ups.js +75 -14
  152. package/.agents/scripts/lib/orchestration/story-init-remote.js +12 -8
  153. package/.agents/scripts/lib/orchestration/story-plan-state.js +14 -29
  154. package/.agents/scripts/lib/orchestration/task-body-validator.js +52 -7
  155. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  156. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +119 -14
  157. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +3 -4
  158. package/.agents/scripts/lib/orchestration/ticket-validator.js +121 -18
  159. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -47
  160. package/.agents/scripts/lib/orchestration/ticketing/reads.js +19 -32
  161. package/.agents/scripts/lib/orchestration/ticketing/transition.js +61 -1
  162. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  163. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  164. package/.agents/scripts/lib/planning-corpus.js +12 -286
  165. package/.agents/scripts/lib/preflight-runner.js +2 -2
  166. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  167. package/.agents/scripts/lib/signals/index.js +4 -17
  168. package/.agents/scripts/lib/signals/read.js +35 -35
  169. package/.agents/scripts/lib/signals/schema.js +8 -11
  170. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  171. package/.agents/scripts/lib/signals/write.js +0 -1
  172. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  173. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  174. package/.agents/scripts/lib/story-adjacency.js +8 -7
  175. package/.agents/scripts/lib/story-body/story-body.js +81 -13
  176. package/.agents/scripts/lib/templates/decomposer-prompts.js +15 -16
  177. package/.agents/scripts/lib/test-env.js +14 -1
  178. package/.agents/scripts/lib/test-tiers.js +0 -3
  179. package/.agents/scripts/lib/ticket-body-sections.js +0 -14
  180. package/.agents/scripts/lib/validation-evidence.js +31 -59
  181. package/.agents/scripts/lib/wave-runner/live-probe.js +315 -0
  182. package/.agents/scripts/lib/wave-runner/ready-set.js +32 -6
  183. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  184. package/.agents/scripts/lib/worktree/lifecycle/reap.js +68 -19
  185. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  186. package/.agents/scripts/plan-context.js +38 -7
  187. package/.agents/scripts/plan-critics.js +203 -0
  188. package/.agents/scripts/plan-persist.js +145 -35
  189. package/.agents/scripts/plan-run-epilogue.js +83 -38
  190. package/.agents/scripts/post-structured-comment.js +0 -38
  191. package/.agents/scripts/pr-watch-with-update.js +43 -22
  192. package/.agents/scripts/providers/github/compose.js +0 -1
  193. package/.agents/scripts/providers/github/errors.js +0 -19
  194. package/.agents/scripts/providers/github/issues.js +1 -11
  195. package/.agents/scripts/providers/github/mappers.js +5 -0
  196. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  197. package/.agents/scripts/providers/github/tickets.js +33 -153
  198. package/.agents/scripts/providers/github.js +17 -6
  199. package/.agents/scripts/quality-preview.js +13 -6
  200. package/.agents/scripts/resolve-stories.js +236 -0
  201. package/.agents/scripts/run-coverage.js +4 -1
  202. package/.agents/scripts/run-lint.js +2 -2
  203. package/.agents/scripts/run-verify.js +31 -2
  204. package/.agents/scripts/signals-view.js +9 -10
  205. package/.agents/scripts/single-story-close.js +173 -18
  206. package/.agents/scripts/single-story-confirm-merge.js +288 -15
  207. package/.agents/scripts/single-story-init.js +6 -10
  208. package/.agents/scripts/stories-wave-tick.js +380 -53
  209. package/.agents/scripts/story-plan.js +3 -3
  210. package/.agents/scripts/update-ticket-state.js +8 -50
  211. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  212. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  213. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  214. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  215. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  216. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  217. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  218. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  219. package/.agents/skills/core/idea-refinement/SKILL.md +3 -3
  220. package/.agents/skills/core/scope-triage/SKILL.md +3 -0
  221. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  222. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  223. package/.agents/skills/skills.index.json +2 -12
  224. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  225. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  226. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  227. package/.agents/workflows/audit-architecture.md +3 -4
  228. package/.agents/workflows/audit-clean-code.md +4 -4
  229. package/.agents/workflows/audit-documentation.md +4 -5
  230. package/.agents/workflows/audit-lighthouse.md +8 -0
  231. package/.agents/workflows/audit-navigability.md +10 -0
  232. package/.agents/workflows/audit-performance.md +2 -3
  233. package/.agents/workflows/audit-quality.md +8 -9
  234. package/.agents/workflows/audit-security.md +1 -2
  235. package/.agents/workflows/audit-seo.md +10 -0
  236. package/.agents/workflows/audit-ux-ui.md +7 -0
  237. package/.agents/workflows/deliver.md +133 -45
  238. package/.agents/workflows/git-cleanup.md +2 -2
  239. package/.agents/workflows/git-deliver.md +1 -1
  240. package/.agents/workflows/helpers/acceptance-self-eval.md +34 -17
  241. package/.agents/workflows/helpers/code-quality-guardrails.md +15 -12
  242. package/.agents/workflows/helpers/code-review.md +14 -12
  243. package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
  244. package/.agents/workflows/helpers/deliver-story.md +209 -118
  245. package/.agents/workflows/helpers/parallel-tooling.md +2 -2
  246. package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
  247. package/.agents/workflows/plan.md +239 -19
  248. package/.agents/workflows/qa-assist.md +6 -6
  249. package/.agents/workflows/qa-explore.md +3 -3
  250. package/.agents/workflows/qa-run.md +1 -5
  251. package/bin/mandrel.js +12 -1
  252. package/docs/CHANGELOG.md +62 -0
  253. package/lib/cli/registry.js +262 -19
  254. package/lib/cli/sync-agents.js +157 -0
  255. package/lib/cli/sync-commands.js +115 -6
  256. package/lib/cli/sync.js +168 -6
  257. package/lib/cli/update.js +105 -8
  258. package/lib/cli/version-helpers.js +131 -0
  259. package/lib/migrations/README.md +7 -5
  260. package/lib/migrations/index.js +17 -9
  261. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  262. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  263. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +154 -0
  264. package/package.json +2 -2
  265. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  266. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  267. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  268. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  269. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  270. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  271. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  272. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  273. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  274. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  275. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  276. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  277. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  278. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  279. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  280. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  281. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  282. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  283. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  284. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  285. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  286. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  287. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  288. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  289. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  290. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  291. package/.agents/schemas/risk-verdict.schema.json +0 -53
  292. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  293. package/.agents/scripts/analyze-execution.js +0 -444
  294. package/.agents/scripts/check-prepush-recovery.js +0 -90
  295. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  296. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  297. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -187
  298. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  299. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  300. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  301. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +0 -128
  302. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -273
  303. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  304. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  305. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  306. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  307. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  308. package/.agents/scripts/lib/orchestration/planning/risk-verdict.js +0 -104
  309. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  310. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  311. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  312. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -21
  313. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  314. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  315. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  316. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -397
  317. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  318. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +0 -155
  319. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  320. package/.agents/scripts/lib/orchestration/story-progress/story-run-progress-writer.js +0 -400
  321. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +0 -36
  322. package/.agents/scripts/resolve-plan-run.js +0 -117
  323. package/.agents/skills/core/analyze-execution/SKILL.md +0 -101
@@ -0,0 +1,100 @@
1
+ // lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js
2
+ /**
3
+ * Story #4531 — the first real step in the migration registry.
4
+ *
5
+ * `delivery.quality.codingGuardrails.miDropMustRefactor` and
6
+ * `delivery.quality.autoRefresh.miDropCap` were schema-validated, defaulted,
7
+ * and seeded by `apply-quality-bootstrap.js` into a consumer's
8
+ * `.agentrc.json` — but never consumed by the gate they were named for
9
+ * (`maintainability.tolerance` is the knob actually in force; see the
10
+ * Story body for the full diagnosis). Both retired keys lived under
11
+ * sub-schemas with `additionalProperties: false`, so a consumer whose
12
+ * config still carries either key hits a hard AJV validation failure on
13
+ * upgrade, not a warning. This step strips them before that check runs.
14
+ */
15
+
16
+ import nodeFs from 'node:fs';
17
+ import path from 'node:path';
18
+
19
+ const AGENTRC_FILENAME = '.agentrc.json';
20
+
21
+ /**
22
+ * @param {unknown} ctx
23
+ * @returns {string}
24
+ */
25
+ function resolveAgentrcPath(ctx) {
26
+ const projectRoot = ctx?.projectRoot ?? process.cwd();
27
+ return path.join(projectRoot, AGENTRC_FILENAME);
28
+ }
29
+
30
+ /**
31
+ * @param {unknown} ctx
32
+ * @param {typeof nodeFs} fsImpl
33
+ * @returns {object | null}
34
+ */
35
+ function readAgentrcConfig(ctx, fsImpl) {
36
+ try {
37
+ const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx), 'utf8');
38
+ return JSON.parse(raw);
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * @param {object | null} config
46
+ * @returns {boolean}
47
+ */
48
+ function hasRetiredKey(config) {
49
+ const guardrails = config?.delivery?.quality?.codingGuardrails;
50
+ const autoRefresh = config?.delivery?.quality?.autoRefresh;
51
+ return (
52
+ (Boolean(guardrails) && Object.hasOwn(guardrails, 'miDropMustRefactor')) ||
53
+ (Boolean(autoRefresh) && Object.hasOwn(autoRefresh, 'miDropCap'))
54
+ );
55
+ }
56
+
57
+ export const retireMiDropKnobs = {
58
+ version: '2.1.0',
59
+ description:
60
+ 'strip retired delivery.quality.codingGuardrails.miDropMustRefactor ' +
61
+ 'and delivery.quality.autoRefresh.miDropCap from .agentrc.json',
62
+ /**
63
+ * @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
64
+ * @returns {boolean}
65
+ */
66
+ detect(ctx) {
67
+ const fsImpl = ctx?.fs ?? nodeFs;
68
+ return hasRetiredKey(readAgentrcConfig(ctx, fsImpl));
69
+ },
70
+ /**
71
+ * @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
72
+ * @returns {void}
73
+ */
74
+ apply(ctx) {
75
+ const fsImpl = ctx?.fs ?? nodeFs;
76
+ const config = readAgentrcConfig(ctx, fsImpl);
77
+ if (!config) return;
78
+
79
+ const guardrails = config.delivery?.quality?.codingGuardrails;
80
+ if (guardrails && Object.hasOwn(guardrails, 'miDropMustRefactor')) {
81
+ delete guardrails.miDropMustRefactor;
82
+ if (Object.keys(guardrails).length === 0) {
83
+ delete config.delivery.quality.codingGuardrails;
84
+ }
85
+ }
86
+
87
+ const autoRefresh = config.delivery?.quality?.autoRefresh;
88
+ if (autoRefresh && Object.hasOwn(autoRefresh, 'miDropCap')) {
89
+ delete autoRefresh.miDropCap;
90
+ if (Object.keys(autoRefresh).length === 0) {
91
+ delete config.delivery.quality.autoRefresh;
92
+ }
93
+ }
94
+
95
+ fsImpl.writeFileSync(
96
+ resolveAgentrcPath(ctx),
97
+ `${JSON.stringify(config, null, 2)}\n`,
98
+ );
99
+ },
100
+ };
@@ -0,0 +1,101 @@
1
+ // lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js
2
+ /**
3
+ * Story #4545 — retire `delivery.deliverRunner.verifyConcurrencyCap`.
4
+ *
5
+ * The knob was schema-validated, defaulted to 4, resolved by `getRunners`,
6
+ * and documented as bounding "the per-wave verifyWaveResults loop" — a loop
7
+ * that does not exist anywhere in the tree. Its only reader was
8
+ * `analyze-execution.js`, which echoed the number into a perf report rather
9
+ * than bounding anything; that CLI is deleted in the same Story. Setting the
10
+ * knob to any value only ever changed a number printed in a report.
11
+ *
12
+ * `delivery.deliverRunner` declares `additionalProperties: false`, so a
13
+ * consumer whose config still carries the key hits a hard AJV validation
14
+ * failure on upgrade — every script that resolves config, not just the one
15
+ * that read it. This step strips it before that check runs.
16
+ *
17
+ * Unlike the 2.1.0 mi-drop step, this one also sweeps `.agentrc.local.json`:
18
+ * the resolver deep-merges the local override over `.agentrc.json` and
19
+ * validates the *merged* result, so a key left in the local file fails the
20
+ * same way a key in the committed file does.
21
+ */
22
+
23
+ import nodeFs from 'node:fs';
24
+ import path from 'node:path';
25
+
26
+ const AGENTRC_FILENAMES = ['.agentrc.json', '.agentrc.local.json'];
27
+
28
+ /**
29
+ * @param {unknown} ctx
30
+ * @param {string} filename
31
+ * @returns {string}
32
+ */
33
+ function resolveAgentrcPath(ctx, filename) {
34
+ const projectRoot = ctx?.projectRoot ?? process.cwd();
35
+ return path.join(projectRoot, filename);
36
+ }
37
+
38
+ /**
39
+ * @param {unknown} ctx
40
+ * @param {string} filename
41
+ * @param {typeof nodeFs} fsImpl
42
+ * @returns {object | null}
43
+ */
44
+ function readAgentrcConfig(ctx, filename, fsImpl) {
45
+ try {
46
+ const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx, filename), 'utf8');
47
+ return JSON.parse(raw);
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * @param {object | null} config
55
+ * @returns {boolean}
56
+ */
57
+ function hasRetiredKey(config) {
58
+ const deliverRunner = config?.delivery?.deliverRunner;
59
+ return (
60
+ Boolean(deliverRunner) &&
61
+ Object.hasOwn(deliverRunner, 'verifyConcurrencyCap')
62
+ );
63
+ }
64
+
65
+ export const retireVerifyConcurrencyCap = {
66
+ version: '2.1.0',
67
+ description:
68
+ 'strip retired delivery.deliverRunner.verifyConcurrencyCap from ' +
69
+ '.agentrc.json and .agentrc.local.json',
70
+ /**
71
+ * @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
72
+ * @returns {boolean}
73
+ */
74
+ detect(ctx) {
75
+ const fsImpl = ctx?.fs ?? nodeFs;
76
+ return AGENTRC_FILENAMES.some((filename) =>
77
+ hasRetiredKey(readAgentrcConfig(ctx, filename, fsImpl)),
78
+ );
79
+ },
80
+ /**
81
+ * @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
82
+ * @returns {void}
83
+ */
84
+ apply(ctx) {
85
+ const fsImpl = ctx?.fs ?? nodeFs;
86
+ for (const filename of AGENTRC_FILENAMES) {
87
+ const config = readAgentrcConfig(ctx, filename, fsImpl);
88
+ if (!hasRetiredKey(config)) continue;
89
+
90
+ delete config.delivery.deliverRunner.verifyConcurrencyCap;
91
+ if (Object.keys(config.delivery.deliverRunner).length === 0) {
92
+ delete config.delivery.deliverRunner;
93
+ }
94
+
95
+ fsImpl.writeFileSync(
96
+ resolveAgentrcPath(ctx, filename),
97
+ `${JSON.stringify(config, null, 2)}\n`,
98
+ );
99
+ }
100
+ },
101
+ };
@@ -0,0 +1,154 @@
1
+ // lib/migrations/steps/2.2.0-retire-epic-ac-tags.js
2
+ /**
3
+ * Story #4604 — strip the retired `@epic-<id>-ac-N` Gherkin AC tag namespace
4
+ * from consumer feature files.
5
+ *
6
+ * The v2 Epic removal deleted `acceptance-spec-reconciler.js`, the only
7
+ * consumer of the namespaced per-Epic AC tags, and the `/plan` authoring
8
+ * prompt no longer mandates them. Surviving tags in consumer `.feature`
9
+ * files are inert and violate the gherkin-standards tag taxonomy's
10
+ * no-ad-hoc-tags rule, so this step removes them: each `@epic-<digits>-ac-<digits>`
11
+ * token is deleted from tag lines, a tag line left with no tags is dropped
12
+ * entirely, and every other tag and line is preserved byte-for-byte. Files
13
+ * with no stale tags are never rewritten.
14
+ */
15
+
16
+ import nodeFs from 'node:fs';
17
+ import path from 'node:path';
18
+
19
+ /**
20
+ * Mirror of `CANONICAL_FEATURE_ROOTS` in
21
+ * `.agents/scripts/lib/bdd-runner-detect.js`. Duplicated deliberately:
22
+ * `lib/` runs from the installed npm package inside a consumer project and
23
+ * must not import from the materialized `.agents/` payload.
24
+ */
25
+ const CANONICAL_FEATURE_ROOTS = Object.freeze([
26
+ 'tests/features',
27
+ 'features',
28
+ 'test/features',
29
+ ]);
30
+
31
+ const EPIC_AC_TAG_RE = /@epic-\d+-ac-\d+/;
32
+
33
+ /**
34
+ * A Gherkin tag line: optional indentation followed by one or more
35
+ * whitespace-separated `@tag` tokens and nothing else.
36
+ */
37
+ const TAG_LINE_RE = /^(\s*)(@\S+(?:\s+@\S+)*)\s*$/;
38
+
39
+ /**
40
+ * Recursively collect `.feature` file paths under `root`.
41
+ *
42
+ * @param {string} root
43
+ * @param {typeof nodeFs} fsImpl
44
+ * @returns {string[]}
45
+ */
46
+ function collectFeatureFiles(root, fsImpl) {
47
+ /** @type {string[]} */
48
+ const found = [];
49
+ /** @type {string[]} */
50
+ const queue = [root];
51
+ while (queue.length > 0) {
52
+ const dir = queue.pop();
53
+ /** @type {import('node:fs').Dirent[]} */
54
+ let entries;
55
+ try {
56
+ entries = fsImpl.readdirSync(dir, { withFileTypes: true });
57
+ } catch {
58
+ continue;
59
+ }
60
+ for (const entry of entries) {
61
+ const full = path.join(dir, entry.name);
62
+ if (entry.isDirectory()) {
63
+ queue.push(full);
64
+ } else if (entry.isFile() && entry.name.endsWith('.feature')) {
65
+ found.push(full);
66
+ }
67
+ }
68
+ }
69
+ return found.sort();
70
+ }
71
+
72
+ /**
73
+ * @param {unknown} ctx
74
+ * @param {typeof nodeFs} fsImpl
75
+ * @returns {string[]} Absolute paths of every `.feature` file under the
76
+ * canonical feature roots that exist in the consumer tree.
77
+ */
78
+ function resolveFeatureFiles(ctx, fsImpl) {
79
+ const projectRoot = ctx?.projectRoot ?? process.cwd();
80
+ return CANONICAL_FEATURE_ROOTS.flatMap((root) =>
81
+ collectFeatureFiles(path.join(projectRoot, root), fsImpl),
82
+ );
83
+ }
84
+
85
+ /**
86
+ * Strip retired `@epic-<id>-ac-<n>` tokens from one file's content.
87
+ * Only tag lines are touched; a tag line whose every tag was retired is
88
+ * dropped. Returns the original string when nothing matched.
89
+ *
90
+ * @param {string} content
91
+ * @returns {string}
92
+ */
93
+ function stripEpicAcTags(content) {
94
+ if (!EPIC_AC_TAG_RE.test(content)) return content;
95
+ const newline = content.includes('\r\n') ? '\r\n' : '\n';
96
+ const lines = content.split(newline);
97
+ /** @type {string[]} */
98
+ const out = [];
99
+ for (const line of lines) {
100
+ const match = line.match(TAG_LINE_RE);
101
+ if (!match || !EPIC_AC_TAG_RE.test(line)) {
102
+ out.push(line);
103
+ continue;
104
+ }
105
+ const [, indent, tagBlock] = match;
106
+ const kept = tagBlock
107
+ .split(/\s+/)
108
+ .filter((tag) => !EPIC_AC_TAG_RE.test(tag));
109
+ if (kept.length === 0) continue;
110
+ out.push(`${indent}${kept.join(' ')}`);
111
+ }
112
+ return out.join(newline);
113
+ }
114
+
115
+ export const retireEpicAcTags = {
116
+ version: '2.2.0',
117
+ description:
118
+ 'strip retired @epic-<id>-ac-N Gherkin AC tags from feature files ' +
119
+ '(their reconciler consumer was deleted in the v2 Epic removal)',
120
+ /**
121
+ * @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
122
+ * @returns {boolean}
123
+ */
124
+ detect(ctx) {
125
+ const fsImpl = ctx?.fs ?? nodeFs;
126
+ return resolveFeatureFiles(ctx, fsImpl).some((file) => {
127
+ try {
128
+ return EPIC_AC_TAG_RE.test(fsImpl.readFileSync(file, 'utf8'));
129
+ } catch {
130
+ return false;
131
+ }
132
+ });
133
+ },
134
+ /**
135
+ * @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
136
+ * @returns {void}
137
+ */
138
+ apply(ctx) {
139
+ const fsImpl = ctx?.fs ?? nodeFs;
140
+ for (const file of resolveFeatureFiles(ctx, fsImpl)) {
141
+ /** @type {string} */
142
+ let content;
143
+ try {
144
+ content = fsImpl.readFileSync(file, 'utf8');
145
+ } catch {
146
+ continue;
147
+ }
148
+ const stripped = stripEpicAcTags(content);
149
+ if (stripped !== content) {
150
+ fsImpl.writeFileSync(file, stripped);
151
+ }
152
+ }
153
+ },
154
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandrel",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Claude Code-first opinionated workflow framework: instructions, skills, rules, and SDLC workflows that govern AI coding assistants.",
5
5
  "files": [
6
6
  ".agents/",
@@ -45,7 +45,7 @@
45
45
  "crap:update": "node .agents/scripts/update-crap-baseline.js",
46
46
  "duplication:check": "node .agents/scripts/check-baselines.js --gate duplication",
47
47
  "duplication:update": "node .agents/scripts/update-duplication-baseline.js",
48
- "quality:preview": "node .agents/scripts/quality-preview.js --changed-since HEAD && node .agents/scripts/check-dead-exports.js",
48
+ "quality:preview": "node .agents/scripts/check-dead-exports.js && node .agents/scripts/quality-preview.js",
49
49
  "quality:watch": "node .agents/scripts/quality-watch.js",
50
50
  "sync:commands": "node bin/mandrel.js sync-commands",
51
51
  "sync:agents": "node .agents/scripts/sync-claude-agents.js",
@@ -1,89 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/epic-perf-report.schema.json",
4
- "title": "EpicPerfReport",
5
- "description": "Payload of the <!-- structured:epic-perf-report --> comment posted once per Epic at close, alongside the retro (Epic #1030; waveParallelism utilisation rows added under Epic #3019 / Story #3025).",
6
- "type": "object",
7
- "additionalProperties": false,
8
- "required": [
9
- "kind",
10
- "epicId",
11
- "generatedAt",
12
- "signalCounts",
13
- "waveParallelism",
14
- "topHotspots",
15
- "mostFrictionStories"
16
- ],
17
- "properties": {
18
- "kind": { "type": "string", "const": "epic-perf-report" },
19
- "epicId": { "type": "integer", "minimum": 1 },
20
- "generatedAt": { "type": "string", "format": "date-time" },
21
- "signalCounts": {
22
- "type": "object",
23
- "description": "Rolled-up signal counts by kind for the entire Epic.",
24
- "additionalProperties": false,
25
- "properties": {
26
- "friction": { "type": "integer", "minimum": 0 },
27
- "hotspot": { "type": "integer", "minimum": 0 },
28
- "rework": { "type": "integer", "minimum": 0 },
29
- "churn": { "type": "integer", "minimum": 0 },
30
- "idle": { "type": "integer", "minimum": 0 },
31
- "retry": { "type": "integer", "minimum": 0 }
32
- }
33
- },
34
- "waveParallelism": {
35
- "type": "array",
36
- "description": "Per-wave parallelism utilisation. utilisation = summedStoryMs / (wallClockMs * min(storyCount, concurrencyCap)), clamped to [0,1] (Epic #3019 / Story #3025; effective-cap denominator Story #3850).",
37
- "items": {
38
- "type": "object",
39
- "additionalProperties": false,
40
- "required": [
41
- "waveIndex",
42
- "wallClockMs",
43
- "summedStoryMs",
44
- "utilisation",
45
- "capBinding",
46
- "verifyConcurrencyCap"
47
- ],
48
- "properties": {
49
- "waveIndex": { "type": "integer", "minimum": 0 },
50
- "storyCount": {
51
- "type": "integer",
52
- "minimum": 0,
53
- "description": "Number of Stories in the wave (from wave-start.stories). Added Story #3850."
54
- },
55
- "wallClockMs": { "type": "integer", "minimum": 0 },
56
- "summedStoryMs": { "type": "integer", "minimum": 0 },
57
- "utilisation": { "type": "number", "minimum": 0, "maximum": 1 },
58
- "capBinding": { "type": "boolean" },
59
- "verifyConcurrencyCap": { "type": "integer", "minimum": 1 }
60
- }
61
- }
62
- },
63
- "topHotspots": {
64
- "type": "array",
65
- "items": {
66
- "type": "object",
67
- "additionalProperties": false,
68
- "required": ["phase", "occurrences", "avgRatio"],
69
- "properties": {
70
- "phase": { "type": "string", "minLength": 1 },
71
- "occurrences": { "type": "integer", "minimum": 0 },
72
- "avgRatio": { "type": "number", "minimum": 0 }
73
- }
74
- }
75
- },
76
- "mostFrictionStories": {
77
- "type": "array",
78
- "items": {
79
- "type": "object",
80
- "additionalProperties": false,
81
- "required": ["storyId", "frictionCount"],
82
- "properties": {
83
- "storyId": { "type": "integer", "minimum": 1 },
84
- "frictionCount": { "type": "integer", "minimum": 0 }
85
- }
86
- }
87
- }
88
- }
89
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json",
4
- "title": "acceptance.reconcile.failed",
5
- "description": "Emitted by AcceptanceReconciler when reconciliation fails. Routes to epic.blocked; no PR is created.",
6
- "type": "object",
7
- "required": ["baseRead", "reason"],
8
- "properties": {
9
- "baseRead": { "type": "boolean" },
10
- "reason": { "type": "string", "minLength": 1 }
11
- },
12
- "additionalProperties": false
13
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json",
4
- "title": "acceptance.reconcile.ok",
5
- "description": "Emitted by AcceptanceReconciler when reconciliation passes. Finalizer subscribes only to this event to gate the push and PR create.",
6
- "type": "object",
7
- "required": ["baseRead"],
8
- "properties": {
9
- "baseRead": { "type": "boolean" },
10
- "reason": { "type": "string" }
11
- },
12
- "additionalProperties": false
13
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json",
4
- "title": "acceptance.reconcile.skipped",
5
- "description": "Emitted by AcceptanceReconciler when reconciliation is skipped because the linked Acceptance Spec declares zero AC IDs ('empty-spec'). Story #2893 split the `acceptance::n-a` waiver path out to `acceptance.reconcile.waived` so the Finalizer can route waived Epics through to PR creation while empty-spec Epics still terminate without a PR. The reason field is required so the listener never silently no-ops.",
6
- "type": "object",
7
- "required": ["baseRead", "reason"],
8
- "properties": {
9
- "baseRead": { "type": "boolean" },
10
- "reason": { "type": "string", "minLength": 1 }
11
- },
12
- "additionalProperties": false
13
- }
@@ -1,12 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json",
4
- "title": "acceptance.reconcile.start",
5
- "description": "Emitted by AcceptanceReconciler at the start of acceptance-spec reconciliation. Must precede pr.created in every healthy run (reconciliation ordering invariant).",
6
- "type": "object",
7
- "required": ["epicId"],
8
- "properties": {
9
- "epicId": { "type": "integer", "minimum": 1 }
10
- },
11
- "additionalProperties": false
12
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json",
4
- "title": "acceptance.reconcile.waived",
5
- "description": "Emitted by AcceptanceReconciler when reconciliation is waived by the acceptance::n-a label. Distinct from acceptance.reconcile.skipped (which now means 'empty-spec' only) so the Finalizer can subscribe to .waived and route waived Epics through to PR creation while empty-spec Epics still terminate without a PR. The reason field is required and pinned to 'waiver'.",
6
- "type": "object",
7
- "required": ["baseRead", "reason"],
8
- "properties": {
9
- "baseRead": { "type": "boolean" },
10
- "reason": { "type": "string", "const": "waiver" }
11
- },
12
- "additionalProperties": false
13
- }
@@ -1,15 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.automerge.end.schema.json",
4
- "title": "epic.automerge.end",
5
- "description": "Emitted at the end of the automerge phase wrapper. merged=true means GitHub completed the squash; merged=false with a reason captures predicate-blocked or armed-but-pending outcomes.",
6
- "type": "object",
7
- "required": ["prUrl", "merged"],
8
- "properties": {
9
- "prUrl": { "type": "string", "format": "uri", "minLength": 1 },
10
- "merged": { "type": "boolean" },
11
- "reason": { "type": "string" },
12
- "epicId": { "type": "integer", "minimum": 1 }
13
- },
14
- "additionalProperties": false
15
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.automerge.start.schema.json",
4
- "title": "epic.automerge.start",
5
- "description": "Emitted at the start of the automerge phase wrapper (Phase 8.5, via lifecycle-emit.js). AutomergePredicate subscribes to this event (Story #3901) and evaluates the structured-signal verdict; it carries no checkOutcomes because Phase 8 already polled CI to green. Distinct from epic.merge.ready (predicate outcome) and epic.merge.armed (arm outcome).",
6
- "type": "object",
7
- "required": ["prUrl"],
8
- "properties": {
9
- "prUrl": { "type": "string", "format": "uri", "minLength": 1 },
10
- "epicId": { "type": "integer", "minimum": 1 }
11
- },
12
- "additionalProperties": false
13
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.blocked.schema.json",
4
- "title": "epic.blocked",
5
- "description": "Emitted by AcceptanceReconciler (on a failed acceptance reconciliation), MergeWatcher (on a merge-watch timeout), and — in headless runs (Story #4472) — AutomergePredicate (on a predicate refusal that would otherwise silently park) and AutomergeArmer (on a genuine arm failure) when the Epic transitions to agent::blocked. Subscribed by NotifyDispatcher, which fans the blocker out to the curated webhook channel. The reason field carries either a typed marker (timeout:<event>, merge-predicate:refused, merge-arm:failed, waiver, …) or a free-form summary; sourceStoryId scopes the blocker to a child Story when applicable.",
6
- "type": "object",
7
- "required": ["reason"],
8
- "properties": {
9
- "reason": { "type": "string", "minLength": 1 },
10
- "sourceStoryId": { "type": "integer", "minimum": 1 }
11
- },
12
- "additionalProperties": false
13
- }
@@ -1,12 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.cleanup.end.schema.json",
4
- "title": "epic.cleanup.end",
5
- "description": "Emitted by Cleaner when branch cleanup and temp archive complete.",
6
- "type": "object",
7
- "required": ["epicId"],
8
- "properties": {
9
- "epicId": { "type": "integer", "minimum": 1 }
10
- },
11
- "additionalProperties": false
12
- }
@@ -1,12 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.cleanup.start.schema.json",
4
- "title": "epic.cleanup.start",
5
- "description": "Emitted by Cleaner at the start of branch cleanup + temp archive.",
6
- "type": "object",
7
- "required": ["epicId"],
8
- "properties": {
9
- "epicId": { "type": "integer", "minimum": 1 }
10
- },
11
- "additionalProperties": false
12
- }
@@ -1,12 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.close.end.schema.json",
4
- "title": "epic.close.end",
5
- "description": "Emitted when the close-tail phase finishes; AcceptanceReconciler subscribes to this event to gate finalize.",
6
- "type": "object",
7
- "required": ["epicId"],
8
- "properties": {
9
- "epicId": { "type": "integer", "minimum": 1 }
10
- },
11
- "additionalProperties": false
12
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.complete.schema.json",
4
- "title": "epic.complete",
5
- "description": "Terminal event for a successful Epic run, emitted by Cleaner once the temp archive + branch reap complete. NotifyDispatcher subscribes to this event to fan the completion out to the curated webhook channel; the agent::done label flip is driven by the post-merge close path.",
6
- "type": "object",
7
- "required": ["epicId", "prUrl"],
8
- "properties": {
9
- "epicId": { "type": "integer", "minimum": 1 },
10
- "prUrl": { "type": "string", "format": "uri", "minLength": 1 }
11
- },
12
- "additionalProperties": false
13
- }
@@ -1,13 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.finalize.end.schema.json",
4
- "title": "epic.finalize.end",
5
- "description": "Emitted by Finalizer after the PR is opened (or short-circuited by gh pr list --head idempotency check).",
6
- "type": "object",
7
- "required": ["epicId", "prUrl"],
8
- "properties": {
9
- "epicId": { "type": "integer", "minimum": 1 },
10
- "prUrl": { "type": "string", "format": "uri", "minLength": 1 }
11
- },
12
- "additionalProperties": false
13
- }