mandrel 1.94.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. package/.agents/README.md +116 -99
  2. package/.agents/agents/acceptance-critic.md +9 -7
  3. package/.agents/agents/story-worker.md +45 -51
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +498 -1287
  6. package/.agents/docs/agentrc-reference.json +185 -80
  7. package/.agents/docs/configuration.md +132 -190
  8. package/.agents/docs/execution-reference.md +51 -25
  9. package/.agents/docs/quality-gates.md +25 -33
  10. package/.agents/docs/workflows.md +8 -8
  11. package/.agents/instructions.md +113 -139
  12. package/.agents/rules/ci-remediation.md +11 -15
  13. package/.agents/rules/git-conventions-reference.md +48 -58
  14. package/.agents/rules/git-conventions.md +16 -22
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  16. package/.agents/schemas/agentrc.schema.json +83 -254
  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/retro.end.schema.json +1 -1
  24. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  25. package/.agents/schemas/signal-event.schema.json +3 -3
  26. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  27. package/.agents/schemas/validation-evidence.schema.json +1 -1
  28. package/.agents/scripts/acceptance-eval.js +22 -66
  29. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  30. package/.agents/scripts/audit-to-stories.js +7 -7
  31. package/.agents/scripts/boot-sweep.js +1 -1
  32. package/.agents/scripts/bootstrap.js +3 -3
  33. package/.agents/scripts/check-dead-exports.js +43 -104
  34. package/.agents/scripts/check-doc-links.js +2 -2
  35. package/.agents/scripts/check-lifecycle-lint.js +7 -10
  36. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  37. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  38. package/.agents/scripts/deliver-recover.js +122 -0
  39. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  40. package/.agents/scripts/evidence-gate.js +20 -50
  41. package/.agents/scripts/generate-skills-index.js +17 -1
  42. package/.agents/scripts/generate-workflows-doc.js +4 -4
  43. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  44. package/.agents/scripts/lib/Logger.js +6 -10
  45. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  46. package/.agents/scripts/lib/audit-suite/selector.js +328 -28
  47. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  48. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  49. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
  50. package/.agents/scripts/lib/baselines/reader.js +1 -6
  51. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  52. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  53. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  54. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  55. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  56. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  57. package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
  58. package/.agents/scripts/lib/checks/index.js +3 -2
  59. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  60. package/.agents/scripts/lib/checks/state.js +17 -248
  61. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
  62. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  63. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  64. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  65. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  66. package/.agents/scripts/lib/cli-args.js +39 -9
  67. package/.agents/scripts/lib/close-validation/gates.js +15 -15
  68. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  69. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  70. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  71. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  72. package/.agents/scripts/lib/config/ci.js +6 -31
  73. package/.agents/scripts/lib/config/delivery-routing.js +52 -35
  74. package/.agents/scripts/lib/config/explain.js +61 -48
  75. package/.agents/scripts/lib/config/github.js +7 -5
  76. package/.agents/scripts/lib/config/limits.js +29 -80
  77. package/.agents/scripts/lib/config/paths.js +0 -2
  78. package/.agents/scripts/lib/config/quality.js +12 -15
  79. package/.agents/scripts/lib/config/runners.js +20 -66
  80. package/.agents/scripts/lib/config/temp-paths.js +30 -63
  81. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  82. package/.agents/scripts/lib/config-resolver.js +2 -7
  83. package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
  84. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
  85. package/.agents/scripts/lib/config-settings-schema.js +100 -60
  86. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  87. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  88. package/.agents/scripts/lib/dependency-parser.js +3 -2
  89. package/.agents/scripts/lib/doc-tiers.js +2 -2
  90. package/.agents/scripts/lib/duplicate-search.js +242 -41
  91. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  93. package/.agents/scripts/lib/format-generated-json.js +97 -0
  94. package/.agents/scripts/lib/framework-version.js +19 -190
  95. package/.agents/scripts/lib/gh-exec.js +8 -0
  96. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  97. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
  98. package/.agents/scripts/lib/git-utils.js +32 -20
  99. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  100. package/.agents/scripts/lib/json-utils.js +1 -2
  101. package/.agents/scripts/lib/label-constants.js +10 -38
  102. package/.agents/scripts/lib/label-taxonomy.js +10 -55
  103. package/.agents/scripts/lib/observability/active-story-env.js +44 -165
  104. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  105. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  106. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  107. package/.agents/scripts/lib/observability/source-classifier.js +5 -5
  108. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  109. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  110. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  111. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  112. package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
  113. package/.agents/scripts/lib/orchestration/code-review.js +78 -436
  114. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  115. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
  116. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  117. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  118. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  119. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  120. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  121. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  122. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  123. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  124. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  125. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
  126. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  127. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  128. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  129. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
  130. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  131. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  132. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  133. package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
  134. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  135. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  136. package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
  137. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
  138. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
  139. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  140. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  141. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
  142. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
  143. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  144. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
  145. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
  146. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
  147. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  148. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  149. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  150. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
  151. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  152. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
  153. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  154. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  155. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  156. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  157. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  158. package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
  159. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  160. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  161. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  162. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  163. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  164. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  165. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  166. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  167. package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  170. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  171. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
  172. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  173. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
  174. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  175. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  176. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
  177. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  178. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  179. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
  180. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  181. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  182. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  183. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  184. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  185. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  186. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  187. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
  188. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  189. package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
  190. package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
  191. package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
  192. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  193. package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
  194. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  195. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
  196. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
  197. package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
  198. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
  199. package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
  200. package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
  201. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  202. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  203. package/.agents/scripts/lib/planning-corpus.js +12 -281
  204. package/.agents/scripts/lib/preflight-runner.js +4 -4
  205. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  206. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  207. package/.agents/scripts/lib/signals/index.js +4 -17
  208. package/.agents/scripts/lib/signals/read.js +35 -35
  209. package/.agents/scripts/lib/signals/schema.js +8 -11
  210. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  211. package/.agents/scripts/lib/signals/write.js +0 -1
  212. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  213. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  214. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  215. package/.agents/scripts/lib/story-adjacency.js +17 -19
  216. package/.agents/scripts/lib/story-body/story-body.js +130 -75
  217. package/.agents/scripts/lib/story-plan.js +2 -4
  218. package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
  219. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  220. package/.agents/scripts/lib/test-env.js +14 -1
  221. package/.agents/scripts/lib/test-tiers.js +0 -3
  222. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
  223. package/.agents/scripts/lib/validation-evidence.js +32 -60
  224. package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
  225. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  226. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
  228. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  229. package/.agents/scripts/lint-issue-body.js +71 -40
  230. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  231. package/.agents/scripts/notify.js +4 -3
  232. package/.agents/scripts/plan-context.js +102 -80
  233. package/.agents/scripts/plan-persist.js +230 -279
  234. package/.agents/scripts/plan-run-epilogue.js +142 -0
  235. package/.agents/scripts/post-structured-comment.js +0 -38
  236. package/.agents/scripts/pr-watch-with-update.js +43 -22
  237. package/.agents/scripts/providers/github/compose.js +0 -1
  238. package/.agents/scripts/providers/github/errors.js +0 -19
  239. package/.agents/scripts/providers/github/issues.js +13 -39
  240. package/.agents/scripts/providers/github/mappers.js +5 -12
  241. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  242. package/.agents/scripts/providers/github/tickets.js +33 -156
  243. package/.agents/scripts/providers/github.js +17 -6
  244. package/.agents/scripts/resolve-stories.js +236 -0
  245. package/.agents/scripts/run-coverage.js +4 -1
  246. package/.agents/scripts/run-lint.js +2 -2
  247. package/.agents/scripts/run-verify.js +31 -2
  248. package/.agents/scripts/signals-view.js +25 -21
  249. package/.agents/scripts/single-story-close.js +178 -26
  250. package/.agents/scripts/single-story-confirm-merge.js +313 -24
  251. package/.agents/scripts/single-story-init.js +35 -30
  252. package/.agents/scripts/stories-wave-tick.js +85 -10
  253. package/.agents/scripts/story-plan.js +28 -49
  254. package/.agents/scripts/update-ticket-state.js +14 -65
  255. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  256. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  257. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  258. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  259. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  260. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  261. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  262. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  263. package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
  264. package/.agents/skills/core/scope-triage/SKILL.md +31 -172
  265. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  266. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  267. package/.agents/skills/skills.index.json +3 -53
  268. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  269. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  270. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  271. package/.agents/starter-agentrc.json +0 -5
  272. package/.agents/templates/agent-protocol.md +9 -10
  273. package/.agents/workflows/audit-architecture.md +6 -7
  274. package/.agents/workflows/audit-clean-code.md +7 -7
  275. package/.agents/workflows/audit-dependencies.md +3 -3
  276. package/.agents/workflows/audit-devops.md +3 -3
  277. package/.agents/workflows/audit-documentation.md +9 -10
  278. package/.agents/workflows/audit-lighthouse.md +11 -3
  279. package/.agents/workflows/audit-navigability.md +13 -2
  280. package/.agents/workflows/audit-performance.md +5 -6
  281. package/.agents/workflows/audit-privacy.md +3 -3
  282. package/.agents/workflows/audit-quality.md +11 -12
  283. package/.agents/workflows/audit-security.md +4 -5
  284. package/.agents/workflows/audit-seo.md +13 -3
  285. package/.agents/workflows/audit-sre.md +3 -3
  286. package/.agents/workflows/audit-to-stories.md +20 -20
  287. package/.agents/workflows/audit-ux-ui.md +10 -3
  288. package/.agents/workflows/deliver.md +177 -176
  289. package/.agents/workflows/git-cleanup.md +5 -6
  290. package/.agents/workflows/git-deliver.md +1 -1
  291. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  292. package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
  293. package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
  294. package/.agents/workflows/helpers/code-review.md +75 -196
  295. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
  296. package/.agents/workflows/helpers/deliver-story.md +606 -0
  297. package/.agents/workflows/helpers/diagnose.md +10 -10
  298. package/.agents/workflows/helpers/parallel-tooling.md +3 -3
  299. package/.agents/workflows/helpers/signals.md +16 -16
  300. package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
  301. package/.agents/workflows/mandrel-update.md +2 -1
  302. package/.agents/workflows/plan.md +277 -145
  303. package/.agents/workflows/qa-assist.md +27 -33
  304. package/.agents/workflows/qa-explore.md +29 -38
  305. package/.agents/workflows/qa-run.md +2 -6
  306. package/README.md +9 -8
  307. package/bin/mandrel.js +12 -1
  308. package/docs/CHANGELOG.md +70 -0
  309. package/lib/cli/registry.js +262 -19
  310. package/lib/cli/sync-agents.js +157 -0
  311. package/lib/cli/sync-commands.js +115 -6
  312. package/lib/cli/sync.js +168 -6
  313. package/lib/cli/update.js +105 -8
  314. package/lib/cli/version-helpers.js +131 -0
  315. package/lib/migrations/README.md +7 -5
  316. package/lib/migrations/index.js +12 -8
  317. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  318. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  319. package/package.json +2 -2
  320. package/.agents/agents/retro.md +0 -42
  321. package/.agents/personas/architect.md +0 -113
  322. package/.agents/personas/devops-engineer.md +0 -38
  323. package/.agents/personas/engineer.md +0 -33
  324. package/.agents/personas/project-manager.md +0 -114
  325. package/.agents/personas/qa-engineer.md +0 -95
  326. package/.agents/personas/security-engineer.md +0 -111
  327. package/.agents/personas/technical-writer.md +0 -101
  328. package/.agents/schemas/dispatch-manifest.json +0 -232
  329. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  330. package/.agents/schemas/epic-spec.schema.json +0 -153
  331. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  332. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  333. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  334. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  335. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  336. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  337. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  338. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  339. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  340. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  341. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  342. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  343. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  344. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  345. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  346. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  347. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  348. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  349. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  350. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  351. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  352. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  353. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  354. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  355. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  356. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  357. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  358. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  359. package/.agents/schemas/risk-verdict.schema.json +0 -66
  360. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  361. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  362. package/.agents/scripts/analyze-execution.js +0 -444
  363. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  364. package/.agents/scripts/check-prepush-recovery.js +0 -90
  365. package/.agents/scripts/dispatcher.js +0 -295
  366. package/.agents/scripts/epic-audit-prepare.js +0 -497
  367. package/.agents/scripts/epic-audit-recheck.js +0 -274
  368. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  369. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  370. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  371. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  372. package/.agents/scripts/epic-plan-clarity.js +0 -211
  373. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  374. package/.agents/scripts/epic-reconcile.js +0 -625
  375. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  376. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  377. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  378. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  379. package/.agents/scripts/lib/config/preflight.js +0 -58
  380. package/.agents/scripts/lib/config/retro.js +0 -77
  381. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  382. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  383. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  384. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  385. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  386. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
  387. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  388. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  389. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  390. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
  391. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  392. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  393. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  394. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  395. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  396. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  397. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  398. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  399. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  400. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  401. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  402. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  403. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  404. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  405. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  406. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  407. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  408. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
  409. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  410. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  411. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  412. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  413. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  414. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  415. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  416. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  417. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  418. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  419. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  420. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  421. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  422. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  423. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  424. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  425. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  426. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
  427. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  428. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  429. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  430. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  431. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  432. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  433. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  434. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  435. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  436. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  437. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  438. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  439. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  440. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  441. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  442. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  443. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  444. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  445. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  446. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  447. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  448. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  449. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  450. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  451. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  452. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  453. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  454. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  455. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  456. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  457. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  458. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  459. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  460. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  461. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
  462. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  463. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  464. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  465. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
  466. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  467. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  468. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  469. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  470. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  471. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  472. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  473. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  474. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  475. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  476. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  477. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  478. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  479. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  480. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  481. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  482. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  483. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  484. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  485. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  486. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  487. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  488. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  489. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  490. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  491. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  492. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  493. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  494. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  495. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  496. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  497. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  498. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  499. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  500. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  501. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  502. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  503. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  504. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  505. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  506. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  507. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  508. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  509. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  510. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  511. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  512. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  513. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  514. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  515. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  516. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  517. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  518. package/.agents/scripts/lib/spec/index.js +0 -36
  519. package/.agents/scripts/lib/spec/loader.js +0 -425
  520. package/.agents/scripts/lib/spec/state.js +0 -208
  521. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  522. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  523. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  524. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  525. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  526. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  527. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  528. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  529. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  530. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  531. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  532. package/.agents/scripts/lifecycle-emit.js +0 -510
  533. package/.agents/scripts/retro-run.js +0 -218
  534. package/.agents/scripts/slice-phase.js +0 -361
  535. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  536. package/.agents/scripts/story-close.js +0 -294
  537. package/.agents/scripts/story-init.js +0 -599
  538. package/.agents/scripts/story-phase.js +0 -369
  539. package/.agents/scripts/wave-tick.js +0 -464
  540. package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
  541. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  542. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  543. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  544. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  545. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  546. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  547. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  548. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  549. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  550. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  551. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  552. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  553. package/.agents/workflows/helpers/epic-audit.md +0 -189
  554. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  555. package/.agents/workflows/helpers/epic-testing.md +0 -125
  556. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  557. package/.agents/workflows/helpers/plan-epic.md +0 -353
  558. package/.agents/workflows/helpers/plan-story.md +0 -251
  559. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  560. package/.agents/workflows/helpers/single-story-deliver.md +0 -557
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * plan-run-epilogue.js — execute the real per-run closeout for a
4
+ * multi-Story `/deliver`.
5
+ *
6
+ * Usage:
7
+ * node .agents/scripts/plan-run-epilogue.js --stories 1,2,3
8
+ *
9
+ * Keyed on the delivered id set: an `adhoc-<sorted-ids>` run id is
10
+ * synthesized from `--stories`. Story #4540 retired the `--run <planRunId>`
11
+ * label-resolution branch along with the `plan-run::<id>` label itself.
12
+ */
13
+
14
+ import './lib/runtime-deps/ensure-installed.js';
15
+ import { parseArgs } from 'node:util';
16
+
17
+ import { runAsCli } from './lib/cli-utils.js';
18
+ import { resolveConfig } from './lib/config-resolver.js';
19
+ import { Logger } from './lib/Logger.js';
20
+ import { runPlanRunEpilogue } from './lib/orchestration/run-epilogue.js';
21
+ import { createProvider } from './lib/provider-factory.js';
22
+
23
+ const CLI_OPTIONS = {
24
+ stories: { type: 'string' },
25
+ cwd: { type: 'string' },
26
+ };
27
+
28
+ /**
29
+ * @param {string[]} [argv]
30
+ * @returns {Promise<object>}
31
+ */
32
+ export async function main(argv = process.argv.slice(2)) {
33
+ const { values } = parseArgs({
34
+ args: argv,
35
+ options: CLI_OPTIONS,
36
+ strict: false,
37
+ });
38
+ const hasStoriesFlag =
39
+ typeof values.stories === 'string' && values.stories.trim().length > 0;
40
+ if (!hasStoriesFlag) {
41
+ throw new Error('Usage: node plan-run-epilogue.js --stories 1,2,3');
42
+ }
43
+ const cwd =
44
+ typeof values.cwd === 'string' && values.cwd.trim()
45
+ ? values.cwd.trim()
46
+ : process.cwd();
47
+ const config = resolveConfig({ cwd });
48
+ const provider = createProvider(config);
49
+
50
+ // Story #4540 retired the `--run <planRunId>` label-resolution branch
51
+ // along with the label itself. The epilogue is keyed on the delivered id
52
+ // set, and the synthesized `adhoc-<ids>` id it already used for positional
53
+ // runs is now the only id it needs.
54
+ const stories = values.stories
55
+ .split(',')
56
+ .map((s) => Number(s.trim()))
57
+ .filter((n) => Number.isInteger(n) && n > 0);
58
+
59
+ const planRunId = `adhoc-${[...stories].sort((a, b) => a - b).join('-')}`;
60
+
61
+ const result = await runPlanRunEpilogue({
62
+ planRunId,
63
+ stories,
64
+ provider,
65
+ config,
66
+ cwd,
67
+ });
68
+ warnOnUnresolvedBase(result);
69
+ warnOnEmptyRollup(result);
70
+ Logger.info(JSON.stringify(result, null, 2));
71
+ if (result.errors?.length) {
72
+ process.exitCode = 1;
73
+ }
74
+ return result;
75
+ }
76
+
77
+ /**
78
+ * Surface an unresolvable combined landed diff as a loud operator warning.
79
+ *
80
+ * The roster's changed-file set is the input the host walks its audit lenses
81
+ * against; a silent absence would read as "nothing changed" and the lens walk
82
+ * would look complete while covering nothing. Not fatal — with no diff the
83
+ * selector degrades to keyword-only lens selection, so the rest of the
84
+ * roster is still useful.
85
+ *
86
+ * @param {object} result - `runPlanRunEpilogue` envelope.
87
+ * @returns {void}
88
+ */
89
+ function warnOnUnresolvedBase(result) {
90
+ const roster = (result?.results ?? []).find(
91
+ (r) => r?.kind === 'audit-roster',
92
+ );
93
+ const base = roster?.baseResolution;
94
+ if (base?.resolved !== false) return;
95
+ Logger.warn(
96
+ `⚠️ Combined landed diff unavailable — the pre-run base sha could not be ` +
97
+ `resolved against \`${base.baseRef}\`: ${base.reason}\n` +
98
+ ` changedFiles is null (NOT an empty set). Determine the run diff by ` +
99
+ `hand before walking the selected lenses.`,
100
+ );
101
+ }
102
+
103
+ /**
104
+ * Surface a zero-signal roll-up over a multi-Story run as a loud operator
105
+ * warning (Story #4578).
106
+ *
107
+ * The failure this exists to prevent is a *reassuring* one. The roll-up read
108
+ * "No friction signals — nothing to follow up" for a 7-Story run that
109
+ * contained a mid-run git outage, a parked worker needing an operator
110
+ * resume, and an acceptance critic that needed four rounds. Nothing was
111
+ * broken in the roll-up — the stream really was empty — but the report was
112
+ * indistinguishable from a clean run, so the retro loop that exists to learn
113
+ * from a run was silently blind to that run's pain.
114
+ *
115
+ * Not fatal: a genuinely friction-free multi-Story run is possible, and this
116
+ * cannot tell the two apart — which is precisely why it asks the operator
117
+ * rather than asserting either reading.
118
+ *
119
+ * @param {object} result - `runPlanRunEpilogue` envelope.
120
+ * @returns {void}
121
+ */
122
+ function warnOnEmptyRollup(result) {
123
+ const rollup = (result?.results ?? []).find(
124
+ (r) => r?.kind === 'follow-up-rollup',
125
+ );
126
+ if (!rollup?.emptyRollupSuspect) return;
127
+ Logger.warn(
128
+ `⚠️ 0 friction signals across ${rollup.storyCount} Stories — telemetry may not ` +
129
+ `have fired.\n` +
130
+ ` An empty roll-up is NOT evidence of a clean run: it is the same output a ` +
131
+ `run with\n` +
132
+ ` heavy friction produces when nothing recorded it. The runtime emits ` +
133
+ `friction from its\n` +
134
+ ` own observables (agent::blocked transitions, failed closes, exhausted ` +
135
+ `merge waits), so\n` +
136
+ ` zero here also means none of those fired. If this run had friction you ` +
137
+ `can name, that\n` +
138
+ ` telemetry gap is itself worth filing.`,
139
+ );
140
+ }
141
+
142
+ await runAsCli(import.meta.url, main);
@@ -22,10 +22,6 @@ import fs from 'node:fs/promises';
22
22
  import { parseArgs } from 'node:util';
