@joshuafolkken/kit 1.1784.0 → 1.2114.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 (690) hide show
  1. package/.claude/agents/reviewer-verification.md +19 -0
  2. package/.claude/agents/reviewer.md +19 -0
  3. package/.claude/settings.json +5 -6
  4. package/.claude/skills/dependency-update/SKILL.md +9 -10
  5. package/.claude/skills/workflow-commands/SKILL.md +6 -6
  6. package/.claude/skills/workflow-commands/background-commands.md +8 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
  13. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  14. package/.claude/skills/workflow-commands/chain-rule.md +41 -32
  15. package/.claude/skills/workflow-commands/delegation.md +6 -6
  16. package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
  17. package/.claude/skills/workflow-commands/followup.md +7 -5
  18. package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
  19. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  20. package/.claude/skills/workflow-commands/issue-comments.md +9 -4
  21. package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +2 -2
  23. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  24. package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
  25. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
  26. package/.claude/skills/workflow-commands/prerequisite.md +3 -2
  27. package/.claude/skills/workflow-commands/retrospective.md +2 -2
  28. package/.claude/skills/workflow-commands/split-assessment.md +7 -5
  29. package/.codex/hooks.json +5 -5
  30. package/.github/actions/setup-pnpm/action.yml +9 -16
  31. package/.github/dependabot.yml +16 -0
  32. package/.github/workflows/auto-tag.yml +45 -0
  33. package/.github/workflows/ci.yml +155 -15
  34. package/.github/workflows/dependabot-auto-merge.yml +63 -4
  35. package/.github/workflows/production.yml +8 -0
  36. package/.github/workflows/publish.yml +59 -45
  37. package/.vscode/settings.json +19 -0
  38. package/CLAUDE.md +5 -12
  39. package/SECURITY.md +2 -2
  40. package/dist/CLAUDE.md +5 -12
  41. package/dist/commands/document-read-cli.js +2 -1
  42. package/dist/commands/document-section-main.js +2 -1
  43. package/dist/commands/read-set-cli.js +194 -134
  44. package/dist/commands/run-prep-main.js +9694 -10173
  45. package/dist/commands/run-step-cli.js +22138 -18285
  46. package/dist/hooks/audit-provision.js +23 -5
  47. package/dist/hooks/chunk-3GKE653K.js +6204 -0
  48. package/dist/hooks/chunk-45CJJOO7.js +1243 -0
  49. package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
  50. package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
  51. package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
  52. package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
  53. package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
  54. package/dist/hooks/chunk-VVNYJWEI.js +30 -0
  55. package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
  56. package/dist/hooks/codex-hook-adapter.js +8 -8
  57. package/dist/hooks/format-edited.js +4 -5
  58. package/dist/hooks/inputs.json +415 -389
  59. package/dist/hooks/pretool-guard.js +7 -6
  60. package/dist/hooks/session-lang.js +101 -258
  61. package/dist/hooks/stop-guard.js +1744 -2576
  62. package/dist/josh.js +7133 -6368
  63. package/dist/version/index.js +161 -1
  64. package/eslint/rules/comment-why-only.js +108 -0
  65. package/package.json +15 -8
  66. package/prompts/coding-standards.md +1 -1
  67. package/prompts/collaboration-workflow/file-edits.md +14 -11
  68. package/prompts/collaboration-workflow/issue-citation.md +0 -4
  69. package/prompts/collaboration-workflow/issue-template.md +40 -21
  70. package/prompts/collaboration-workflow/lane-instructions.md +3 -1
  71. package/prompts/collaboration-workflow/measurement.md +8 -1
  72. package/prompts/collaboration-workflow/operating-rules.md +11 -2
  73. package/prompts/collaboration-workflow/output-bounds.md +6 -2
  74. package/prompts/collaboration-workflow/plan-comment.md +1 -1
  75. package/prompts/collaboration-workflow/principles.md +9 -0
  76. package/prompts/collaboration-workflow/residency.md +3 -2
  77. package/prompts/collaboration-workflow/rule-delivery.md +13 -1
  78. package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
  79. package/prompts/collaboration-workflow/wip-cap.md +3 -1
  80. package/prompts/review-rubric.md +8 -0
  81. package/prompts/review.md +31 -22
  82. package/prompts/testing-guide.md +1 -0
  83. package/scripts/agent/agent-argv.ts +14 -16
  84. package/scripts/agent/agent-provider.ts +138 -0
  85. package/scripts/agent/agent-role-profile.ts +108 -156
  86. package/scripts/agent/agent-safe-text.ts +20 -5
  87. package/scripts/agent/api-usage-limit.ts +65 -0
  88. package/scripts/agent/claude-agent-argv.ts +19 -9
  89. package/scripts/agent/codex-agent-argv.ts +118 -22
  90. package/scripts/agent/usage-limit-reset.ts +179 -0
  91. package/scripts/auth/claude-token-output.ts +2 -2
  92. package/scripts/auto-ok/auto-ok-author.ts +53 -0
  93. package/scripts/auto-ok/auto-ok-cli.ts +20 -9
  94. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  95. package/scripts/backlog/backlog-drive-cli.ts +6 -1
  96. package/scripts/backlog/backlog-drive-hold.ts +3 -3
  97. package/scripts/backlog/backlog-drive-idle.ts +10 -0
  98. package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
  99. package/scripts/backlog/backlog-drive-launch.ts +8 -2
  100. package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
  101. package/scripts/backlog/backlog-drive-named.ts +28 -7
  102. package/scripts/backlog/backlog-drive-paused.ts +5 -4
  103. package/scripts/backlog/backlog-drive-restore.ts +11 -3
  104. package/scripts/backlog/backlog-drive.ts +21 -60
  105. package/scripts/backlog/backlog-gate-scope.ts +61 -0
  106. package/scripts/backlog/backlog-measure-close.ts +112 -0
  107. package/scripts/backlog/backlog-next.ts +39 -49
  108. package/scripts/backlog/backlog-occupied.ts +2 -2
  109. package/scripts/backlog/backlog-overlap.ts +42 -8
  110. package/scripts/backlog/backlog-plan-cli.ts +4 -1
  111. package/scripts/backlog/backlog-plan-comment.ts +81 -0
  112. package/scripts/backlog/backlog-plan-read.ts +19 -6
  113. package/scripts/backlog/backlog-pool.ts +50 -12
  114. package/scripts/backlog/backlog-rank.ts +60 -13
  115. package/scripts/backlog/backlog-stalled-detect.ts +2 -1
  116. package/scripts/backlog/backlog-waves.ts +17 -2
  117. package/scripts/backlog/backlogrun-launch.ts +7 -4
  118. package/scripts/cost-runtime/context-cut-payback.ts +27 -25
  119. package/scripts/cost-runtime/cost-cli.ts +37 -16
  120. package/scripts/cost-runtime/cost-pricing.ts +9 -0
  121. package/scripts/cost-runtime/cost-verdict.ts +4 -1
  122. package/scripts/delegation/delegation-policy.ts +2 -2
  123. package/scripts/delegation/duplicate-read-guard.ts +1 -0
  124. package/scripts/delegation/investigation-guard.ts +14 -2
  125. package/scripts/delegation/investigation-reads.ts +45 -23
  126. package/scripts/dependabot/dependabot-cooldown.ts +3 -2
  127. package/scripts/discovery/repo-party.ts +80 -20
  128. package/scripts/discovery/session-owner-pin.ts +51 -0
  129. package/scripts/document/capped-print.ts +1 -1
  130. package/scripts/document/command-reference-line-budget.ts +42 -0
  131. package/scripts/document/document-byte-budget.ts +17 -7
  132. package/scripts/document/document-checks.ts +20 -0
  133. package/scripts/document/document-ratchet-check.ts +101 -0
  134. package/scripts/document/document-section.ts +1 -0
  135. package/scripts/document/entry-read-budget.ts +7 -3
  136. package/scripts/document/issue-citation-budget.ts +94 -0
  137. package/scripts/epic/epic-cli-argv.ts +2 -2
  138. package/scripts/epic/epic-fetch.ts +4 -2
  139. package/scripts/epic/epic-graph.ts +7 -2
  140. package/scripts/epic/epic-issue.ts +3 -1
  141. package/scripts/epic/epic-rank.ts +5 -0
  142. package/scripts/exports/unused-members-check.ts +62 -0
  143. package/scripts/exports/unused-members-cli.ts +6 -51
  144. package/scripts/followup/followup-ci-path.ts +67 -0
  145. package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
  146. package/scripts/followup/followup-coderabbit-wait.ts +13 -10
  147. package/scripts/followup/followup-failed-tests.ts +160 -0
  148. package/scripts/followup/followup-job-needs.ts +100 -0
  149. package/scripts/followup/followup-job-rerun.ts +303 -0
  150. package/scripts/followup/followup-main-move.ts +113 -0
  151. package/scripts/followup/git-followup-finish.ts +43 -11
  152. package/scripts/followup/git-followup-pending.ts +3 -3
  153. package/scripts/followup/git-followup-stages.ts +41 -11
  154. package/scripts/followup/git-pr-followup-checks.ts +55 -16
  155. package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
  156. package/scripts/followup/git-pr-followup.ts +62 -27
  157. package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
  158. package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
  159. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
  160. package/scripts/gate/busy-average.ts +34 -2
  161. package/scripts/gate/check-related-pinned.ts +43 -0
  162. package/scripts/gate/check-related-reuse.ts +64 -0
  163. package/scripts/gate/check-related-section.ts +57 -0
  164. package/scripts/gate/check-related-unplanned.ts +34 -0
  165. package/scripts/gate/check-related.ts +265 -0
  166. package/scripts/gate/command-memory.ts +1 -1
  167. package/scripts/gate/core-admission.ts +24 -6
  168. package/scripts/gate/core-budget-timing.ts +20 -6
  169. package/scripts/gate/core-budget.ts +40 -11
  170. package/scripts/gate/core-wait-record.ts +3 -2
  171. package/scripts/gate/core-wait.ts +25 -2
  172. package/scripts/gate/core-weights.ts +15 -7
  173. package/scripts/gate/gate-labels.ts +46 -0
  174. package/scripts/gate/gate-ledger.ts +14 -6
  175. package/scripts/gate/gate-plan.ts +103 -58
  176. package/scripts/gate/gate-report.ts +9 -7
  177. package/scripts/gate/gate-run-steps.ts +26 -3
  178. package/scripts/gate/gate-skip.ts +45 -6
  179. package/scripts/gate/gate-static-group.ts +60 -0
  180. package/scripts/gate/gate-steps.ts +2 -1
  181. package/scripts/gate/gate-tree.ts +4 -2
  182. package/scripts/gate/hook-gate-reuse.ts +19 -2
  183. package/scripts/gate/metrics-totals.ts +59 -0
  184. package/scripts/gate/scoped-green.ts +68 -15
  185. package/scripts/gate/since-green.ts +14 -6
  186. package/scripts/gate/structural-checks.ts +96 -0
  187. package/scripts/gate/verification-gate.ts +51 -16
  188. package/scripts/gate/verification-inputs.ts +21 -6
  189. package/scripts/gate/verification-tail.ts +52 -0
  190. package/scripts/gh/gh-author-association.ts +23 -2
  191. package/scripts/gh/git-ai-review-scan.ts +1 -1
  192. package/scripts/gh/git-gh-api-path.ts +12 -3
  193. package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
  194. package/scripts/gh/git-gh-exec.ts +32 -2
  195. package/scripts/gh/git-gh-issue-read.ts +4 -2
  196. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  197. package/scripts/gh/git-gh-issue-write.ts +8 -2
  198. package/scripts/gh/git-gh-issue.ts +12 -5
  199. package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
  200. package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
  201. package/scripts/gh/git-gh-pr-read.ts +74 -13
  202. package/scripts/gh/git-gh-pr-rest.ts +3 -1
  203. package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
  204. package/scripts/gh/git-gh-pr-too-large.ts +20 -0
  205. package/scripts/gh/git-gh-pr.ts +21 -7
  206. package/scripts/gh/git-gh-retry.ts +141 -0
  207. package/scripts/gh/git-pr-ai-review.ts +15 -6
  208. package/scripts/gh/git-pr-checks-eval.ts +3 -0
  209. package/scripts/gh/git-pr-checks.ts +5 -5
  210. package/scripts/git/base-tree.ts +30 -0
  211. package/scripts/git/change-base.ts +4 -10
  212. package/scripts/git/changed-paths-sync.ts +63 -0
  213. package/scripts/git/changed-paths.ts +16 -1
  214. package/scripts/git/git-common-directory.ts +11 -1
  215. package/scripts/git/git-diff-reads.ts +66 -20
  216. package/scripts/git/git-error.ts +9 -2
  217. package/scripts/git/git-schemas.ts +13 -0
  218. package/scripts/git/git-worktree.ts +13 -0
  219. package/scripts/git/gone-branch.ts +4 -1
  220. package/scripts/git/main-merge-budget-conflict.ts +89 -0
  221. package/scripts/git/main-merge-guard.ts +55 -18
  222. package/scripts/git/main-merge-regenerate.ts +59 -25
  223. package/scripts/git/main-merge.ts +53 -5
  224. package/scripts/git/no-base-checkout.ts +127 -0
  225. package/scripts/git/stash/git-stash.ts +11 -2
  226. package/scripts/git/stash/stash-push-cli.ts +10 -0
  227. package/scripts/hooks/batch-guard.ts +40 -21
  228. package/scripts/hooks/edited-cspell.ts +37 -11
  229. package/scripts/hooks/format-edited-file.ts +22 -2
  230. package/scripts/hooks/lane-plan-guard.ts +50 -0
  231. package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
  232. package/scripts/hooks/pre-commit-lint.ts +14 -1
  233. package/scripts/hooks/pre-push-related-switch.ts +10 -0
  234. package/scripts/hooks/pre-push-unit.ts +76 -10
  235. package/scripts/hooks/pretool-guard.ts +2 -0
  236. package/scripts/hooks/reserved-run.ts +14 -1
  237. package/scripts/hooks/run-hook.sh +23 -8
  238. package/scripts/hooks/step-zero-notice.ts +6 -1
  239. package/scripts/hooks/stop-actions.ts +3 -15
  240. package/scripts/hooks/stop-guard.ts +7 -6
  241. package/scripts/init/distributed-paths.ts +1 -0
  242. package/scripts/init/hook-command-rewrite.ts +5 -1
  243. package/scripts/init/hook-launch.ts +4 -2
  244. package/scripts/issue/aggregation-split.ts +52 -0
  245. package/scripts/issue/defect-origin-line.ts +19 -1
  246. package/scripts/issue/defect-rate-cli.ts +5 -102
  247. package/scripts/issue/defect-report.ts +4 -4
  248. package/scripts/issue/effect-audit-cli.ts +178 -0
  249. package/scripts/issue/effect-audit.ts +185 -0
  250. package/scripts/issue/expected-effect-lint.ts +64 -9
  251. package/scripts/issue/git-next-issues.ts +5 -0
  252. package/scripts/issue/issue-body-or-comment.ts +38 -4
  253. package/scripts/issue/issue-cite-cli.ts +1 -3
  254. package/scripts/issue/issue-classification.ts +1 -0
  255. package/scripts/issue/issue-closing-pr.ts +8 -1
  256. package/scripts/issue/issue-evidence-exit.ts +4 -2
  257. package/scripts/issue/issue-file-cap.ts +58 -0
  258. package/scripts/issue/issue-file-cli.ts +111 -38
  259. package/scripts/issue/issue-file-deferral.ts +52 -0
  260. package/scripts/issue/issue-file-fold.ts +29 -10
  261. package/scripts/issue/issue-file-interrupt.ts +85 -0
  262. package/scripts/issue/issue-file-lane-hint.ts +30 -0
  263. package/scripts/issue/issue-file.ts +43 -6
  264. package/scripts/issue/issue-labels.ts +19 -2
  265. package/scripts/issue/issue-lint-cli.ts +27 -2
  266. package/scripts/issue/issue-measured-cli.ts +13 -35
  267. package/scripts/issue/issue-measured-close.ts +58 -0
  268. package/scripts/issue/issue-not-before-label.ts +2 -2
  269. package/scripts/issue/issue-not-before.ts +4 -1
  270. package/scripts/issue/issue-priority-cli.ts +60 -0
  271. package/scripts/issue/issue-priority-raise.ts +55 -0
  272. package/scripts/issue/issue-priority.ts +174 -43
  273. package/scripts/issue/issue-rank.ts +21 -4
  274. package/scripts/issue/issue-read-cli.ts +32 -6
  275. package/scripts/issue/issue-read.ts +37 -12
  276. package/scripts/issue/issue-sample-gate.ts +95 -74
  277. package/scripts/issue/issue-sample-prime.ts +127 -0
  278. package/scripts/issue/issue-sample-required.ts +57 -0
  279. package/scripts/issue/issue-sample-source.ts +12 -11
  280. package/scripts/issue/issue-search.ts +124 -0
  281. package/scripts/issue/issue-state.ts +13 -1
  282. package/scripts/issue/issue-template-section.ts +43 -0
  283. package/scripts/issue/issue-watch-diff.ts +31 -1
  284. package/scripts/issue/issue-watch-hook.ts +11 -2
  285. package/scripts/issue/issue-watch.ts +55 -12
  286. package/scripts/issue/markdown-section.ts +1 -0
  287. package/scripts/issue/measure-declaration.ts +121 -0
  288. package/scripts/issue/measure-rerun-cli.ts +7 -70
  289. package/scripts/issue/plan-consumers-section.ts +22 -1
  290. package/scripts/issue/reproduction-measure.ts +3 -1
  291. package/scripts/issue/size-estimate.ts +90 -0
  292. package/scripts/issue/trusted-measure.ts +84 -0
  293. package/scripts/josh/command-usage.ts +3 -2
  294. package/scripts/josh/durable-state-migrate.ts +105 -0
  295. package/scripts/josh/durable-state.ts +112 -0
  296. package/scripts/josh/josh-aliases.ts +95 -0
  297. package/scripts/josh/josh-command-map.ts +1 -82
  298. package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
  299. package/scripts/josh/josh-commands-ai.ts +5 -5
  300. package/scripts/josh/josh-commands-development.ts +59 -58
  301. package/scripts/josh/josh-commands-issue-write.ts +23 -4
  302. package/scripts/josh/josh-commands-issue.ts +32 -0
  303. package/scripts/josh/josh-commands-lane.ts +87 -4
  304. package/scripts/josh/josh-commands-lint.ts +16 -3
  305. package/scripts/josh/josh-commands-maintenance.ts +15 -0
  306. package/scripts/josh/josh-commands-review.ts +41 -6
  307. package/scripts/josh/josh-commands-ship.ts +56 -8
  308. package/scripts/josh/josh-commands-test-check.ts +80 -0
  309. package/scripts/josh/josh-commands-workflow.ts +1 -1
  310. package/scripts/josh/josh-environment-file.ts +43 -3
  311. package/scripts/josh/josh-in-process.ts +2 -2
  312. package/scripts/josh/josh-logic.ts +5 -3
  313. package/scripts/josh/josh-run.ts +19 -1
  314. package/scripts/josh/run-record-path.ts +15 -0
  315. package/scripts/josh/stamp-file.ts +11 -2
  316. package/scripts/lane/lane-adopt-cli.ts +98 -0
  317. package/scripts/lane/lane-adopt.ts +208 -0
  318. package/scripts/lane/lane-await.ts +5 -8
  319. package/scripts/lane/lane-baseline.ts +123 -0
  320. package/scripts/lane/lane-breakdown-cli.ts +64 -0
  321. package/scripts/lane/lane-breakdown-implement.ts +170 -0
  322. package/scripts/lane/lane-breakdown-laps.ts +107 -0
  323. package/scripts/lane/lane-breakdown-pinned.ts +76 -0
  324. package/scripts/lane/lane-breakdown-text.ts +145 -0
  325. package/scripts/lane/lane-breakdown.ts +239 -0
  326. package/scripts/lane/lane-check-stats.ts +29 -8
  327. package/scripts/lane/lane-child-invocation.ts +9 -2
  328. package/scripts/lane/lane-child-mark-keys.ts +12 -0
  329. package/scripts/lane/lane-child-marker.ts +20 -1
  330. package/scripts/lane/lane-ci-path-stats.ts +73 -0
  331. package/scripts/lane/lane-claim-stats.ts +84 -0
  332. package/scripts/lane/lane-close.ts +8 -3
  333. package/scripts/lane/lane-dispatch-log.ts +3 -3
  334. package/scripts/lane/lane-dispatch.ts +2 -2
  335. package/scripts/lane/lane-gap-stats.ts +7 -6
  336. package/scripts/lane/lane-guard-policy.ts +7 -1
  337. package/scripts/lane/lane-implement-stats.ts +207 -0
  338. package/scripts/lane/lane-implement-subagents.ts +90 -0
  339. package/scripts/lane/lane-investigation-switch.ts +16 -0
  340. package/scripts/lane/lane-ledger-kind.ts +31 -0
  341. package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
  342. package/scripts/lane/lane-ledger-schema.ts +119 -36
  343. package/scripts/lane/lane-ledger-write.ts +257 -0
  344. package/scripts/lane/lane-ledger.ts +31 -177
  345. package/scripts/lane/lane-load.ts +1 -1
  346. package/scripts/lane/lane-measure-cli.ts +176 -59
  347. package/scripts/lane/lane-net-read.ts +44 -0
  348. package/scripts/lane/lane-net-time.ts +212 -0
  349. package/scripts/lane/lane-open.ts +16 -7
  350. package/scripts/lane/lane-output.ts +2 -4
  351. package/scripts/lane/lane-overrun-prompt.ts +147 -0
  352. package/scripts/lane/lane-overrun.ts +274 -0
  353. package/scripts/lane/lane-paths.ts +24 -1
  354. package/scripts/lane/lane-pause-cli.ts +4 -1
  355. package/scripts/lane/lane-paused-spans.ts +97 -0
  356. package/scripts/lane/lane-plan-check.ts +207 -0
  357. package/scripts/lane/lane-plan-cli.ts +41 -0
  358. package/scripts/lane/lane-plan.ts +144 -0
  359. package/scripts/lane/lane-registry.ts +14 -1
  360. package/scripts/lane/lane-relaunch.ts +1 -1
  361. package/scripts/lane/lane-round-one-stats.ts +51 -0
  362. package/scripts/lane/lane-sampler.ts +23 -4
  363. package/scripts/lane/lane-session-action.ts +93 -18
  364. package/scripts/lane/lane-session-broker.ts +49 -21
  365. package/scripts/lane/lane-session-reread-main.ts +14 -0
  366. package/scripts/lane/lane-session-reread.ts +51 -0
  367. package/scripts/lane/lane-ship-lap-stats.ts +74 -0
  368. package/scripts/lane/lane-sleep.ts +58 -0
  369. package/scripts/lane/lane-spent.ts +1 -1
  370. package/scripts/lane/lane-split-stats.ts +28 -0
  371. package/scripts/lane/lane-stage-stats.ts +13 -1
  372. package/scripts/lane/lane-state.ts +41 -9
  373. package/scripts/lane/lane-stats-tables.ts +58 -0
  374. package/scripts/lane/lane-stats.ts +21 -5
  375. package/scripts/lane/lane-stop-stats.ts +51 -19
  376. package/scripts/lane/lane-tail-stats.ts +32 -0
  377. package/scripts/lane/lane-transcript-calls.ts +67 -10
  378. package/scripts/lane/lane-transcript-stats.ts +44 -12
  379. package/scripts/lane/lane-value-cell.ts +72 -0
  380. package/scripts/lane/lane-value.ts +118 -0
  381. package/scripts/lane/lane-withdraw-closed.ts +124 -0
  382. package/scripts/lane/lane-withdraw.ts +108 -31
  383. package/scripts/lane/lane-yield.ts +85 -0
  384. package/scripts/lane/openai-lane-ship.ts +12 -11
  385. package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
  386. package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
  387. package/scripts/lane/openai-lane-supervisor.ts +5 -4
  388. package/scripts/lib/poll.ts +38 -9
  389. package/scripts/lib/settled-together.ts +10 -0
  390. package/scripts/lib/shell-quote.ts +21 -0
  391. package/scripts/lib/token-shape.ts +111 -0
  392. package/scripts/lint/eslint-daemon-sources.ts +79 -0
  393. package/scripts/lint/eslint-daemon.ts +45 -6
  394. package/scripts/lint/eslint-warm-cli.ts +7 -0
  395. package/scripts/lint/eslint-warm.ts +66 -0
  396. package/scripts/lint/import-graph.ts +141 -11
  397. package/scripts/lint/lint-gate-scope.ts +2 -2
  398. package/scripts/lint/lint-parallel.ts +54 -6
  399. package/scripts/lint/lint-related.ts +154 -33
  400. package/scripts/lint/rename-cli.ts +179 -0
  401. package/scripts/lint/rename-identifier.ts +192 -0
  402. package/scripts/lint/type-only-imports.ts +58 -0
  403. package/scripts/notify/telegram-notify.ts +12 -3
  404. package/scripts/observations/observation-record.ts +42 -16
  405. package/scripts/observations/observations-flush.ts +32 -9
  406. package/scripts/overrides/overrides-check.ts +9 -1
  407. package/scripts/release/release-approval-prune.ts +7 -1
  408. package/scripts/repo/required-checks-logic.ts +4 -1
  409. package/scripts/repo/ruleset-check.ts +4 -3
  410. package/scripts/report/markdown-shape.ts +28 -0
  411. package/scripts/report/report-format-reference.ts +15 -1
  412. package/scripts/report/report-labels.ts +12 -1
  413. package/scripts/report/report-lint-child-summary.ts +94 -0
  414. package/scripts/report/report-lint-cli.ts +26 -7
  415. package/scripts/report/report-lint.ts +2 -20
  416. package/scripts/review/prose-stale-cli.ts +88 -0
  417. package/scripts/review/prose-stale-scan.ts +152 -0
  418. package/scripts/review/review-attest.ts +73 -23
  419. package/scripts/review/review-brief-cli.ts +68 -19
  420. package/scripts/review/review-brief-paths.ts +22 -0
  421. package/scripts/review/review-brief.ts +14 -7
  422. package/scripts/review/review-comment-carry.ts +47 -0
  423. package/scripts/review/review-comment-round.ts +85 -22
  424. package/scripts/review/review-finding-ledger.ts +109 -7
  425. package/scripts/review/review-finding-text.ts +43 -0
  426. package/scripts/review/review-interaction.ts +11 -0
  427. package/scripts/review/review-lane-handover.ts +68 -0
  428. package/scripts/review/review-lint-cli.ts +57 -0
  429. package/scripts/review/review-lint-findings.ts +92 -0
  430. package/scripts/review/review-lint-sections.ts +80 -0
  431. package/scripts/review/review-lint.ts +221 -0
  432. package/scripts/review/review-prior-findings.ts +102 -0
  433. package/scripts/review/review-readers-scan.ts +4 -2
  434. package/scripts/review/review-record-cli.ts +177 -54
  435. package/scripts/review/review-record-code-round.ts +55 -0
  436. package/scripts/review/review-record-comment.ts +60 -0
  437. package/scripts/review/review-record-interaction.ts +35 -0
  438. package/scripts/review/review-record-pinned.ts +108 -0
  439. package/scripts/review/review-record.ts +25 -1
  440. package/scripts/review/review-reviewed-tree.ts +307 -0
  441. package/scripts/review/review-round-one-closure.ts +62 -0
  442. package/scripts/review/review-round-reuse.ts +106 -0
  443. package/scripts/review/review-round2-cli.ts +91 -29
  444. package/scripts/review/review-round2-skip-comment.ts +55 -0
  445. package/scripts/review/review-round2.ts +24 -8
  446. package/scripts/review/review-stamps.ts +7 -3
  447. package/scripts/review/review-stop-log.ts +20 -6
  448. package/scripts/review/review-stops-cli.ts +2 -1
  449. package/scripts/review/review-submit-cli.ts +101 -0
  450. package/scripts/rules/agent-model.ts +1 -1
  451. package/scripts/rules/bash-triggers.ts +3 -3
  452. package/scripts/rules/concise-reply.ts +88 -0
  453. package/scripts/rules/credential-body.ts +77 -0
  454. package/scripts/rules/decision-oracle.ts +1 -1
  455. package/scripts/rules/delivered-rules.ts +36 -17
  456. package/scripts/rules/destructive-command.ts +3 -11
  457. package/scripts/rules/direct-issue-comment.ts +34 -12
  458. package/scripts/rules/direct-issue-read.ts +191 -0
  459. package/scripts/rules/direct-pr-create.ts +4 -24
  460. package/scripts/rules/early-heartbeat.ts +2 -0
  461. package/scripts/rules/edit-tool.ts +27 -0
  462. package/scripts/rules/file-edit-rows.ts +17 -0
  463. package/scripts/rules/file-rewrite.ts +146 -0
  464. package/scripts/rules/firing-point.ts +3 -2
  465. package/scripts/rules/gh-api.ts +128 -7
  466. package/scripts/rules/gh-repo-selector.ts +84 -0
  467. package/scripts/rules/git-force.ts +2 -2
  468. package/scripts/rules/guard-remedy.ts +14 -5
  469. package/scripts/rules/implementation-cut.ts +61 -28
  470. package/scripts/rules/investigator-foreground.ts +231 -0
  471. package/scripts/rules/issue-citation.ts +15 -60
  472. package/scripts/rules/issue-comments.ts +9 -4
  473. package/scripts/rules/josh-git-bare.ts +1 -1
  474. package/scripts/rules/lane-background.ts +41 -13
  475. package/scripts/rules/lane-direct-tool.ts +107 -9
  476. package/scripts/rules/lane-interactive-ask.ts +4 -1
  477. package/scripts/rules/lane-park.ts +4 -2
  478. package/scripts/rules/lane-spilled-read.ts +90 -0
  479. package/scripts/rules/lane-split-park.ts +1 -1
  480. package/scripts/rules/lane-switch-main.ts +4 -4
  481. package/scripts/rules/last-prompt.ts +20 -47
  482. package/scripts/rules/oracle-consulted.ts +1 -1
  483. package/scripts/rules/permission-guards.ts +5 -1
  484. package/scripts/rules/piped-verification-shapes.ts +110 -0
  485. package/scripts/rules/piped-verification.ts +67 -17
  486. package/scripts/rules/poll-loop.ts +72 -9
  487. package/scripts/rules/pr-merge.ts +5 -5
  488. package/scripts/rules/pre-gate-cut.ts +3 -3
  489. package/scripts/rules/protected-files.ts +88 -24
  490. package/scripts/rules/reply-language.ts +3 -17
  491. package/scripts/rules/reply-prose.ts +34 -0
  492. package/scripts/rules/repo-admin.ts +132 -0
  493. package/scripts/rules/reviewer-foreground.ts +88 -0
  494. package/scripts/rules/round-one-check-related.ts +120 -0
  495. package/scripts/rules/rule-body-guard.ts +5 -15
  496. package/scripts/rules/rule-value-cache.ts +53 -5
  497. package/scripts/rules/rule-value-candidates.ts +84 -0
  498. package/scripts/rules/rule-value-cli.ts +59 -11
  499. package/scripts/rules/rule-value.ts +17 -4
  500. package/scripts/rules/run-tail-rule.ts +1 -1
  501. package/scripts/rules/sed-in-place.ts +196 -0
  502. package/scripts/rules/shell-segments.ts +10 -2
  503. package/scripts/rules/stop-rule-rows.ts +1 -13
  504. package/scripts/rules/stop-rules.ts +33 -58
  505. package/scripts/rules/test-declared-commit.ts +1 -1
  506. package/scripts/rules/third-party-write.ts +110 -23
  507. package/scripts/rules/timed-rerun.ts +1 -1
  508. package/scripts/rules/turn-filings.ts +90 -0
  509. package/scripts/rules/worktree-guard.ts +22 -7
  510. package/scripts/run/board/run-board-ending-reason.ts +6 -2
  511. package/scripts/run/board/run-board-fit.ts +24 -1
  512. package/scripts/run/board/run-board-found.ts +134 -0
  513. package/scripts/run/board/run-board-header.ts +8 -0
  514. package/scripts/run/board/run-board-labels.ts +11 -1
  515. package/scripts/run/board/run-board-lane-time.ts +1 -0
  516. package/scripts/run/board/run-board-link.ts +15 -2
  517. package/scripts/run/board/run-board-notes.ts +7 -1
  518. package/scripts/run/board/run-board-operation.ts +4 -2
  519. package/scripts/run/board/run-board-phase.ts +2 -5
  520. package/scripts/run/board/run-board-plan.ts +1 -1
  521. package/scripts/run/board/run-board-read.ts +46 -1
  522. package/scripts/run/board/run-board-reason.ts +20 -8
  523. package/scripts/run/board/run-board-render-checks.ts +3 -2
  524. package/scripts/run/board/run-board-render-drawn.ts +11 -0
  525. package/scripts/run/board/run-board-render-found.ts +157 -0
  526. package/scripts/run/board/run-board-render-lead.ts +9 -0
  527. package/scripts/run/board/run-board-render-legend.ts +19 -0
  528. package/scripts/run/board/run-board-render-tail.ts +1 -1
  529. package/scripts/run/board/run-board-render.ts +82 -18
  530. package/scripts/run/board/run-board-spin.ts +1 -3
  531. package/scripts/run/board/run-board-status.ts +2 -0
  532. package/scripts/run/board/run-board-tick.ts +39 -10
  533. package/scripts/run/carry/run-carry-ended.ts +3 -2
  534. package/scripts/run/carry/run-carry.ts +3 -2
  535. package/scripts/run/cut/run-cut-cli.ts +33 -133
  536. package/scripts/run/cut/run-cut-digest.ts +152 -0
  537. package/scripts/run/cut/run-cut-handoff.ts +52 -8
  538. package/scripts/run/cut/run-cut-report.ts +24 -3
  539. package/scripts/run/cut/run-cut-resume.ts +129 -0
  540. package/scripts/run/cut/run-cut-review.ts +105 -0
  541. package/scripts/run/cut/run-cut.ts +18 -7
  542. package/scripts/run/detached-launch.ts +1 -1
  543. package/scripts/run/entry/run-entry-cli.ts +88 -19
  544. package/scripts/run/entry/run-entry-spill.ts +83 -0
  545. package/scripts/run/entry/run-entry-stop.ts +5 -1
  546. package/scripts/run/entry/run-entry-trust.ts +91 -0
  547. package/scripts/run/event/run-event-baseline.ts +56 -0
  548. package/scripts/run/event/run-event-filed.ts +9 -3
  549. package/scripts/run/event/run-event-overrun.ts +197 -0
  550. package/scripts/run/event/run-event-render.ts +4 -0
  551. package/scripts/run/event/run-event-stream.ts +25 -3
  552. package/scripts/run/hold/run-stop-notify.ts +3 -8
  553. package/scripts/run/merge/run-merge-cap.ts +57 -0
  554. package/scripts/run/merge/run-merge-cli.ts +66 -23
  555. package/scripts/run/merge/run-merge-outcome.ts +2 -0
  556. package/scripts/run/merge/run-merge-ship.ts +13 -3
  557. package/scripts/run/merge/run-merge-signals.ts +40 -23
  558. package/scripts/run/merge/run-merge-steps.ts +56 -36
  559. package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
  560. package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
  561. package/scripts/run/merge/run-merge.ts +41 -14
  562. package/scripts/run/review/run-review-cli.ts +306 -20
  563. package/scripts/run/review/run-review-early-push.ts +121 -0
  564. package/scripts/run/review/run-review-join-read.ts +94 -0
  565. package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
  566. package/scripts/run/review/run-review-pinned-join.ts +216 -0
  567. package/scripts/run/review/run-review-pinned-steps.ts +383 -0
  568. package/scripts/run/review/run-review-pinned-tree.ts +37 -0
  569. package/scripts/run/review/run-review-pinned.ts +53 -0
  570. package/scripts/run/review/run-review-steps.ts +70 -34
  571. package/scripts/run/review/run-review.ts +26 -6
  572. package/scripts/run/run-parent-cut-hook.ts +3 -4
  573. package/scripts/run/run-prep.ts +1 -0
  574. package/scripts/run/run-stage-read.ts +2 -6
  575. package/scripts/run/run-step-cli.ts +17 -5
  576. package/scripts/run/run-step-lane-plan.ts +27 -0
  577. package/scripts/run/run-step-section.ts +26 -7
  578. package/scripts/run/run-step.ts +5 -2
  579. package/scripts/run/ship/run-ship-args.ts +19 -0
  580. package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
  581. package/scripts/run/ship/run-ship-cli.ts +131 -39
  582. package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
  583. package/scripts/run/ship/run-ship-detach.ts +10 -4
  584. package/scripts/run/ship/run-ship-handover.ts +106 -0
  585. package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
  586. package/scripts/run/ship/run-ship-lap.ts +63 -0
  587. package/scripts/run/ship/run-ship-next.ts +27 -26
  588. package/scripts/run/ship/run-ship-overlap.ts +8 -3
  589. package/scripts/run/ship/run-ship-place.ts +9 -2
  590. package/scripts/run/ship/run-ship-planned.ts +92 -0
  591. package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
  592. package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
  593. package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
  594. package/scripts/run/ship/run-ship-preflight.ts +16 -4
  595. package/scripts/run/ship/run-ship-probe.ts +23 -9
  596. package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
  597. package/scripts/run/ship/run-ship-relaunch.ts +51 -0
  598. package/scripts/run/ship/run-ship-return.ts +103 -29
  599. package/scripts/run/ship/run-ship-review-reason.ts +24 -0
  600. package/scripts/run/ship/run-ship-review-steps.ts +230 -59
  601. package/scripts/run/ship/run-ship-review.ts +171 -51
  602. package/scripts/run/ship/run-ship-reviewer.ts +138 -42
  603. package/scripts/run/ship/run-ship-scoped.ts +39 -10
  604. package/scripts/run/ship/run-ship-stage.ts +49 -13
  605. package/scripts/run/ship/run-ship-steps.ts +24 -4
  606. package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
  607. package/scripts/run/ship/run-ship-stop-context.ts +50 -13
  608. package/scripts/run/ship/run-ship-sync.ts +171 -30
  609. package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
  610. package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
  611. package/scripts/run/ship/run-ship-waiter.ts +114 -0
  612. package/scripts/run/ship/run-ship.ts +16 -2
  613. package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
  614. package/scripts/run/wake/run-wake-cli.ts +6 -113
  615. package/scripts/run/wake/run-wake-code.ts +53 -11
  616. package/scripts/run/wake/run-wake-driver.ts +5 -3
  617. package/scripts/run/wake/run-wake-finish.ts +137 -0
  618. package/scripts/run/wake/run-wake-loop.ts +5 -3
  619. package/scripts/run/wake/run-wake-ports.ts +11 -3
  620. package/scripts/run/wake/run-wake-session.ts +2 -0
  621. package/scripts/run/wake/run-wake.ts +3 -2
  622. package/scripts/safe-chain/ci-installer-pin.ts +49 -8
  623. package/scripts/safe-chain/project-config.ts +3 -2
  624. package/scripts/security/secretlint-scan.ts +42 -9
  625. package/scripts/security/security-audit-provision-main.ts +9 -1
  626. package/scripts/security/security-audit-provision.ts +1 -1
  627. package/scripts/security/security-audit.ts +21 -1
  628. package/scripts/security/sonar-file.ts +10 -5
  629. package/scripts/split/split-assess.ts +12 -3
  630. package/scripts/split/split-early-notice.ts +116 -0
  631. package/scripts/split/split-measure.ts +20 -2
  632. package/scripts/split/split-resolution.ts +107 -0
  633. package/scripts/test/direct-importers.ts +185 -0
  634. package/scripts/test/pure-files-entries.ts +83 -0
  635. package/scripts/test/related-heavy-tests.ts +81 -0
  636. package/scripts/test/test-no-base.ts +88 -0
  637. package/scripts/test/test-pinned-cache-logic.ts +363 -0
  638. package/scripts/test/test-pinned-cache.ts +337 -0
  639. package/scripts/test/test-pinned-emit.ts +49 -0
  640. package/scripts/test/test-pinned-functions.ts +116 -0
  641. package/scripts/test/test-pinned-ledger.ts +80 -0
  642. package/scripts/test/test-pinned-logic.ts +208 -20
  643. package/scripts/test/test-pinned-main.ts +84 -18
  644. package/scripts/test/test-pinned-pool.ts +73 -0
  645. package/scripts/test/test-pinned-probe.ts +254 -0
  646. package/scripts/test/test-pinned-prune-logic.ts +118 -0
  647. package/scripts/test/test-pinned-reach.ts +194 -0
  648. package/scripts/test/test-pinned-record.ts +196 -0
  649. package/scripts/test/test-pinned-rewire.ts +148 -0
  650. package/scripts/test/test-pinned-spawn.ts +81 -0
  651. package/scripts/test/test-pinned-stage.ts +70 -0
  652. package/scripts/test/test-pinned.ts +258 -47
  653. package/scripts/test/test-reach-cli.ts +61 -0
  654. package/scripts/test/test-read-map.ts +35 -11
  655. package/scripts/test/test-read-recording.ts +17 -5
  656. package/scripts/test/test-read-trace.ts +26 -8
  657. package/scripts/test/test-red-logic.ts +46 -7
  658. package/scripts/test/test-red.ts +34 -14
  659. package/scripts/test/test-related-claim.ts +37 -0
  660. package/scripts/test/test-related-main.ts +4 -1
  661. package/scripts/test/test-related-moved.ts +91 -0
  662. package/scripts/test/test-related-record.ts +43 -23
  663. package/scripts/test/test-related-scope.ts +99 -34
  664. package/scripts/test/test-related-synced.ts +135 -0
  665. package/scripts/test/test-related-touched.ts +84 -0
  666. package/scripts/test/test-related.ts +167 -83
  667. package/scripts/test/test-unit-guard.ts +28 -5
  668. package/scripts/test/unit-durations.ts +41 -0
  669. package/scripts/test/unit-worker-share.ts +5 -4
  670. package/scripts/test/vitest-cache-directory.ts +19 -0
  671. package/scripts/test/vitest-cli-excludes.ts +14 -0
  672. package/scripts/test/vitest-failure-summary.ts +111 -0
  673. package/scripts/test/whole-suite-files.ts +12 -1
  674. package/scripts/time-runtime/time-batch-guard.ts +42 -4
  675. package/scripts/time-runtime/time-bundle-call.ts +1 -1
  676. package/scripts/time-runtime/time-bundles.ts +36 -5
  677. package/scripts/time-runtime/time-markers.ts +2 -2
  678. package/scripts/time-runtime/time-search-call.ts +38 -0
  679. package/scripts/time-runtime/time-shell.ts +1 -1
  680. package/scripts/time-runtime/time-transcript-line.ts +17 -5
  681. package/scripts/version/development-engines-verdict.ts +124 -0
  682. package/scripts/version/latest-corepack.ts +2 -0
  683. package/templates/gitignore +2 -0
  684. package/templates/workflows/ci.yml +41 -0
  685. package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
  686. package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
  687. package/dist/hooks/chunk-TUIFS5E7.js +0 -72
  688. package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
  689. package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
  690. package/scripts/rules/filing-cap.ts +0 -139
