mandrel 1.58.0 → 1.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/.agents/README.md +100 -98
  2. package/.agents/docs/SDLC.md +140 -141
  3. package/.agents/docs/configuration.md +16 -16
  4. package/.agents/docs/workflows.md +7 -8
  5. package/.agents/instructions.md +12 -11
  6. package/.agents/personas/architect.md +1 -1
  7. package/.agents/personas/product.md +1 -1
  8. package/.agents/personas/project-manager.md +14 -14
  9. package/.agents/personas/technical-writer.md +1 -1
  10. package/.agents/rules/changelog-style.md +5 -5
  11. package/.agents/rules/git-conventions.md +3 -3
  12. package/.agents/schemas/agentrc.schema.json +3 -3
  13. package/.agents/schemas/audit-rules.json +20 -0
  14. package/.agents/schemas/dispatch-manifest.json +4 -4
  15. package/.agents/schemas/epic-spec.schema.json +15 -45
  16. package/.agents/schemas/lifecycle/README.md +1 -1
  17. package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +1 -1
  18. package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +1 -1
  20. package/.agents/schemas/validation-evidence.schema.json +1 -1
  21. package/.agents/scripts/README.md +1 -1
  22. package/.agents/scripts/acceptance-eval.js +21 -4
  23. package/.agents/scripts/acceptance-spec-reconciler.js +2 -2
  24. package/.agents/scripts/analyze-execution.js +2 -2
  25. package/.agents/scripts/assert-branch.js +1 -3
  26. package/.agents/scripts/audit-to-stories.js +1 -1
  27. package/.agents/scripts/bootstrap.js +1 -1
  28. package/.agents/scripts/check-arch-cycles.js +360 -0
  29. package/.agents/scripts/check-doc-links.js +2 -3
  30. package/.agents/scripts/coverage-capture.js +24 -3
  31. package/.agents/scripts/diagnose-friction.js +1 -1
  32. package/.agents/scripts/dispatcher.js +2 -2
  33. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  34. package/.agents/scripts/epic-audit-prepare.js +3 -3
  35. package/.agents/scripts/epic-deliver-note-intervention.js +2 -2
  36. package/.agents/scripts/epic-deliver-preflight.js +11 -9
  37. package/.agents/scripts/epic-deliver-prepare.js +13 -5
  38. package/.agents/scripts/epic-execute-record-wave.js +5 -5
  39. package/.agents/scripts/epic-plan-healthcheck.js +6 -10
  40. package/.agents/scripts/epic-plan-spec-validate.js +1 -1
  41. package/.agents/scripts/epic-reconcile.js +11 -29
  42. package/.agents/scripts/evidence-gate.js +2 -2
  43. package/.agents/scripts/generate-workflows-doc.js +1 -1
  44. package/.agents/scripts/git-rebase-and-resolve.js +1 -1
  45. package/.agents/scripts/hierarchy-gate.js +40 -24
  46. package/.agents/scripts/lib/ITicketingProvider.js +1 -1
  47. package/.agents/scripts/lib/audit-suite/selector.js +1 -1
  48. package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +2 -2
  49. package/.agents/scripts/lib/baseline-snapshot.js +7 -7
  50. package/.agents/scripts/lib/baselines/kinds/coverage.js +33 -149
  51. package/.agents/scripts/lib/baselines/kinds/duplication.js +27 -116
  52. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +192 -0
  53. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +34 -133
  54. package/.agents/scripts/lib/baselines/kinds/maintainability.js +31 -124
  55. package/.agents/scripts/lib/baselines/kinds/mutation.js +25 -111
  56. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +59 -0
  57. package/.agents/scripts/lib/baselines/maintainability-baseline-save.js +37 -0
  58. package/.agents/scripts/lib/baselines/writer.js +1 -1
  59. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  60. package/.agents/scripts/lib/bdd-scenario-scanner.js +3 -3
  61. package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +1 -1
  62. package/.agents/scripts/lib/bootstrap/branch-protection.js +1 -1
  63. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +1 -1
  64. package/.agents/scripts/lib/bootstrap/commit-push.js +2 -2
  65. package/.agents/scripts/lib/close-validation/commands.js +188 -0
  66. package/.agents/scripts/lib/close-validation/gates.js +235 -0
  67. package/.agents/scripts/lib/close-validation/process.js +101 -0
  68. package/.agents/scripts/lib/close-validation/projections/maintainability.js +1 -1
  69. package/.agents/scripts/lib/close-validation/runner.js +325 -0
  70. package/.agents/scripts/lib/close-validation/telemetry.js +70 -0
  71. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  72. package/.agents/scripts/lib/config/explain.js +1 -1
  73. package/.agents/scripts/lib/config/quality.js +6 -6
  74. package/.agents/scripts/lib/config/runners.js +2 -2
  75. package/.agents/scripts/lib/config/runtime.js +1 -1
  76. package/.agents/scripts/lib/config/temp-paths.js +2 -2
  77. package/.agents/scripts/lib/config-resolver.js +2 -5
  78. package/.agents/scripts/lib/config-settings-schema-delivery.js +2 -2
  79. package/.agents/scripts/lib/config-settings-schema-quality.js +1 -1
  80. package/.agents/scripts/lib/config-settings-schema.js +3 -3
  81. package/.agents/scripts/lib/coverage-capture.js +147 -4
  82. package/.agents/scripts/lib/cpu-pool.js +14 -0
  83. package/.agents/scripts/lib/crap-utils.js +6 -11
  84. package/.agents/scripts/lib/duplicate-search.js +1 -1
  85. package/.agents/scripts/lib/dynamic-workflow/capability.js +1 -1
  86. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +87 -0
  87. package/.agents/scripts/lib/epic-plan-clarity.js +1 -1
  88. package/.agents/scripts/lib/epic-plan-ideation.js +1 -1
  89. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +1 -1
  90. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +1 -1
  91. package/.agents/scripts/lib/findings/classify-finding.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +10 -10
  93. package/.agents/scripts/lib/git-utils.js +24 -22
  94. package/.agents/scripts/lib/label-constants.js +3 -4
  95. package/.agents/scripts/lib/label-taxonomy.js +3 -8
  96. package/.agents/scripts/lib/maintainability-engine.js +1 -1
  97. package/.agents/scripts/lib/maintainability-utils.js +4 -187
  98. package/.agents/scripts/lib/observability/perf-report-readers.js +32 -23
  99. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +81 -7
  100. package/.agents/scripts/lib/orchestration/code-review.js +95 -82
  101. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +8 -9
  102. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +3 -3
  103. package/.agents/scripts/lib/orchestration/detectors-phase.js +2 -2
  104. package/.agents/scripts/lib/orchestration/dispatch-engine.js +30 -38
  105. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +14 -37
  106. package/.agents/scripts/lib/orchestration/epic-cleanup.js +1 -1
  107. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +22 -22
  108. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +1 -1
  109. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +7 -21
  110. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +3 -3
  111. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +2 -2
  112. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +206 -58
  113. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +1 -1
  114. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +27 -3
  115. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +1 -1
  116. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +28 -8
  117. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +1 -1
  118. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +3 -3
  119. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +4 -4
  120. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +3 -3
  121. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +13 -41
  122. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +7 -7
  123. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +2 -3
  124. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +2 -8
  125. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +4 -4
  126. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +103 -0
  127. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +22 -64
  128. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +38 -76
  129. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +4 -4
  130. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +10 -10
  131. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +8 -20
  132. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +7 -15
  133. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +72 -41
  134. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +2 -4
  135. package/.agents/scripts/lib/orchestration/file-assumptions.js +6 -5
  136. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +1 -1
  137. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +2 -2
  138. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +1 -1
  139. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +144 -0
  140. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +1 -1
  141. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +3 -3
  142. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +1 -1
  143. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +1 -1
  144. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +1 -1
  145. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +1 -1
  146. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +1 -1
  147. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  148. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +1 -1
  149. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +1 -1
  150. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +8 -8
  151. package/.agents/scripts/lib/orchestration/manifest-builder.js +5 -5
  152. package/.agents/scripts/lib/orchestration/parked-follow-ons.js +2 -2
  153. package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +5 -5
  154. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +3 -3
  155. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +3 -3
  156. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +7 -7
  157. package/.agents/scripts/lib/orchestration/preflight-cache.js +36 -13
  158. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +1 -1
  159. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +1 -1
  160. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +2 -2
  161. package/.agents/scripts/lib/orchestration/retro-runner.js +3 -3
  162. package/.agents/scripts/lib/orchestration/review-depth.js +1 -1
  163. package/.agents/scripts/lib/orchestration/review-providers/codex.js +5 -60
  164. package/.agents/scripts/lib/orchestration/review-providers/native.js +7 -6
  165. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +105 -0
  166. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +7 -59
  167. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +2 -4
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +1 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +1 -1
  170. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +2 -4
  171. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +32 -35
  172. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +1 -2
  173. package/.agents/scripts/lib/orchestration/spec-freshness.js +1 -1
  174. package/.agents/scripts/lib/orchestration/spec-renderer.js +36 -73
  175. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  176. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +451 -503
  177. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +8 -2
  178. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +47 -2
  179. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +2 -2
  180. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +1 -1
  181. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +358 -54
  182. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +1 -1
  183. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +3 -2
  184. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +32 -5
  185. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +5 -18
  186. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +3 -3
  187. package/.agents/scripts/lib/orchestration/story-close-recovery.js +33 -16
  188. package/.agents/scripts/lib/orchestration/story-reachability.js +47 -0
  189. package/.agents/scripts/lib/orchestration/task-body-validator.js +6 -6
  190. package/.agents/scripts/lib/orchestration/ticket-lease.js +1 -1
  191. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +4 -35
  192. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +1 -10
  193. package/.agents/scripts/lib/orchestration/ticket-validator.js +25 -70
  194. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +44 -73
  195. package/.agents/scripts/lib/orchestration/ticketing/reads.js +16 -7
  196. package/.agents/scripts/lib/orchestration/ticketing/state.js +53 -439
  197. package/.agents/scripts/lib/orchestration/ticketing/transition.js +471 -0
  198. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  199. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +3 -3
  200. package/.agents/scripts/lib/orchestration/wave-record-projection.js +2 -8
  201. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -1
  202. package/.agents/scripts/lib/preflight-runner.js +1 -1
  203. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +4 -5
  204. package/.agents/scripts/lib/presentation/manifest-builder.js +28 -34
  205. package/.agents/scripts/lib/presentation/manifest-formatter.js +3 -4
  206. package/.agents/scripts/lib/presentation/manifest-helpers.js +1 -1
  207. package/.agents/scripts/lib/presentation/manifest-procedures.js +4 -4
  208. package/.agents/scripts/lib/presentation/manifest-render-waves.js +4 -23
  209. package/.agents/scripts/lib/presentation/manifest-renderer.js +1 -1
  210. package/.agents/scripts/lib/presentation/manifest-story-views.js +2 -11
  211. package/.agents/scripts/lib/project-root.js +17 -0
  212. package/.agents/scripts/lib/signals/schema.js +1 -1
  213. package/.agents/scripts/lib/spec/index.js +1 -1
  214. package/.agents/scripts/lib/spec/loader.js +2 -2
  215. package/.agents/scripts/lib/spec/state.js +7 -16
  216. package/.agents/scripts/lib/story-adjacency.js +76 -0
  217. package/.agents/scripts/lib/story-init/context-resolver.js +3 -3
  218. package/.agents/scripts/lib/story-init/state-transitioner.js +2 -2
  219. package/.agents/scripts/lib/story-init/task-graph-builder.js +7 -7
  220. package/.agents/scripts/lib/story-lifecycle.js +9 -9
  221. package/.agents/scripts/lib/story-plan.js +1 -1
  222. package/.agents/scripts/lib/templates/decomposer-prompts.js +59 -52
  223. package/.agents/scripts/lib/transpile.js +93 -0
  224. package/.agents/scripts/lib/wave-runner/tick.js +4 -153
  225. package/.agents/scripts/lib/workers/crap-worker.js +1 -1
  226. package/.agents/scripts/lib/workers/maintainability-report-worker.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/creation.js +20 -2
  228. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +90 -0
  229. package/.agents/scripts/lib/worktree/lifecycle/reap.js +26 -8
  230. package/.agents/scripts/lib/worktree/node-modules-strategy.js +74 -0
  231. package/.agents/scripts/lifecycle-emit-story-dispatch.js +1 -1
  232. package/.agents/scripts/lifecycle-emit.js +1 -1
  233. package/.agents/scripts/providers/github/board-add.js +1 -1
  234. package/.agents/scripts/providers/github/errors.js +1 -1
  235. package/.agents/scripts/providers/github/mappers.js +2 -2
  236. package/.agents/scripts/providers/github/tickets.js +114 -10
  237. package/.agents/scripts/resync-status-column.js +1 -1
  238. package/.agents/scripts/retro-run.js +2 -2
  239. package/.agents/scripts/run-lint.js +10 -1
  240. package/.agents/scripts/run-tests.js +24 -4
  241. package/.agents/scripts/single-story-init.js +1 -1
  242. package/.agents/scripts/stories-wave-tick.js +13 -10
  243. package/.agents/scripts/story-close.js +1 -1
  244. package/.agents/scripts/story-init.js +162 -26
  245. package/.agents/scripts/story-phase.js +5 -5
  246. package/.agents/scripts/story-plan.js +3 -3
  247. package/.agents/scripts/sync-branch-from-base.js +2 -2
  248. package/.agents/scripts/validate-docs-freshness.js +1 -1
  249. package/.agents/scripts/wave-tick.js +1 -1
  250. package/.agents/skills/core/analyze-execution/SKILL.md +2 -2
  251. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +21 -26
  252. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +23 -56
  253. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +4 -4
  254. package/.agents/skills/core/hydrate-context/SKILL.md +2 -2
  255. package/.agents/skills/core/idea-refinement/SKILL.md +4 -4
  256. package/.agents/skills/core/knowledge-transfer/SKILL.md +2 -2
  257. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +1 -1
  258. package/.agents/skills/core/scope-triage/SKILL.md +9 -10
  259. package/.agents/skills/core/using-agent-skills/SKILL.md +1 -1
  260. package/.agents/skills/skills.index.json +7 -7
  261. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +1 -1
  262. package/.agents/templates/agent-protocol.md +2 -2
  263. package/.agents/workflows/agents-update.md +2 -2
  264. package/.agents/workflows/audit-architecture.md +2 -2
  265. package/.agents/workflows/audit-clean-code.md +2 -2
  266. package/.agents/workflows/audit-dependencies.md +1 -1
  267. package/.agents/workflows/audit-devops.md +1 -1
  268. package/.agents/workflows/audit-documentation.md +226 -0
  269. package/.agents/workflows/audit-lighthouse.md +1 -1
  270. package/.agents/workflows/audit-performance.md +2 -2
  271. package/.agents/workflows/audit-privacy.md +1 -1
  272. package/.agents/workflows/audit-quality.md +2 -2
  273. package/.agents/workflows/audit-security.md +2 -2
  274. package/.agents/workflows/audit-seo.md +1 -1
  275. package/.agents/workflows/audit-sre.md +1 -1
  276. package/.agents/workflows/audit-to-stories.md +10 -10
  277. package/.agents/workflows/audit-ux-ui.md +1 -1
  278. package/.agents/workflows/deliver.md +85 -0
  279. package/.agents/workflows/explain.md +3 -3
  280. package/.agents/workflows/git-merge-pr.md +1 -1
  281. package/.agents/workflows/git-pr-all.md +13 -10
  282. package/.agents/workflows/git-push.md +6 -3
  283. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  284. package/.agents/workflows/helpers/acceptance-self-eval.md +1 -1
  285. package/.agents/workflows/helpers/code-review.md +5 -5
  286. package/.agents/workflows/{epic-deliver.md → helpers/deliver-epic.md} +59 -66
  287. package/.agents/workflows/{story-deliver.md → helpers/deliver-stories.md} +25 -25
  288. package/.agents/workflows/helpers/diagnose.md +1 -1
  289. package/.agents/workflows/helpers/epic-audit.md +6 -6
  290. package/.agents/workflows/helpers/epic-deliver-story.md +28 -39
  291. package/.agents/workflows/helpers/epic-plan-decompose.md +23 -23
  292. package/.agents/workflows/helpers/epic-plan-spec.md +6 -6
  293. package/.agents/workflows/helpers/epic-testing.md +3 -3
  294. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  295. package/.agents/workflows/{epic-plan.md → helpers/plan-epic.md} +84 -84
  296. package/.agents/workflows/{story-plan.md → helpers/plan-story.md} +43 -43
  297. package/.agents/workflows/helpers/signals.md +1 -1
  298. package/.agents/workflows/helpers/single-story-deliver.md +12 -11
  299. package/.agents/workflows/helpers/worktree-lifecycle.md +18 -18
  300. package/.agents/workflows/onboard.md +21 -20
  301. package/.agents/workflows/plan.md +89 -0
  302. package/.agents/workflows/qa-explore.md +1 -1
  303. package/.agents/workflows/qa-run-harness.md +1 -1
  304. package/README.md +17 -20
  305. package/docs/CHANGELOG.md +1149 -0
  306. package/lib/cli/__tests__/update-changelog-surface.test.js +357 -0
  307. package/lib/cli/__tests__/update-reexec.test.js +513 -0
  308. package/lib/cli/init.js +338 -0
  309. package/lib/cli/update.js +413 -52
  310. package/package.json +3 -1
  311. package/.agents/scripts/lib/auto-refresh-baselines.js +0 -308
  312. package/.agents/scripts/lib/close-validation.js +0 -897
  313. package/.agents/scripts/lib/orchestration/cascade-grouping.js +0 -275
  314. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +0 -69
  315. package/.agents/scripts/lib/orchestration/reconciler.js +0 -137
  316. package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +0 -221
  317. package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +0 -123
  318. package/.agents/scripts/lib/task-utils.js +0 -26
  319. package/.agents/scripts/story-deliver-prepare.js +0 -267
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/epic-spec.schema.json",
4
- "version": "3.0.0",
4
+ "version": "4.0.0",
5
5
  "title": "Epic Spec (declarative structural SSOT)",