23
23
  import { runAsCli } from './lib/cli-utils.js';
24
24
  import { resolveConfig } from './lib/config-resolver.js';
25
- import {
26
- outboxPathFor,
27
- postCommentOrBuffer,
28
- } from './lib/orchestration/bookkeeping-outbox.js';
29
25
  import {
30
26
  assertValidStructuredCommentType,
31
27
  upsertStructuredComment,
@@ -41,11 +37,6 @@ Flags:
41
37
  retro, epic-run-state, wave-0-start) (required).
42
38
  --body-file Path to a file containing the markdown body (required).
43
39
  --provider Provider name (default: inferred from .agentrc.json github block).
44
- --buffer Headless mode: buffer this upsert to the per-Epic bookkeeping
45
- outbox instead of posting live. Requires --epic. Drained to
46
- GitHub once at finalize by bookkeeping-reconcile.js (Epic
47
- #4476). Omit for attended runs (posts live, unchanged).
48
- --epic <id> Epic id owning the outbox (required with --buffer).
49
40
  --help Show this message.
50
41
  `;
51
42
 
@@ -73,8 +64,6 @@ export function parseArgv(argv) {
73
64
  marker: { type: 'string' },
74
65
  'body-file': { type: 'string' },
75
66
  provider: { type: 'string' },
76
- buffer: { type: 'boolean' },
77
- epic: { type: 'string' },
78
67
  help: { type: 'boolean' },
79
68
  },
80
69
  strict: false,
@@ -126,33 +115,6 @@ export async function main(argv = process.argv.slice(2)) {
126
115
  : config;
127
116
  const provider = createProvider(effectiveConfig);
128
117
 
129
- // Headless buffering (Epic #4476 M5): route the upsert to the per-Epic
130
- // outbox instead of a live GitHub round-trip. Requires --epic to locate the
131
- // outbox; finalize's bookkeeping-reconcile.js drains it once. Attended runs
132
- // (no --buffer) are unchanged.
133
- if (values.buffer) {
134
- const epicId = Number.parseInt(values.epic ?? '', 10);
135
- if (!Number.isInteger(epicId) || epicId <= 0) {
136
- process.stderr.write(
137
- '[post-structured-comment] --buffer requires --epic <id>.\n',
138
- );
139
- process.exit(2);
140
- }
141
- assertValidStructuredCommentType(values.marker);
142
- const { buffered } = await postCommentOrBuffer({
143
- provider,
144
- ticketId,
145
- marker: values.marker,
146
- body,
147
- headless: true,
148
- outboxPath: outboxPathFor(epicId, config),
149
- });
150
- process.stdout.write(
151
- `${JSON.stringify({ success: true, ticketId, type: values.marker, buffered })}\n`,
152
- );
153
- return;
154
- }
155
-
156
118
  const envelope = await runPostStructuredComment({
157
119
  ticketId,
158
120
  type: values.marker,
@@ -1,10 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * pr-watch-with-update.js — the single CI-watch mechanism for BOTH the
4
- * Epic Phase 8 path (`deliver-epic.md`) and the standalone single-Story
5
- * Step 4 path (`single-story-deliver.md`). Story #4358 retired the bare
6
- * `gh pr checks --watch` from the single-Story path so both drive this
7
- * one CLI.
3
+ * pr-watch-with-update.js — the single CI-watch mechanism for the Story
4
+ * delivery path (`helpers/deliver-story.md` Step 4). Story #4358 retired
5
+ * the bare `gh pr checks --watch` so every caller drives this one CLI.
8
6
  *
9
7
  * Polls the PR's required checks to a terminal state and auto-recovers
10
8
  * from `mergeStateStatus: BEHIND` (via bounded `gh pr update-branch`
@@ -17,10 +15,13 @@
17
15
  * - GREEN — every required check terminal + green → exit 0.
18
16
  * - RED — one or more required checks genuinely failed → exit 1
19
17
  * IMMEDIATELY, consuming no resume budget. On red the CLI
20
- * writes `temp/epic-<id>-ci-digest.{json,md}` (failing check
18
+ * writes `temp/story-<id>-ci-digest.{json,md}` (failing check
21
19
  * name, run id, a `gh run view --log-failed` tail, and a
22
20
  * coarse classification) and prints the red-green
23
- * remediation handoff.
21
+ * remediation handoff. The digest is scoped by filename, so
22
+ * it requires `--story` (Story #4539: the digest was
23
+ * Epic-scoped and therefore never written on the only
24
+ * delivery path v2 has).
24
25
  * - STILL-RUNNING — the poll cap fired with checks still pending and
25
26
  * none failed; the watcher re-armed up to
26
27
  * `delivery.ci.watch.maxResumes` times, then returned a
@@ -35,8 +36,8 @@
35
36
  * CLI flags override config; config overrides the framework fallback.
36
37
  *
37
38
  * Usage:
38
- * node .agents/scripts/pr-watch-with-update.js --pr <n> [--repo owner/repo]
39
- * [--epic <id>] [--max-updates N] [--poll-interval-ms MS]
39
+ * node .agents/scripts/pr-watch-with-update.js --pr <n> --story <id>
40
+ * [--repo owner/repo] [--max-updates N] [--poll-interval-ms MS]
40
41
  * [--max-polls N] [--max-resumes N]
41
42
  */
42
43
  import { spawnSync } from 'node:child_process';
@@ -161,13 +162,33 @@ function resolveRunId({ prRef, checkName, cwd, spawnFn = spawnSync }) {
161
162
  }
162
163
  }
163
164
 
165
+ /**
166
+ * Resolve which ticket the digest is keyed to. Story #4539: the digest used
167
+ * to be Epic-scoped by filename and returned `null` without an epic id — so
168
+ * on the v2 Story path (which has no Epic and invokes the watch with `--pr`
169
+ * alone) a red check wrote no digest at all, despite the module header
170
+ * advertising one. v2.0.0 removed the Epic tier; Story scope is the only
171
+ * scope.
172
+ *
173
+ * @param {{ storyId?: number|string|null }} opts
174
+ * @returns {{ kind: 'story', id: number } | null}
175
+ */
176
+ export function resolveDigestScope({ storyId = null } = {}) {
177
+ if (storyId == null || String(storyId).length === 0) return null;
178
+ const parsed = Number.parseInt(String(storyId), 10);
179
+ return Number.isInteger(parsed) && parsed > 0
180
+ ? { kind: 'story', id: parsed }
181
+ : null;
182
+ }
183
+
164
184
  /**
165
185
  * Write the CI failure digest (`.json` + `.md`) for a red watch. Returns
166
- * the two paths written (or `null` when no epic id was supplied the
167
- * digest is Epic-scoped by filename). Exported for tests.
186
+ * the two paths written, or `null` when no story id was supplied (the
187
+ * digest is scoped by filename and has nothing to key on). Exported for
188
+ * tests.
168
189
  *
169
190
  * @param {object} opts
170
- * @param {number|string|null} opts.epicId
191
+ * @param {number|string|null} [opts.storyId] The v2 delivery scope.
171
192
  * @param {number} opts.prNumber
172
193
  * @param {Array<{name:string, outcome:string}>} opts.failures
173
194
  * @param {string} opts.tempRoot
@@ -178,7 +199,7 @@ function resolveRunId({ prRef, checkName, cwd, spawnFn = spawnSync }) {
178
199
  * @returns {{ jsonPath: string, mdPath: string } | null}
179
200
  */
180
201
  export function writeCiDigest({
181
- epicId,
202
+ storyId = null,
182
203
  prNumber,
183
204
  failures,
184
205
  tempRoot,
@@ -187,13 +208,14 @@ export function writeCiDigest({
187
208
  runIdFn = resolveRunId,
188
209
  logTailFn = ghRunLogTail,
189
210
  }) {
190
- if (epicId == null || String(epicId).length === 0) return null;
211
+ const scope = resolveDigestScope({ storyId });
212
+ if (!scope) return null;
191
213
  const primary = failures[0] ?? { name: 'unknown', outcome: 'failure' };
192
214
  const runId = runIdFn({ prRef, checkName: primary.name, cwd });
193
215
  const logTail = logTailFn({ runId, cwd });
194
216
  const classification = classifyFailure(primary.name);
195
217
  const digest = {
196
- epicId: Number.parseInt(String(epicId), 10),
218
+ storyId: scope.id,
197
219
  prNumber,
198
220
  failingCheck: primary.name,
199
221
  failingOutcome: primary.outcome,
@@ -205,12 +227,12 @@ export function writeCiDigest({
205
227
  };
206
228
  const dir = path.isAbsolute(tempRoot) ? tempRoot : path.join(cwd, tempRoot);
207
229
  mkdirSync(dir, { recursive: true });
208
- const base = `epic-${digest.epicId}-ci-digest`;
230
+ const base = `${scope.kind}-${scope.id}-ci-digest`;
209
231
  const jsonPath = path.join(dir, `${base}.json`);
210
232
  const mdPath = path.join(dir, `${base}.md`);
211
233
  writeFileSync(jsonPath, `${JSON.stringify(digest, null, 2)}\n`);
212
234
  const md = [
213
- `# CI failure digest — Epic #${digest.epicId} (PR #${prNumber})`,
235
+ `# CI failure digest — Story #${scope.id} (PR #${prNumber})`,
214
236
  '',
215
237
  `- **Failing check:** \`${digest.failingCheck}\` (${digest.failingOutcome})`,
216
238
  `- **Run id:** ${runId ?? 'unresolved'}`,
@@ -247,7 +269,6 @@ export function writeCiDigest({
247
269
  * @param {object} opts
248
270
  * @param {number} opts.prNumber
249
271
  * @param {string|null} [opts.repo]
250
- * @param {number|string|null} [opts.epicId] Epic id for the red-path digest.
251
272
  * @param {number|string} [opts.maxUpdates]
252
273
  * @param {number|string} [opts.pollIntervalMs]
253
274
  * @param {number|string} [opts.maxPolls]
@@ -266,7 +287,7 @@ export function writeCiDigest({
266
287
  export async function runPrWatch({
267
288
  prNumber,
268
289
  repo = null,
269
- epicId = null,
290
+ storyId = null,
270
291
  maxUpdates,
271
292
  pollIntervalMs,
272
293
  maxPolls,
@@ -377,7 +398,7 @@ export async function runPrWatch({
377
398
  let digestPaths = null;
378
399
  try {
379
400
  digestPaths = writeDigestFn({
380
- epicId,
401
+ storyId,
381
402
  prNumber,
382
403
  failures,
383
404
  tempRoot: effectiveTempRoot,
@@ -415,7 +436,7 @@ async function main() {
415
436
  options: {
416
437
  pr: { type: 'string' },
417
438
  repo: { type: 'string' },
418
- epic: { type: 'string' },
439
+ story: { type: 'string' },
419
440
  'max-updates': { type: 'string' },
420
441
  'poll-interval-ms': { type: 'string' },
421
442
  'max-polls': { type: 'string' },
@@ -426,7 +447,7 @@ async function main() {
426
447
  return runPrWatch({
427
448
  prNumber: Number.parseInt(values.pr ?? '', 10),
428
449
  repo: values.repo ?? null,
429
- epicId: values.epic ?? null,
450
+ storyId: values.story ?? null,
430
451
  maxUpdates: values['max-updates'],
431
452
  pollIntervalMs: values['poll-interval-ms'],
432
453
  maxPolls: values['max-polls'],
@@ -42,7 +42,6 @@ export function composeGateways(provider) {
42
42
  ...ghDeps,
43
43
  cache: p._cache,
44
44
  hooks: {
45
- addSubIssue: (a, b) => p.addSubIssue(a, b),
46
45
  addItemToProject,
47
46
  getProjectNumber,
48
47
  },
@@ -272,22 +272,3 @@ export const REMOVE_SUB_ISSUE_MUTATION = `
272
272
  subIssue { number }
273
273
  }
274
274
  }`;
275
-
276
- // Story #2982 — native parent lookup for the cascade upward walk. The
277
- // inverse of `SUB_ISSUES_QUERY`: given a child Issue node, fetch the
278
- // `parent` field exposed by the Sub-Issues feature so `cascadeCompletion`
279
- // can resolve a parent even when the child body lacks the `parent: #N`
280
- // orchestrator footer.
281
- export const PARENT_ISSUE_QUERY = `query($id: ID!) {
282
- node(id: $id) {
283
- ... on Issue {
284
- parent {
285
- number
286
- databaseId
287
- id
288
- title
289
- state
290
- }
291
- }
292
- }
293
- }`;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Owns the remaining read-side surface that did not belong to any of the
5
5
  * earlier six gateways: the raw GraphQL shim (`graphql` / `_ghGraphql`),
6
- * epic enumeration (`getEpics`, `getEpic`), repository-wide label scans
6
+ * epic reads (`getEpic`), repository-wide label scans
7
7
  * (`listIssuesByLabel`), branch existence probes (`branchExists`), and the
8
8
  * three-strategy sub-ticket aggregator (`getSubTickets`).
9
9
  *
@@ -16,11 +16,10 @@
16
16
  */
17
17
 
18
18
  import { Logger } from '../../lib/Logger.js';
19
- import { TYPE_LABELS } from '../../lib/label-constants.js';
20
19
  import { concurrentMap } from '../../lib/util/concurrent-map.js';
21
20
  import { isNotFoundError } from './branch-protection.js';
22
21
  import { withTransientRetry } from './errors.js';
23
- import { issueToEpic, issueToEpicListItem } from './mappers.js';
22
+ import { issueToEpic } from './mappers.js';
24
23
  import {
25
24
  defaultRetryWarn,
26
25
  paginateRest,
@@ -114,13 +113,15 @@ export class IssuesGateway {
114
113
  * are returned (no `state:` qualifier is appended) so a closed-fingerprint
115
114
  * match can surface as `regression-of-closed`.
116
115
  *
117
- * Returns the trimmed `[{ number, state, body }]` projection the dedup
118
- * port expects. `state` is normalised to the REST lowercase form
119
- * (`open` / `closed`).
116
+ * Returns the trimmed `[{ number, state, body, title, html_url }]`
117
+ * projection. Dedup callers use `{ number, state, body }`; duplicate-
118
+ * search also needs `title` / `html_url`. `state` is normalised to the
119
+ * REST lowercase form (`open` / `closed`). Results are capped at one
120
+ * Search API page (`per_page=100`).
120
121
  *
121
122
  * @param {{ query: string, owner?: string, repo?: string }} params
122
- * @returns {Promise<Array<{ number: number, state: string, body: string }>>}
123
- * @field-manifest GET /search/issues: total_count, items[number, state, body]
123
+ * @returns {Promise<Array<{ number: number, state: string, body: string, title: string, html_url?: string }>>}
124
+ * @field-manifest GET /search/issues: total_count, items[number, state, body, title, html_url]
124
125
  */
125
126
  async searchIssues({ query, owner, repo } = {}) {
126
127
  if (typeof query !== 'string' || query.trim().length === 0) {
@@ -133,7 +134,8 @@ export class IssuesGateway {
133
134
  // issue body where the `<!-- audit-fingerprints: ... -->` footer lives.
134
135
  const qualifiers = [`repo:${scopeOwner}/${scopeRepo}`, 'type:issue'];
135
136
  const q = `${query.trim()} ${qualifiers.join(' ')}`;
136
- const endpoint = `/search/issues?q=${encodeURIComponent(q)}`;
137
+ const params = new URLSearchParams({ q, per_page: '100' });
138
+ const endpoint = `/search/issues?${params}`;
137
139
  const result = await withTransientRetry(
138
140
  () => this._gh.api({ method: 'GET', endpoint }),
139
141
  { label: `searchIssues ${query}`, onRetry: defaultRetryWarn },
@@ -144,39 +146,11 @@ export class IssuesGateway {
144
146
  number: item.number,
145
147
  state: item.state ?? 'open',
146
148
  body: item.body ?? '',
149
+ title: item.title ?? '',
150
+ html_url: item.html_url ?? undefined,
147
151
  }));
148
152
  }
149
153
 
150
- /**
151
- * List Epic-typed issues. Filter shape preserved from the old code.
152
- *
153
- * `filters.pageCap` / `filters.perPage` pass through to `paginateRest`
154
- * so a caller that only needs a bounded shortlist (e.g. the
155
- * standalone-Story corpus lookup in `planning-corpus.js`, which ranks
156
- * candidates down to a top-5 shortlist) can cap the scan instead of
157
- * inheriting the default 50-page / 5000-item ceiling. Omitted, both
158
- * fall back to `paginateRest`'s own defaults — unchanged behavior for
159
- * existing callers (e.g. `duplicate-search.js`).
160
- *
161
- * @field-manifest /repos/{owner}/{repo}/issues?labels=type::epic: number,
162
- * title, labels, state, state_reason, pull_request
163
- */
164
- /* node:coverage ignore next */
165
- async getEpics(filters = {}) {
166
- const params = new URLSearchParams({
167
- state: filters.state ?? 'all',
168
- labels: TYPE_LABELS.EPIC,
169
- });
170
- const endpoint = `/repos/${this.owner}/${this.repo}/issues?${params}`;
171
- const issues = await paginateRest(this._gh, endpoint, {
172
- pageCap: filters.pageCap,
173
- perPage: filters.perPage,
174
- });
175
- return issues
176
- .filter((issue) => !issue.pull_request)
177
- .map(issueToEpicListItem);
178
- }
179
-
180
154
  /**
181
155
  * @field-manifest /repos/{owner}/{repo}/issues/{n}: number, id, node_id,
182
156
  * title, body, labels, state
@@ -35,6 +35,11 @@ export function issueToTicket(issue) {
35
35
  labelSet: new Set(labels),
36
36
  assignees: (issue.assignees ?? []).map((a) => a.login),
37
37
  state: issue.state,
38
+ // `completed` | `not_planned` | `reopened` | null. `state` alone cannot
39
+ // tell a Story that landed from one closed as superseded — both read
40
+ // `closed` — so the close path needs this to avoid reporting a
41
+ // never-merged Story as landed.
42
+ stateReason: issue.state_reason ?? null,
38
43
  };
39
44
  }
40
45
 
@@ -109,15 +114,3 @@ export function issueToListItem(issue) {
109
114
  state: issue.state,
110
115
  };
111
116
  }
112
-
113
- export function issueToEpicListItem(issue) {
114
- const labels = normalizeLabels(issue);
115
- return {
116
- id: issue.number,
117
- title: issue.title,
118
- labels,
119
- labelSet: new Set(labels),
120
- state: issue.state,
121
- state_reason: issue.state_reason,
122
- };
123
- }
@@ -30,7 +30,6 @@ import { concurrentMap } from '../../lib/util/concurrent-map.js';
30
30
  import {
31
31
  ADD_SUB_ISSUE_MUTATION,
32
32
  classifyGithubError as defaultClassifyGithubError,
33
- PARENT_ISSUE_QUERY,
34
33
  REMOVE_SUB_ISSUE_MUTATION,
35
34
  SUB_ISSUES_QUERY,
36
35
  withTransientRetry,
@@ -134,52 +133,6 @@ export class SubIssueGateway {
134
133
  return childIds;
135
134
  }
136
135
 
137
- /**
138
- * Strategy 2 — native GitHub Sub-Issues, inverse direction. Given a
139
- * child Issue node, return the parent's issue number (or `null` when
140
- * the child has no native parent link, or the feature is disabled on
141
- * this repo). Story #2982: used by `cascadeCompletion` as a third
142
- * fallback so a Story whose body lost the `parent: #N` orchestrator
143
- * footer still cascades upward to its true Sub-Issue parent.
144
- *
145
- * @param {string} childNodeId GraphQL node ID of the child Issue.
146
- * @param {number} childNumber Issue number, for log context only.
147
- * @returns {Promise<number|null>}
148
- */
149
- async getNativeParent(childNodeId, childNumber) {
150
- if (!childNodeId) return null;
151
- try {
152
- const data = await withTransientRetry(
153
- () =>
154
- this._ghGraphql(
155
- PARENT_ISSUE_QUERY,
156
- { id: childNodeId },
157
- { headers: { 'GraphQL-Features': 'sub_issues' } },
158
- ),
159
- {
160
- label: `getNativeParent child=#${childNumber}`,
161
- classify: this._classify,
162
- onRetry: defaultRetryWarn,
163
- },
164
- );
165
- const parent = data?.node?.parent;
166
- if (!parent || typeof parent.number !== 'number') return null;
167
- return parent.number;
168
- } catch (err) {
169
- const category = this._classify(err);
170
- if (category === 'feature-disabled') {
171
- Logger.warn(
172
- `[GitHubProvider] sub-issues parent lookup unavailable (child #${childNumber})`,
173
- );
174
- return null;
175
- }
176
- Logger.error(
177
- `[GitHubProvider] native parent lookup failed (child #${childNumber}, category=${category}): ${err.message}`,
178
- );
179
- throw err;
180
- }
181
- }
182
-
183
136
  /**
184
137
  * Establish the native sub-issue link between `parentNumber` and the
185
138
  * child identified by `childNodeId`. Retries on transient errors with