@@ -0,0 +1,113 @@
1
+ import { git_command } from '#scripts/git/git-command'
2
+ import { main_merge_guard } from '#scripts/git/main-merge-guard'
3
+ import type { ObservationEntry } from '#scripts/observations/observation-record'
4
+ import { followup_failed_tests } from './followup-failed-tests'
5
+
6
+ // **A test red outside the change that main has since changed is merged, not rerun**
7
+ // (joshuafolkken/kit#5316): a date-bound test fixed on main went red on a lane still on the old base,
8
+ // and the rerun on that base was red again before `merge_again` (`run-ship-sync.ts`) took main in. So
9
+ // before a rerun, a failed test whose file or subject module (`followup_failed_tests.subjects_of`) main
10
+ // moved since the branch point skips it: `followup` fails as before and ship's merge, gate and push go
11
+ // first. The rerun right is unspent, and after the merge the same file is no longer incoming, so a
12
+ // test still red is rerun once as before.
13
+
14
+ const OBSERVATION_SLUG = 'followup-main-merge-first'
15
+ const OBSERVATION_DEPTH = 'd1'
16
+ const LATEST_COMMIT = 1
17
+ const SHORT_SHA_LENGTH = 12
18
+
19
+ interface MainMove {
20
+ files: ReadonlyArray<string>
21
+ commit: string
22
+ }
23
+
24
+ // A failed test file beside the path main moved for it: the file itself or its subject module.
25
+ interface MovedTest {
26
+ file: string
27
+ moved: string
28
+ }
29
+
30
+ function moved_tests(
31
+ test_files: ReadonlyArray<string>,
32
+ incoming: ReadonlySet<string>,
33
+ ): Array<MovedTest> {
34
+ return test_files.flatMap((file) => {
35
+ const moved = followup_failed_tests.subjects_of(file).find((subject) => incoming.has(subject))
36
+
37
+ return moved === undefined ? [] : { file, moved }
38
+ })
39
+ }
40
+
41
+ // The main-side commit is the latest on main's own line that touched the first moved path.
42
+ async function latest_commit(file: string, main_reference: string): Promise<string> {
43
+ const [commit] = await git_command.log_first_parent(LATEST_COMMIT, file, main_reference)
44
+
45
+ return commit ?? main_reference
46
+ }
47
+
48
+ // **The failed test files main moved since the branch point**, `undefined` when main did not move or
49
+ // moved none of them. The fetch is what makes `origin/<default>` current, as `main_merge.merge` does.
50
+ async function read_main_move(test_files: ReadonlyArray<string>): Promise<MainMove | undefined> {
51
+ if (test_files.length === 0) return undefined
52
+
53
+ const default_branch = await git_command.get_default_branch()
54
+
55
+ await git_command.fetch_branch(default_branch)
56
+
57
+ const incoming = new Set(await main_merge_guard.incoming_paths(default_branch))
58
+ const moved = moved_tests(test_files, incoming)
59
+ const [first] = moved
60
+
61
+ if (first === undefined) return undefined
62
+
63
+ return {
64
+ files: moved.map(({ file }) => file),
65
+ commit: await latest_commit(first.moved, `origin/${default_branch}`),
66
+ }
67
+ }
68
+
69
+ function observation_of(move: MainMove): ObservationEntry {
70
+ return {
71
+ slug: OBSERVATION_SLUG,
72
+ depth: OBSERVATION_DEPTH,
73
+ where: move.files.join(', '),
74
+ what: `followup put the main merge before the rerun; the failed test moved on main at ${move.commit.slice(0, SHORT_SHA_LENGTH)}`,
75
+ }
76
+ }
77
+
78
+ // A fetch or read that fails is reported and keeps the rerun: the merge is the shortcut, the rerun the
79
+ // recovery that stood before it.
80
+ async function read_or_rerun(test_files: ReadonlyArray<string>): Promise<MainMove | undefined> {
81
+ try {
82
+ return await read_main_move(test_files)
83
+ } catch (error) {
84
+ console.info(`⚠️ Could not compare the failed tests with main, rerunning: ${String(error)}`)
85
+
86
+ return undefined
87
+ }
88
+ }
89
+
90
+ // **Whether the rerun is skipped for a merge of main**, with the reason posted on the issue.
91
+ async function should_merge_first(
92
+ test_files: ReadonlyArray<string>,
93
+ issue: number | undefined,
94
+ ): Promise<boolean> {
95
+ const move = await read_or_rerun(test_files)
96
+
97
+ if (move === undefined) return false
98
+
99
+ console.info(
100
+ `🔀 Not rerunning: main changed the failed tests since the branch point (${move.files.join(', ')}); merge main first.`,
101
+ )
102
+ await followup_failed_tests.record_entry(observation_of(move), issue)
103
+
104
+ return true
105
+ }
106
+
107
+ const followup_main_move = {
108
+ read_main_move,
109
+ should_merge_first,
110
+ }
111
+
112
+ export type { MainMove }
113
+ export { followup_main_move, OBSERVATION_SLUG }
@@ -7,6 +7,7 @@ import { run_progress_clock } from '#scripts/run/progress/run-progress-clock'
7
7
  import { parse_completed_issue_number } from './followup-issue-number'