6
- "description": "Canonical structural specification for an Epic and its children (Features, Stories), consumed by the epic-spec-reconciler. Lives on disk as .agents/epics/<epic-id>.yaml. The reconciler diffs this spec against live GitHub state and applies structural mutations (Create/Update/Close/Relink) behind a dry-run default. Slugs are stable, GH-incarnation-independent identifiers used for intra-spec dependency edges (dependsOn) and the spec ↔ GH-issue mapping persisted in the sibling .agents/epics/<epic-id>.state.json. This schema describes the 3-tier structural shape only (Epic → Feature → Story with inline Story-level acceptance[]/verify[]); agent-execution state (agent::* labels) is intentionally not modelled — that surface belongs to the wave-runner, not the reconciler.",
6
+ "description": "Canonical structural specification for an Epic and its child Stories, consumed by the epic-spec-reconciler. Lives on disk as .agents/epics/<epic-id>.yaml. The reconciler diffs this spec against live GitHub state and applies structural mutations (Create/Update/Close/Relink) behind a dry-run default. Slugs are stable, GH-incarnation-independent identifiers used for intra-spec dependency edges (dependsOn) and the spec ↔ GH-issue mapping persisted in the sibling .agents/epics/<epic-id>.state.json. This schema describes the 2-tier structural shape only (Epic → Story with inline Story-level acceptance[]/verify[]); agent-execution state (agent::* labels) is intentionally not modelled — that surface belongs to the wave-runner, not the reconciler.",
7
7
  "type": "object",
8
8
  "additionalProperties": false,
9
- "required": ["epic", "features"],
9
+ "required": ["epic", "stories"],
10
10
  "properties": {
11
11
  "$schema": {
12
12
  "type": "string",
@@ -15,16 +15,16 @@
15
15
  "version": {
16
16
  "type": "string",
17
17
  "pattern": "^\\d+\\.\\d+\\.\\d+$",
18
- "description": "Optional schema-shape identifier. Identification-only — readers MUST NOT branch behavior on this value. Bumped to 3.0.0 when Task-level decomposition was removed under the 3-tier collapse (Epic #3078)."
18
+ "description": "Optional schema-shape identifier. Identification-only — readers MUST NOT branch behavior on this value. Bumped to 4.0.0 when the Feature tier was removed under the 2-tier collapse (Story #4041); 3.0.0 removed Task-level decomposition (Epic #3078)."
19
19
  },
20
20
  "epic": {
21
21
  "$ref": "#/$defs/epic",
22
22
  "description": "The Epic this spec describes. Carries the GH issue number, human title, and structural labels (type::epic plus any project-specific structural tags). Execution-state labels (agent::*) MUST NOT appear here."
23
23
  },
24
- "features": {
24
+ "stories": {
25
25
  "type": "array",
26
- "description": "Ordered list of Features under this Epic. Order is preserved for human readability but is not load-bearing — wave ordering is driven by stories[].wave + dependsOn, not by feature position.",
27
- "items": { "$ref": "#/$defs/feature" }
26
+ "description": "Ordered list of Stories under this Epic. Order is preserved for human readability but is not load-bearing — execution order is driven by stories[].wave + dependsOn, not by array position.",
27
+ "items": { "$ref": "#/$defs/story" }
28
28
  },
29
29
  "gates": {
30
30
  "$ref": "#/$defs/gates",
@@ -36,12 +36,12 @@
36
36
  "type": "string",
37
37
  "minLength": 1,
38
38
  "pattern": "^[a-z0-9][a-z0-9-]*$",
39
- "description": "Stable kebab-case identifier used for intra-spec dependency edges (dependsOn) and the spec ↔ GH-issue mapping. Slugs must be unique within their scope (features within an epic, stories within a feature). Slugs are not GH issue numbers — they survive Epic re-incarnations and ticket renumbering. Pattern: lowercase alphanumeric + hyphens, must start with [a-z0-9]."
39
+ "description": "Stable kebab-case identifier used for intra-spec dependency edges (dependsOn) and the spec ↔ GH-issue mapping. Slugs must be unique within the Epic's stories[] array. Slugs are not GH issue numbers — they survive Epic re-incarnations and ticket renumbering. Pattern: lowercase alphanumeric + hyphens, must start with [a-z0-9]."
40
40
  },
41
41
  "label": {
42
42
  "type": "string",
43
43
  "minLength": 1,
44
- "description": "A GitHub label name. Structural labels only (e.g. type::epic, type::feature, type::story, persona::*, area::*). Execution-state labels in the AGENT_LABELS allow-list (agent::*) MUST NOT appear in the spec — they are owned by the wave-runner and the reconciler refuses to write them."
44
+ "description": "A GitHub label name. Structural labels only (e.g. type::epic, type::story, persona::*, area::*). Execution-state labels in the AGENT_LABELS allow-list (agent::*) MUST NOT appear in the spec — they are owned by the wave-runner and the reconciler refuses to write them."
45
45
  },
46
46
  "labels": {
47
47
  "type": "array",
@@ -53,7 +53,7 @@
53
53
  "type": "object",
54
54
  "additionalProperties": false,
55
55
  "required": ["id", "title"],
56
- "description": "Top-level Epic descriptor. Unlike Features/Stories (which are slug-keyed and may not exist in GH yet), the Epic always has a real GH issue number — the spec lives at .agents/epics/<id>.yaml and that <id> is the same number used here.",
56
+ "description": "Top-level Epic descriptor. Unlike Stories (which are slug-keyed and may not exist in GH yet), the Epic always has a real GH issue number — the spec lives at .agents/epics/<id>.yaml and that <id> is the same number used here.",
57
57
  "properties": {
58
58
  "id": {
59
59
  "type": "integer",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "body": {
69
69
  "type": "string",
70
- "description": "Optional Epic body. When present, the reconciler updates the GH issue body to match. When omitted, the GH issue body is left untouched (allowing operator-curated bodies to coexist with structural reconciliation). Multi-line markdown is fully supported."
70
+ "description": "Optional Epic body. When present, the reconciler updates the GH issue body to match. When omitted, the GH issue body is left untouched (allowing operator-curated bodies to coexist with structural reconciliation). Multi-line markdown is fully supported. Thematic grouping of Stories — formerly the Feature tier's job — lives here (and in the Tech Spec) as prose."
71
71
  },
72
72
  "labels": {
73
73
  "$ref": "#/$defs/labels",
@@ -75,45 +75,15 @@
75
75
  }
76
76
  }
77
77
  },
78
- "feature": {
79
- "type": "object",
80
- "additionalProperties": false,
81
- "required": ["slug", "title", "stories"],
82
- "description": "A Feature groups Stories under a common product/architectural theme. Features themselves are GitHub issues (type::feature) when materialised by the reconciler — they carry no execution state, only structure.",
83
- "properties": {
84
- "slug": {
85
- "$ref": "#/$defs/slug",
86
- "description": "Stable kebab-case identifier for this Feature. Must be unique within the parent Epic's features[] array."
87
- },
88
- "title": {
89
- "type": "string",
90
- "minLength": 1,
91
- "description": "Human-readable Feature title."
92
- },
93
- "body": {
94
- "type": "string",
95
- "description": "Optional Feature body. Same semantics as epic.body — written by the reconciler when present, left untouched when omitted."
96
- },
97
- "labels": {
98
- "$ref": "#/$defs/labels",
99
- "description": "Structural labels attached to this Feature (e.g. type::feature plus any project-specific structural tags)."
100
- },
101
- "stories": {
102
- "type": "array",
103
- "description": "Ordered list of Stories under this Feature. Order is for readability; execution order is driven by stories[].wave + dependsOn.",
104
- "items": { "$ref": "#/$defs/story" }
105
- }
106
- }
107
- },
108
78
  "story": {
109
79
  "type": "object",
110
80
  "additionalProperties": false,
111
81
  "required": ["slug", "title", "wave"],
112
- "description": "A Story is the unit of agent execution — exactly one Story branch (story-<id>) and exactly one Story sub-agent per Story per wave. Stories declare their wave assignment and inter-Story dependencies via slug references; the wave-runner consumes these to schedule the parallel fan-out. Under the 3-tier collapse (Epic #3078), Stories carry inline acceptance[] + verify[] arrays that the Story sub-agent treats as the Goal/Changes/Acceptance/Verify surface; there is no child-Task decomposition.",
82
+ "description": "A Story is the unit of agent execution — exactly one Story branch (story-<id>) and exactly one Story sub-agent per Story per wave. Stories are direct children of the Epic (2-tier hierarchy, Story #4041). They declare their wave assignment and inter-Story dependencies via slug references; the wave-runner consumes these to schedule the parallel fan-out. Stories carry inline acceptance[] + verify[] arrays that the Story sub-agent treats as the Goal/Changes/Acceptance/Verify surface; there is no child-Task decomposition.",
113
83
  "properties": {
114
84
  "slug": {
115
85
  "$ref": "#/$defs/slug",
116
- "description": "Stable kebab-case identifier for this Story. Must be unique within the parent Feature's stories[] array, and is the value referenced by sibling Stories' dependsOn arrays."
86
+ "description": "Stable kebab-case identifier for this Story. Must be unique within the Epic's stories[] array, and is the value referenced by sibling Stories' dependsOn arrays."
117
87
  },
118
88
  "title": {
119
89
  "type": "string",
@@ -144,7 +114,7 @@
144
114
  },
145
115
  "acceptance": {
146
116
  "type": "array",
147
- "description": "Inline acceptance criteria for this Story (Epic #3078 — 3-tier collapse). Each entry is a single user-visible acceptance statement that the Story-level agent must satisfy. Acts as the Story-level outcome contract that the Story sub-agent treats as the Goal/Changes/Acceptance/Verify surface.",
117
+ "description": "Inline acceptance criteria for this Story. Each entry is a single user-visible acceptance statement that the Story-level agent must satisfy. Acts as the Story-level outcome contract that the Story sub-agent treats as the Goal/Changes/Acceptance/Verify surface.",
148
118
  "items": {
149
119
  "type": "string",
150
120
  "minLength": 1,
@@ -153,7 +123,7 @@
153
123
  },
154
124
  "verify": {
155
125
  "type": "array",
156
- "description": "Inline verification commands for this Story (Epic #3078 — 3-tier collapse). Each entry is a shell-runnable command (typically a contract test invocation) that proves the corresponding acceptance[] entries hold.",
126
+ "description": "Inline verification commands for this Story. Each entry is a shell-runnable command (typically a contract test invocation) that proves the corresponding acceptance[] entries hold.",
157
127
  "items": {
158
128
  "type": "string",
159
129
  "minLength": 1,
@@ -1,7 +1,7 @@
1
1
  # Lifecycle event schemas
2
2
 
3
3
  JSON Schemas for the lifecycle event taxonomy consumed by the
4
- `/epic-deliver` lifecycle bus
4
+ `/deliver` lifecycle bus
5
5
  (`lib/orchestration/lifecycle/bus.js`). The bus validates every
6
6
  emit payload against one of these schemas before invoking
7
7
  listeners; a schema mismatch fails the emit and propagates the
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/story.dispatch.end.schema.json",
4
4
  "title": "story.dispatch.end",
5
- "description": "Appended to the Epic ledger by emit-story-dispatch-end.js when a child story sub-agent returns, so /epic-deliver's idle watchdog can subtract completed Stories from the in-flight set. Subscribed by CheckpointPointerWriter via SUBSCRIBED_END_EVENTS. Sibling ordering within a wave is not guaranteed; ordering between waves is.",
5
+ "description": "Appended to the Epic ledger by emit-story-dispatch-end.js when a child story sub-agent returns, so /deliver's idle watchdog can subtract completed Stories from the in-flight set. Subscribed by CheckpointPointerWriter via SUBSCRIBED_END_EVENTS. Sibling ordering within a wave is not guaranteed; ordering between waves is.",
6
6
  "type": "object",
7
7
  "required": ["storyId", "outcome", "durationMs"],
8
8
  "properties": {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/story.dispatch.start.schema.json",
4
4
  "title": "story.dispatch.start",
5
- "description": "Emitted before a story is handed to the host-LLM for Agent-tool fanout. lifecycle-emit-story-dispatch.js appends the {storyId, waveIndex, dispatchedAt, attempt} shape to the Epic ledger so /epic-deliver's host loop can durably ledger every dispatch attempt for in-flight reconciliation (Story #2891).",
5
+ "description": "Emitted before a story is handed to the host-LLM for Agent-tool fanout. lifecycle-emit-story-dispatch.js appends the {storyId, waveIndex, dispatchedAt, attempt} shape to the Epic ledger so /deliver's host loop can durably ledger every dispatch attempt for in-flight reconciliation (Story #2891).",
6
6
  "type": "object",
7
7
  "required": ["storyId", "waveIndex"],
8
8
  "properties": {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/story.heartbeat.schema.json",
4
4
  "title": "story.heartbeat",
5
- "description": "Emitted by story-phase.js inside a Story's implementation loop. Surfaces the in-progress Story as an inspectable ledger event so /epic-deliver's host-loop reconciler can confirm a long Story is still making forward progress between dispatch and merge — distinct from story.dispatch.start (one per Story per attempt) and story.merged (one per Story per close). The 3-tier hierarchy has no child Task tickets, so the heartbeat carries phase info only. The optional operator field (Story #3480) records the handle holding the assignee-as-lease claim on the Story so the ticket-lease primitive can decide claim liveness from the most-recent heartbeat for a given owner.",
5
+ "description": "Emitted by story-phase.js inside a Story's implementation loop. Surfaces the in-progress Story as an inspectable ledger event so /deliver's host-loop reconciler can confirm a long Story is still making forward progress between dispatch and merge — distinct from story.dispatch.start (one per Story per attempt) and story.merged (one per Story per close). The 2-tier hierarchy has no child Task tickets, so the heartbeat carries phase info only. The optional operator field (Story #3480) records the handle holding the assignee-as-lease claim on the Story so the ticket-lease primitive can decide claim liveness from the most-recent heartbeat for a given owner.",
6
6
  "type": "object",
7
7
  "required": ["event", "storyId", "epicId", "phase", "timestamp"],
8
8
  "properties": {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "validation-evidence",
4
4
  "title": "Validation Evidence",
5
- "description": "Per-scope record of which validation gates have passed against which commit SHA. Written by lib/validation-evidence.js under the per-Epic temp tree at temp/epic-<epicId>/validation-evidence.json (Epic-scoped) or temp/epic-<epicId>/stories/story-<storyId>/validation-evidence.json (Story-scoped); both are gitignored via temp/. Consumed by close-validation, epic-code-review, and /epic-deliver Phase 3 (close-validation) to skip identical re-runs against an already-validated tree. The `storyId` field carries the scope id and equals the epic id for Epic-scoped records.",
5
+ "description": "Per-scope record of which validation gates have passed against which commit SHA. Written by lib/validation-evidence.js under the per-Epic temp tree at temp/epic-<epicId>/validation-evidence.json (Epic-scoped) or temp/epic-<epicId>/stories/story-<storyId>/validation-evidence.json (Story-scoped); both are gitignored via temp/. Consumed by close-validation, epic-code-review, and /deliver Phase 3 (close-validation) to skip identical re-runs against an already-validated tree. The `storyId` field carries the scope id and equals the epic id for Epic-scoped records.",
6
6
  "type": "object",
7
7
  "required": ["storyId", "schemaVersion", "records"],
8
8
  "properties": {
@@ -49,7 +49,7 @@ that the file was meaningfully updated during this Epic's lifecycle
49
49
 
50
50
  **When to run.** Optional. Useful as a pre-merge spot check when an
51
51
  Epic should have produced documentation updates; the standard
52
- `/epic-deliver` flow does **not** invoke this gate today.
52
+ `/deliver` flow does **not** invoke this gate today.
53
53
 
54
54
  **Usage.**
55
55
 
@@ -16,7 +16,7 @@
16
16
  * and the resolved, undisableable round cap
17
17
  * (`delivery.acceptanceEval.maxRounds`, clamped to `[1, ceiling]`).
18
18
  * 3. Emit one per-criterion `acceptance-eval` signal into the retro /
19
- * feedback substrate so the retro and `/epic-plan` Phase 0 feedback
19
+ * feedback substrate so the retro and `/plan` Phase 0 feedback
20
20
  * fetch can see which acceptance items needed rework and the round
21
21
  * count.
22
22
  * 4. Print a single JSON envelope and exit:
@@ -61,6 +61,7 @@ import { appendSignal } from './lib/observability/signals-writer.js';
61
61
  import {
62
62
  buildAcceptanceEvalSignal,
63
63
  decideAcceptanceEval,
64
+ deriveAcceptanceEvalRound,
64
65
  } from './lib/orchestration/acceptance-eval-decision.js';
65
66
 
66
67
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -152,17 +153,33 @@ function parseCliArgs(argv) {
152
153
  * @param {object} args.verdict — validated verdict object.
153
154
  * @param {object} args.config — resolved `.agentrc.json`.
154
155
  * @param {boolean} args.emitSignal
156
+ * @param {number} [args.round] — explicit round override (tests). When
157
+ * absent, the round is derived by counting prior `acceptance-eval`
158
+ * signals in the Story's `signals.ndjson` (Story #4019); the verdict's
159
+ * self-reported `round` is never load-bearing for the cap.
155
160
  * @param {object} [deps]
156
161
  * @param {Function} [deps.appendSignalFn]
162
+ * @param {Function} [deps.deriveRoundFn]
157
163
  * @returns {Promise<{ envelope: object, exitCode: number }>}
158
164
  */
159
165
  export async function runAcceptanceEval(
160
- { storyId, epicId, verdict, config, emitSignal },
166
+ { storyId, epicId, verdict, config, emitSignal, round },
161
167
  deps = {},
162
168
  ) {
163
- const { appendSignalFn = appendSignal } = deps;
169
+ const {
170
+ appendSignalFn = appendSignal,
171
+ deriveRoundFn = deriveAcceptanceEvalRound,
172
+ } = deps;
164
173
  const { maxRounds } = getAcceptanceEval(config);
165
- const outcome = decideAcceptanceEval({ verdict, maxRounds });
174
+ const resolvedRound =
175
+ Number.isInteger(round) && round >= 1
176
+ ? round
177
+ : deriveRoundFn({ epicId: epicId ?? null, storyId, config });
178
+ const outcome = decideAcceptanceEval({
179
+ verdict,
180
+ maxRounds,
181
+ round: resolvedRound,
182
+ });
166
183
 
167
184
  let signalEmitted = false;
168
185
  if (emitSignal) {
@@ -301,7 +301,7 @@ export function renderBlockerMessage({
301
301
  lines.push(` Pending (@pending-only coverage): ${pending.join(', ')}`);
302
302
  }
303
303
  lines.push(
304
- `Author or de-pend scenarios under tests/features/** tagged @epic-${epicId}-ac-<n> so every AC ID is satisfied, then re-run /epic-deliver.`,
304
+ `Author or de-pend scenarios under tests/features/** tagged @epic-${epicId}-ac-<n> so every AC ID is satisfied, then re-run /deliver.`,
305
305
  );
306
306
  return lines.join('\n');
307
307
  }
@@ -420,7 +420,7 @@ export async function reconcileAcceptanceSpec({
420
420
  }
421
421
  // Defence in depth — the start gate would normally catch this.
422
422
  throw new Error(
423
- `[acceptance-spec-reconciler] Epic #${epicId} has no linked context::acceptance-spec ticket and no acceptance::n-a waiver label. Re-run /epic-plan Phase 7 or apply the waiver.`,
423
+ `[acceptance-spec-reconciler] Epic #${epicId} has no linked context::acceptance-spec ticket and no acceptance::n-a waiver label. Re-run /plan Phase 7 or apply the waiver.`,
424
424
  );
425
425
  }
426
426
 
@@ -18,7 +18,7 @@
18
18
  * fetching each `story-perf-summary` structured comment from the
19
19
  * ticketing provider. Posts the
20
20
  * `<!-- structured:epic-perf-report -->` comment on the Epic ticket.
21
- * Run from the retro composer / `/epic-deliver` Phase 6.0.
21
+ * Run from the retro composer / `/deliver` Phase 6.0.
22
22
  *
23
23
  * Both modes are idempotent: `upsertStructuredComment` deletes the prior
24
24
  * marker before posting the new one.
@@ -27,7 +27,7 @@
27
27
  * NDJSON for a Story, no children for an Epic) so the close pipelines
28
28
  * never block on observability output. Hard failures (bad CLI args,
29
29
  * provider error, schema-violating payload) exit non-zero — the call
30
- * sites in post-merge-pipeline / `/epic-deliver` Phase 5 treat that
30
+ * sites in post-merge-pipeline / `/deliver` Phase 5 treat that
31
31
  * as a non-fatal warning.
32
32
  *
33
33
  * This file is a thin CLI: it wires the I/O readers from
@@ -20,11 +20,9 @@
20
20
  */
21
21
 
22
22
  import { fileURLToPath } from 'node:url';
23
-
24
- import { PROJECT_ROOT } from './lib/config-resolver.js';
25
23
  import { gitSpawn } from './lib/git-utils.js';
26
-
27
24
  import { Logger } from './lib/Logger.js';
25
+ import { PROJECT_ROOT } from './lib/project-root.js';
28
26
  export function assertBranch(expected, { cwd = PROJECT_ROOT } = {}) {
29
27
  if (!expected || typeof expected !== 'string') {
30
28
  return { ok: false, reason: 'missing --expected <branch>' };
@@ -13,7 +13,7 @@
13
13
  * stdout when --json is set).
14
14
  *
15
15
  * --emit-epic-seed --plan <plan.json> --out <path>
16
- * Read the plan envelope from disk, render the `/epic-plan --idea`
16
+ * Read the plan envelope from disk, render the `/plan --idea`
17
17
  * seed markdown, persist to --out.
18
18
  *
19
19
  * --emit-stories --plan <plan.json>
@@ -1353,7 +1353,7 @@ export async function main(argv = process.argv.slice(2), deps = {}) {
1353
1353
  // the failure is surfaced, not silently rolled back), but they MUST NOT
1354
1354
  // exit 0. `executeGithubBootstrap` records `report.github.error` instead
1355
1355
  // of throwing; detect it here and exit non-zero with a distinct final
1356
- // status line so `create-mandrel` and CI see the failure (Story #3898).
1356
+ // status line so `mandrel init` and CI see the failure (Story #3898).
1357
1357
  const githubError = result.state?.report?.github?.error;
1358
1358
  if (githubError) {
1359
1359
  Logger.error(