8
8
  import { git_followup_cleanup, type CleanupStep } from './git-followup-cleanup'
9
9
  import { git_followup_pending } from './git-followup-pending'
10
+ import { git_followup_stages } from './git-followup-stages'
10
11
 
11
12
  // **The count of unreleased merges, not the project version**. The local `package.json` version
12
13
  // reads as "the version this run just shipped", but children do not bump, so that number names the
@@ -17,38 +18,69 @@ import { git_followup_pending } from './git-followup-pending'
17
18
  // Printed after the merge, and the count is read from a freshly fetched default branch — so this
18
19
  // run's own merge is already in it and nothing here says otherwise, unlike the Telegram sent one step
19
20
  // earlier from a tree the merge had not reached.
20
- async function print_pending_release(): Promise<void> {
21
+ async function read_pending_release(): Promise<ReadonlyArray<string>> {
21
22
  const line = await git_followup_pending.pending_release_line({ is_merge_pending: false })
22
23
 
23
- if (line !== undefined) console.info(line)
24
+ return line === undefined ? [] : [line]
25
+ }
26
+
27
+ async function print_pending_release(): Promise<void> {
28
+ const lines = await read_pending_release()
29
+
30
+ for (const line of lines) console.info(line)
24
31
  }
25
32
 
26
33
  // #821: surface what to run next right where the completion is read. Printed before the project
27
34
  // version line, which stays the final line of the console output by contract.
28
- async function print_next_issues(completed_issue_number: string | undefined): Promise<void> {
29
- const lines = await git_next_issues.fetch_next_issue_lines(
35
+ //
36
+ // Merged runs only, like the epic auto-close: on `--no-merge` the linked issue is still open
37
+ // and still the current task, so a "next" list would hide the one issue that matters.
38
+ async function read_next_issues(
39
+ completed_issue_number: string | undefined,
40
+ should_merge: boolean,
41
+ ): Promise<ReadonlyArray<string>> {
42
+ if (!should_merge) return []
43
+
44
+ return await git_next_issues.fetch_next_issue_lines(
30
45
  parse_completed_issue_number(completed_issue_number),
31
46
  )
47
+ }
48
+
49
+ async function print_next_issues(completed_issue_number: string | undefined): Promise<void> {
50
+ const lines = await read_next_issues(completed_issue_number, true)
51
+
32
52
  for (const line of lines) console.info(line)
33
53
  }
34
54
 
35
- // The tail printed once the workflow itself has finished. `print_pending_release` stays last by
36
- // contract, so anything added here goes above it.
55
+ // The tail printed once the workflow itself has finished. `print_pending_release`'s line stays last
56
+ // by contract, so anything added here goes above it.
57
+ //
58
+ // **The two reads need nothing from one another, so they go out together** (#5131), and the time
59
+ // they take is printed as a `completion` stage row: the stage block is already out by now, and an
60
+ // untimed tail is the fixed cost `josh ship --log` could not see. The row goes above the completion
61
+ // lines, because the pending-release line is the one that has to stay last.
37
62
  async function print_completion(
38
63
  issue_number: string | undefined,
39
64
  should_merge: boolean,
40
65
  ): Promise<void> {
66
+ const started_ms = performance.now()
67
+ const [next_lines, release_lines] = await Promise.all([
68
+ read_next_issues(issue_number, should_merge),
69
+ read_pending_release(),
70
+ ])
71
+ const duration_ms = performance.now() - started_ms
72
+
73
+ console.info(
74
+ git_followup_stages.format_stage({ name: git_followup_stages.STAGE.completion, duration_ms }),
75
+ )
41
76
  console.info('')
42
77
  console.info('✅ PR followup completed.')
43
- // Merged runs only, like the epic auto-close: on `--no-merge` the linked issue is still open
44
- // and still the current task, so a "next" list would hide the one issue that matters.
45
- if (should_merge) await print_next_issues(issue_number)
46
- await print_pending_release()
78
+ for (const line of [...next_lines, ...release_lines]) console.info(line)
47
79
  }
48
80
 
49
81
  // A **merged** run ends here, and the round-1 review snapshot's lifetime is one run.
50
82
  // `--no-merge` is not the end of one — the pull request is still open and
51
- // the issue is still the current task, the same line `print_next_issues` and the epic auto-close
83
+ // the issue is still the current task, the same line `read_next_issues` and the epic auto-close
52
84
  // already draw — and clearing there would be the unsafe direction: the next round-1 brief would find
53
85
  // no record and write a fresh one against the already-fixed tree, which is the arm-A skip over
54
86
  // unreviewed fix code the record exists to prevent.
@@ -14,8 +14,8 @@ import { version_targets } from '#scripts/version/version-targets'
14
14
  // command's own modules rather than re-derived here, and it doubles as the visible signal that a
15
15
  // release is owed — a count that keeps climbing is a release nobody has run.
16
16
 
17
- // **The Telegram is sent before the merge**, deliberately: `git-pr-followup.ts` cuts its wrap-up
18
- // there because that is the last point at which the run can still fail safely. So the count taken
17
+ // **The Telegram's body is read before the merge**, deliberately, though the send goes out beside it
18
+ // (#5080): `git-pr-followup.ts` reads this line before it issues the merge. So the count taken
19
19
  // there cannot include this run's own merge, and a bare number would be understated by exactly one.
20
20
  // Saying so is the honest form of the same measurement. The console line printed after the merge
21
21
  // passes `false` and carries no note, because by then the merge is on the remote and the fetch below
@@ -61,7 +61,7 @@ async function read_tip(options: PendingReadOptions): Promise<string> {
61
61
  // remove.
62
62
  // The manifest read is **inside** the `try` with the rest. `readFileSync` can throw after
63
63
  // `existsSync` passed — EACCES, EISDIR, a racing write — and this function is called from
64
- // `notify_completion`, which runs *before* `pr_merge`: an escaping rejection there would abort the
64
+ // `completion_sender`, which runs *before* `pr_merge`: an escaping rejection there would abort the
65
65
  // run and lose a merge over a cosmetic line.
66
66
  async function read_pending(options: PendingReadOptions): Promise<number | undefined> {
67
67
  try {
@@ -1,6 +1,7 @@
1
1
  import { PrConflictError } from '#scripts/gh/git-pr-checks-eval'
2
- import { lane_ledger } from '#scripts/lane/lane-ledger'
2
+ import { lane_ledger_write } from '#scripts/lane/lane-ledger-write'
3
3
  import { time_format } from '#scripts/time-runtime/time-format'
4
+ import { followup_ci_path, type CiPath } from './followup-ci-path'
4
5
  import { followup_coderabbit_wait, type CodeRabbitWait } from './followup-coderabbit-wait'
5
6
 
6
7
  // Where `pnpm josh followup` spends its own wall clock.
@@ -11,8 +12,9 @@ import { followup_coderabbit_wait, type CodeRabbitWait } from './followup-codera
11
12
  // epic auto-close. Untimed, every proposal to shorten it is a guess, and a guess made under time
12
13
  // pressure falls on whichever stretch is easiest to cut rather than on the one that is long.
13
14
  //
14
- // **Those nine are seven printed rows**: the four reads in front of the wait go out together and so
15
- // do the two steps after the merge, and a lap measures an interval rather than a call. `STAGE` below is the list; the two names carrying `and` are the batches.
15
+ // **Those nine are six printed rows**: the four reads in front of the wait go out together, so do the
16
+ // Telegram and the merge, and so do the two steps after the merge, and a lap measures an interval
17
+ // rather than a call. `STAGE` below is the list; the three names carrying `and` are the batches.
16
18
  //
17
19
  // **Laps, not a wrapper per stage.** The alternative was a `measure(name, () => …)` closure around
18
20
  // each call, which reads well and rewrites every call site in the file it instruments — nine
@@ -52,21 +54,29 @@ const NO_DURATION = 0
52
54
  // The stages, named once. They are the units a proposal to shorten `followup` would be written
53
55
  // against, so a rename has to move the printer and whatever reads it together.
54
56
  //
55
- // **Two names say `and` because two stages became one**. Requests that need
57
+ // **Three names say `and` because each is two stages become one**. Requests that need
56
58
  // nothing from one another are now issued together, and a lap records an interval rather than a
57
59
  // call — so a batch is one interval, and what it holds has to be readable from its name or the
58
60
  // shortening becomes invisible to the very measurement that found it. `closes-and-context` is the
59
61
  // former `closes-check` and `context`; `completion-and-epic-close` the former `completion-comment`
60
- // and `epic-close`. **`checks-wait` is untouched, and deliberately so**: it is the merge gate, and
61
- // this change only ever moved time that was not a wait.
62
+ // and `epic-close`; `telegram-and-merge` the former `telegram` and `merge` (#5080). **`checks-wait` is
63
+ // untouched, and deliberately so**: it is the merge gate, and this change only ever moved time that was
64
+ // not a wait.
62
65
  const STAGE = {
63
66
  closes_and_context: 'closes-and-context',
64
67
  checks_wait: 'checks-wait',
68
+ // Only on a run that retriggered a rate-limited CodeRabbit: the window and the review after it
69
+ // (joshuafolkken/kit#5289), kept out of `checks-wait` so the `ci-wait` row is the checks alone.
70
+ coderabbit_retrigger: 'coderabbit-retrigger',
65
71
  coderabbit_comments: 'coderabbit-comments',
66
72
  ai_review_comments: 'ai-review-comments',
73
+ // The interval of a run that merged nothing, where the send has nothing to go beside.
67
74
  telegram: 'telegram',
68
- merge: 'merge',
75
+ telegram_and_merge: 'telegram-and-merge',
69
76
  completion_and_epic_close: 'completion-and-epic-close',
77
+ // The completion tail `git-followup-finish.ts` prints after this block (#5131): the next-issue list
78
+ // and the unreleased-merge count. Printed as its own row there, since the block is already out.
79
+ completion: 'completion',
70
80
  // The lap that was still running when a stage threw. `followup` exits non-zero on an AI-review
71
81
  // blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
72
82
  // them would leave the measurement blind to exactly the invocations worth measuring.
@@ -93,15 +103,31 @@ interface FollowupStage {
93
103
  // negative lap.
94
104
  //
95
105
  // `coderabbit` rides on the log because every check wait of the run — the merge gate's and the one the
96
- // merge goes back to (#4036) — adds to the same CodeRabbit time.
106
+ // merge goes back to (#4036) — adds to the same CodeRabbit time. `ci_path` is the first wait's
107
+ // per-check timing, which the `ci-wait` row carries (`followup-ci-path.ts`), with `issue` once the run
108
+ // knows it, so `lane:breakdown` finds the lane's row.
97
109
  interface StageLog {
98
110
  stages: Array<FollowupStage>
99
111
  last_ms: number
100
112
  coderabbit: CodeRabbitWait
113
+ ci_path: CiPath
114
+ issue?: number
101
115
  }
102
116
 
103
117
  function new_log(): StageLog {
104
- return { stages: [], last_ms: performance.now(), coderabbit: followup_coderabbit_wait.new_wait() }
118
+ return {
119
+ stages: [],
120
+ last_ms: performance.now(),
121
+ coderabbit: followup_coderabbit_wait.new_wait(),
122
+ ci_path: followup_ci_path.new_path(),
123
+ }
124
+ }
125
+
126
+ // The issue the `ci-wait` row is written under; a number that does not parse leaves the row without one.
127
+ function hold_issue(log: StageLog, issue_number: string | undefined): void {
128
+ const issue = Number(issue_number)
129
+
130
+ if (Number.isSafeInteger(issue) && issue > 0) log.issue = issue
105
131
  }
106
132
 
107
133
  function lap(log: StageLog, name: string): void {
@@ -151,9 +177,11 @@ async function record_ci_wait(log: StageLog): Promise<void> {
151
177
 
152
178
  if (wait === undefined) return
153
179
 
154
- await lane_ledger.record_stage({
155
- stage: lane_ledger.CI_WAIT_STAGE,
180
+ await lane_ledger_write.record_stage({
181
+ stage: lane_ledger_write.CI_WAIT_STAGE,
156
182
  elapsed_ms: wait.duration_ms,
183
+ ...(log.issue !== undefined && { issue: log.issue }),
184
+ ...followup_ci_path.record_of(log.ci_path),
157
185
  })
158
186
  }
159
187
 
@@ -167,8 +195,10 @@ const git_followup_stages = {
167
195
  STAGE_LINE_PREFIX,
168
196
  STAGE_TOTAL_PREFIX,
169
197
  new_log,
198
+ hold_issue,
170
199
  lap,
171
200
  total_ms,
201
+ format_stage,
172
202
  format_stages,
173
203
  print_stages,
174
204
  record_waits,
@@ -6,10 +6,15 @@ import {
6
6
  WATCH_CONFIRMED_STABLE_READS,
7
7
  type SnapshotObserver,
8
8
  } from '#scripts/gh/git-pr-checks'
9
- import { is_coderabbit_check } from '#scripts/gh/git-pr-checks-eval'
9
+ import {
10
+ FAILURE_MESSAGE_PREFIX,
11
+ is_coderabbit_check,
12
+ PrConflictError,
13
+ } from '#scripts/gh/git-pr-checks-eval'
10
14
  import { CHECK_STATUS_PASS, type PrStateSnapshot } from '#scripts/gh/git-pr-checks-parse'
11
15
  import { issue_watch_gate } from '#scripts/issue/issue-watch-gate'
12
16
  import { json_value } from '#scripts/lib/json-value'
17
+ import { followup_job_rerun } from './followup-job-rerun'
13
18
 
14
19
  // The check wait and the notes read off its snapshot — split out of `git-pr-followup.ts` when it
15
20
  // reached its line limit. `git-pr-followup` re-exports each name it always
@@ -71,12 +76,15 @@ async function handle_watch_failure(branch_name: string, error: unknown): Promis
71
76
  console.info(`⚠️ ${WATCH_FAILED_NOTE}: ${git_gh_helpers.get_error_message_with_stderr(error)}`)
72
77
  }
73
78
 
74
- // **Returns whether the watch confirmed completion**: `true` only when
75
- // `pr_checks_watch` saw every check finish, `false` when it timed out with checks still pending or
76
- // fell through to polling on a swallowed failure. `run_checks` reads it to decide how many stable poll
77
- // reads the wait still needs. A timed-out watch (`timed_out: true`) never spanned the pending→settled
78
- // window, so it must keep the full stable-read window rather than claim the confirmation. A rethrown
79
- // failure — the empty-rollup case — never reaches a caller, so it needs no answer here.
79
+ // **Returns whether the watch observed the checks**: `true` when `pr_checks_watch` returned — every
80
+ // check finished, or the budget ran out with one still pending — and `false` when it fell through to
81
+ // polling on a swallowed failure. `run_checks` reads it to decide how many stable poll reads the wait
82
+ // still needs. **A timed-out watch counts too** (#5080): it read the checks for two minutes without
83
+ // two settled reads in a row, so the checks were registered and not yet settled while it watched, and
84
+ // the poll's first settled read closes that pending→settled window — the window the second stable read
85
+ // exists for. Holding it to two cost ten seconds on every lane whose CI outlasts the two-minute
86
+ // budget. A rethrown failure — the empty-rollup case — never reaches a caller, so it needs no answer
87
+ // here.
80
88
  async function watch_before_polling(
81
89
  branch_name: string,
82
90
  observe: SnapshotObserver | undefined,
@@ -85,9 +93,9 @@ async function watch_before_polling(
85
93
  console.info('📊 Watching PR checks...')
86
94
 
87
95
  try {
88
- const result = await git_gh_command.pr_checks_watch(branch_name, observe)
96
+ await git_gh_command.pr_checks_watch(branch_name, observe)
89
97
 
90
- return !result.timed_out
98
+ return true
91
99
  } catch (error) {
92
100
  await handle_watch_failure(branch_name, error)
93
101
 
@@ -95,21 +103,23 @@ async function watch_before_polling(
95
103
  }
96
104
  }
97
105
 
98
- // **A confirmed watch lowers the poll's stable-read requirement to one**. The
99
- // watch is the first confirmation that every check settled, so the poll that follows need only agree
100
- // once rather than twice — which removes the extra interval `followup` spent re-proving a settled run.
106
+ // **A returned watch lowers the poll's stable-read requirement to one**. The
107
+ // watch saw every check settle or saw them pending, so the poll that follows need only agree once
108
+ // rather than twice — which removes the extra interval `followup` spent re-proving a settled run.
101
109
  // A skipped or fallen-through watch keeps `DEFAULT_STABLE_READS`, and a check that turned red is still
102
110
  // caught: the poll evaluates the full merge gate and throws on failure before any stable read counts.
103
111
  // `observe` is shown each poll's snapshot, the watch's included — the run's `pr-checks` line
104
112
  // (joshuafolkken/kit#3770).
105
- async function run_checks(input: {
113
+ interface RunChecksInput {
106
114
  branch_name: string
107
115
  is_skip_watch: boolean
108
116
  observe?: SnapshotObserver
109
- }): Promise<PrStateSnapshot> {
110
- const is_watch_confirmed =
117
+ }
118
+
119
+ async function wait_for_checks(input: RunChecksInput): Promise<PrStateSnapshot> {
120
+ const is_watch_returned =
111
121
  !input.is_skip_watch && (await watch_before_polling(input.branch_name, input.observe))
112
- const stable_reads = is_watch_confirmed ? WATCH_CONFIRMED_STABLE_READS : DEFAULT_STABLE_READS
122
+ const stable_reads = is_watch_returned ? WATCH_CONFIRMED_STABLE_READS : DEFAULT_STABLE_READS
113
123
 
114
124
  return await git_pr_checks.wait_for_pr_success(
115
125
  input.branch_name,
@@ -119,6 +129,35 @@ async function run_checks(input: {
119
129
  )
120
130
  }
121
131
 
132
+ // A merge conflict is not a check, so no rerun can clear it.
133
+ function is_checks_failure(error: unknown): boolean {
134
+ if (error instanceof PrConflictError) return false
135
+
136
+ return error instanceof Error && error.message.startsWith(FAILURE_MESSAGE_PREFIX)
137
+ }
138
+
139
+ // **A job the runner stopped after every step passed, or one red only on tests outside the change, is
140
+ // rerun once and the wait judged again** (`followup-job-rerun.ts`). The second wait has no rerun of its own, so a job that stops the same way
141
+ // twice — or any other failure — ends the run as before.
142
+ async function rejudge_after_rerun(
143
+ input: RunChecksInput,
144
+ error: unknown,
145
+ ): Promise<PrStateSnapshot> {
146
+ if (!is_checks_failure(error)) throw error
147
+ const rerun = await followup_job_rerun.rerun_failed_jobs(input.branch_name)
148
+ if (rerun.length === 0) throw error
149
+
150
+ return await wait_for_checks(input)
151
+ }
152
+
153
+ async function run_checks(input: RunChecksInput): Promise<PrStateSnapshot> {
154
+ try {
155
+ return await wait_for_checks(input)
156
+ } catch (error) {
157
+ return await rejudge_after_rerun(input, error)
158
+ }
159
+ }
160
+
122
161
  // Temporary: record every CodeRabbit check that was not passing when the merge gate
123
162
  // opened, so a merge shipped without CodeRabbit review stays auditable.
124
163
  function read_coderabbit_skip_notes(snapshot: PrStateSnapshot): Array<string> {
@@ -4,6 +4,7 @@ import type { PrStateSnapshot } from '#scripts/gh/git-pr-checks'
4
4
  import { git_pr_merge_checked, type WaitForGreen } from '#scripts/gh/git-pr-merge-checked'
5
5
  import { issue_body_or_comment } from '#scripts/issue/issue-body-or-comment'
6
6
  import { issue_watch_gate } from '#scripts/issue/issue-watch-gate'
7
+ import { settled_together } from '#scripts/lib/settled-together'
7
8
  import { git_notify, type GitNotifyConfig } from '#scripts/notify/git-notify'
8
9
  import { git_followup_cleanup } from './git-followup-cleanup'
9
10
  import { git_followup_issue_close } from './git-followup-issue-close'
@@ -47,6 +48,8 @@ interface WrapupInput {
47
48
  // that head moved before the merge (`git-pr-merge-checked.ts`, #4036).
48
49
  checked?: PrStateSnapshot | undefined
49
50
  wait_for_green: WaitForGreen
51
+ // The completion Telegram, its body already read, sent beside the merge.
52
+ send_completion: () => Promise<void>
50
53
  }
51
54
 
52
55
  function build_notify_body(input: {
@@ -232,13 +235,29 @@ async function run_tail_steps(input: WrapupInput): Promise<void> {
232
235
  // The last look at the issue before the merge: the CI poll checked it on every iteration, but a
233
236
  // person's update can land between that poll and this step, and only the seconds after this read are
234
237
  // left unwatched.
235
- async function run_wrapup(input: WrapupInput, log: StageLog): Promise<void> {
236
- if (input.should_merge && input.is_merged !== true) {
237
- await issue_watch_gate.assert_read_here()
238
- await git_pr_merge_checked.merge_checked(input)
239
- lap(log, STAGE.merge)
238
+ async function merge_step(input: WrapupInput): Promise<void> {
239
+ await issue_watch_gate.assert_read_here()
240
+ await git_pr_merge_checked.merge_checked(input)
241
+ }
242
+
243
+ // **The completion Telegram goes out beside the merge** (#5080): neither reads what the other writes,
244
+ // and in sequence the send was about four seconds in front of every merge. The send is tolerant, so
245
+ // its failure still never stops the merge; both settle before a merge failure is thrown, so a refused
246
+ // merge does not cut a send in flight. Answers the stage the interval was.
247
+ async function send_beside_merge(input: WrapupInput): Promise<string> {
248
+ if (!input.should_merge || input.is_merged === true) {
249
+ await input.send_completion()
250
+
251
+ return STAGE.telegram
240
252
  }
241
253
 
254
+ await settled_together(input.send_completion(), merge_step(input))
255
+
256
+ return STAGE.telegram_and_merge
257
+ }
258
+
259
+ async function run_wrapup(input: WrapupInput, log: StageLog): Promise<void> {
260
+ lap(log, await send_beside_merge(input))
242
261
  await run_tail_steps(input)
243
262
 
244
263
  lap(log, STAGE.completion_and_epic_close)