@joshuafolkken/kit 1.1240.0 → 1.1373.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 (934) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +52 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +19 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +26 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +17 -28
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.vscode/tasks.json +14 -0
  42. package/CLAUDE.md +10 -61
  43. package/README.md +23 -66
  44. package/SECURITY.md +1 -1
  45. package/dist/CLAUDE.md +10 -61
  46. package/dist/commands/document-section-cli.js +43 -11
  47. package/dist/config-merge/index.js +11 -2
  48. package/dist/hooks/audit-provision.js +2 -2
  49. package/dist/hooks/batch-guard.js +7 -7
  50. package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-7UBFU3CL.js} +18 -20
  51. package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-7WKYHEGU.js} +8 -44
  52. package/dist/hooks/{chunk-4TZVB44A.js → chunk-AKGCP4LX.js} +285 -363
  53. package/dist/hooks/{chunk-QVSWU24O.js → chunk-BZMPVFDY.js} +7 -5
  54. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  55. package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
  56. package/dist/hooks/{chunk-XZYKEM6J.js → chunk-JCRDBQXB.js} +13 -11
  57. package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-JGW24KKM.js} +4 -4
  58. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  59. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  60. package/dist/hooks/{chunk-WK2XSHSI.js → chunk-SLSFIWTX.js} +550 -875
  61. package/dist/hooks/chunk-UTHMB4O2.js +1590 -0
  62. package/dist/hooks/{chunk-KRBERBBI.js → chunk-V4TKZHER.js} +4 -4
  63. package/dist/hooks/chunk-YLBBSSTF.js +3705 -0
  64. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  65. package/dist/hooks/codex-hook-adapter.js +26 -21
  66. package/dist/hooks/duplicate-read-guard.js +8 -8
  67. package/dist/hooks/format-edited.js +4 -4
  68. package/dist/hooks/inputs.json +195 -181
  69. package/dist/hooks/investigation-guard.js +8 -8
  70. package/dist/hooks/pretool-guard.js +15 -15
  71. package/dist/hooks/session-lang.js +406 -8
  72. package/dist/hooks/stop-guard.js +122 -187
  73. package/dist/josh.js +282 -95
  74. package/dist/version/index.js +15 -13
  75. package/eslint/base.js +43 -5
  76. package/eslint/rules/english-only-prose.js +3 -3
  77. package/eslint/rules/import.js +12 -0
  78. package/eslint/rules/namespace-object-export.js +2 -2
  79. package/package.json +17 -11
  80. package/pnpm-workspace.yaml +2 -4
  81. package/prompts/coding-standards.md +14 -48
  82. package/prompts/collaboration-workflow/file-edits.md +1 -1
  83. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  84. package/prompts/collaboration-workflow/issue-template.md +3 -10
  85. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  86. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  87. package/prompts/collaboration-workflow/overview.md +1 -1
  88. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  89. package/prompts/collaboration-workflow/principles.md +21 -3
  90. package/prompts/collaboration-workflow/report-format.md +16 -29
  91. package/prompts/collaboration-workflow/residency.md +1 -1
  92. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  93. package/prompts/collaboration-workflow/shell-body.md +3 -23
  94. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  95. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +3 -22
  98. package/prompts/review.md +15 -38
  99. package/prompts/testing-guide.md +2 -4
  100. package/scripts/adopt/adopt-logic.ts +5 -5
  101. package/scripts/adopt/adopt-toolkits.ts +4 -5
  102. package/scripts/adopt/adopt.ts +2 -3
  103. package/scripts/agent/agent-argv.ts +7 -7
  104. package/scripts/agent/agent-diagnostics.ts +2 -2
  105. package/scripts/agent/agent-exit-record.ts +1 -1
  106. package/scripts/agent/agent-headless.ts +1 -1
  107. package/scripts/agent/agent-launch-environment.ts +6 -1
  108. package/scripts/agent/agent-role-profile.ts +49 -22
  109. package/scripts/agent/agent-session-role.ts +32 -0
  110. package/scripts/agent/api-outage.ts +1 -1
  111. package/scripts/agent/claude-agent-argv.ts +4 -4
  112. package/scripts/agent/claude-result-event.ts +4 -4
  113. package/scripts/agent/codex-hooks.ts +2 -2
  114. package/scripts/agent/interactive-ask.ts +3 -6
  115. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  116. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  117. package/scripts/backlog/backlog-arrival.ts +54 -17
  118. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  119. package/scripts/backlog/backlog-budget.ts +17 -24
  120. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  121. package/scripts/backlog/backlog-drive-args.ts +5 -4
  122. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  123. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  124. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  125. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  126. package/scripts/backlog/backlog-drive-named.ts +39 -9
  127. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  128. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  129. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  130. package/scripts/backlog/backlog-drive.ts +43 -28
  131. package/scripts/backlog/backlog-idle.ts +88 -0
  132. package/scripts/backlog/backlog-named.ts +11 -15
  133. package/scripts/backlog/backlog-next.ts +26 -30
  134. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  135. package/scripts/backlog/backlog-offer.ts +7 -7
  136. package/scripts/backlog/backlog-overlap.ts +178 -0
  137. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  138. package/scripts/backlog/backlog-plan-read.ts +111 -0
  139. package/scripts/backlog/backlog-plan.ts +11 -10
  140. package/scripts/backlog/backlog-pool.ts +13 -14
  141. package/scripts/backlog/backlog-rank.ts +11 -11
  142. package/scripts/backlog/backlog-ready.ts +15 -10
  143. package/scripts/backlog/backlog-scope.ts +14 -15
  144. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  145. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  146. package/scripts/backlog/backlog-stalled.ts +5 -6
  147. package/scripts/backlog/backlog-waves.ts +4 -4
  148. package/scripts/backlog/backlogrun-args.ts +74 -0
  149. package/scripts/backlog/backlogrun-cli.ts +113 -0
  150. package/scripts/backlog/backlogrun-launch.ts +178 -0
  151. package/scripts/behavior/behavior-assertion.ts +6 -8
  152. package/scripts/behavior/behavior-cli.ts +1 -1
  153. package/scripts/behavior/behavior-rules.ts +3 -3
  154. package/scripts/build/build-claude-md.ts +4 -4
  155. package/scripts/build/build-codex-hooks.ts +2 -2
  156. package/scripts/build/build-commands.ts +1 -1
  157. package/scripts/build/build-hooks.ts +5 -5
  158. package/scripts/build/build.ts +1 -1
  159. package/scripts/build/hook-bundle-stamp.ts +109 -7
  160. package/scripts/build/local-bin.ts +2 -2
  161. package/scripts/cases/cases-cli.ts +1 -1
  162. package/scripts/cases/cases-logic.ts +2 -2
  163. package/scripts/ci/composite-actions.ts +1 -2
  164. package/scripts/ci/pr-classification.ts +2 -2
  165. package/scripts/claude/workflow-destination.ts +1 -1
  166. package/scripts/clone/clone-aggregate.ts +1 -1
  167. package/scripts/clone/clone-fingerprint.ts +1 -1
  168. package/scripts/clone/clone-scan-cli.ts +1 -1
  169. package/scripts/clone/clone-scan.ts +1 -1
  170. package/scripts/config-merge/index.ts +1 -1
  171. package/scripts/config-merge/json-format.ts +1 -3
  172. package/scripts/config-merge/patch-json-array.ts +90 -0
  173. package/scripts/config-merge/patch-json-key.ts +6 -3
  174. package/scripts/config-merge/patch-json-list.ts +1 -1
  175. package/scripts/cost-runtime/codex-usage.ts +1 -1
  176. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  177. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  178. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  179. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  180. package/scripts/cost-runtime/cost-cli.ts +14 -11
  181. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  182. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  183. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  184. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  185. package/scripts/cost-runtime/cost-usage.ts +6 -7
  186. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  187. package/scripts/cost-runtime/own-session.ts +1 -1
  188. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  189. package/scripts/delegation/delegation-cli.ts +4 -4
  190. package/scripts/delegation/delegation-policy.ts +13 -15
  191. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  192. package/scripts/delegation/fanout-cli.ts +1 -1
  193. package/scripts/delegation/fanout.ts +1 -1
  194. package/scripts/delegation/investigation-guard.ts +18 -22
  195. package/scripts/delegation/investigation-reads.ts +48 -238
  196. package/scripts/discovery/repo-discovery.ts +1 -1
  197. package/scripts/discovery/repo-map-logic.ts +1 -2
  198. package/scripts/discovery/repo-origin.ts +3 -3
  199. package/scripts/discovery/repo-party-cli.ts +2 -2
  200. package/scripts/discovery/repo-party.ts +2 -2
  201. package/scripts/doctor/doctor-consumer.ts +1 -1
  202. package/scripts/doctor/doctor-io.ts +6 -7
  203. package/scripts/doctor/doctor-logic.ts +1 -1
  204. package/scripts/doctor/doctor-ports.ts +1 -1
  205. package/scripts/doctor/doctor.ts +8 -9
  206. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  207. package/scripts/document/bash-output-cap.ts +5 -7
  208. package/scripts/document/capped-print-part.ts +1 -1
  209. package/scripts/document/capped-print.ts +1 -1
  210. package/scripts/document/document-byte-budget.ts +33 -64
  211. package/scripts/document/document-byte-check.ts +4 -4
  212. package/scripts/document/document-reachability.ts +7 -8
  213. package/scripts/document/document-read-cli.ts +2 -2
  214. package/scripts/document/document-scan.ts +30 -5
  215. package/scripts/document/document-section-cli.ts +6 -8
  216. package/scripts/document/document-section.ts +8 -12
  217. package/scripts/document/edit-files-cli.ts +3 -4
  218. package/scripts/document/entry-read-budget.ts +8 -70
  219. package/scripts/document/entry-read-set.ts +51 -34
  220. package/scripts/document/lane-child-read-set.ts +9 -9
  221. package/scripts/document/read-files-cli.ts +1 -2
  222. package/scripts/document/read-set-cli.ts +16 -19
  223. package/scripts/document/read-set-cost.ts +4 -4
  224. package/scripts/document/read-set-point-of-use.ts +28 -38
  225. package/scripts/document/read-set-pricing.ts +1 -1
  226. package/scripts/document/read-set-trim.ts +3 -3
  227. package/scripts/document/resident-budget.ts +8 -10
  228. package/scripts/epic/epic-add-body.ts +15 -18
  229. package/scripts/epic/epic-add-plan.ts +26 -28
  230. package/scripts/epic/epic-add.ts +32 -25
  231. package/scripts/epic/epic-audit-checks.ts +27 -37
  232. package/scripts/epic/epic-audit-cli.ts +21 -22
  233. package/scripts/epic/epic-audit-orphans.ts +16 -17
  234. package/scripts/epic/epic-audit-rationale.ts +10 -15
  235. package/scripts/epic/epic-audit-report.ts +2 -5
  236. package/scripts/epic/epic-audit.ts +18 -14
  237. package/scripts/epic/epic-body.ts +10 -10
  238. package/scripts/epic/epic-bundle-cli.ts +36 -34
  239. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  240. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  241. package/scripts/epic/epic-bundle-poll.ts +1 -1
  242. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  243. package/scripts/epic/epic-bundle.ts +19 -20
  244. package/scripts/epic/epic-busy.ts +44 -21
  245. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  246. package/scripts/epic/epic-chains.ts +18 -23
  247. package/scripts/epic/epic-classify.ts +11 -12
  248. package/scripts/epic/epic-cli-argv.ts +5 -6
  249. package/scripts/epic/epic-cli-remove.ts +9 -4
  250. package/scripts/epic/epic-cli.ts +38 -26
  251. package/scripts/epic/epic-close-comment.ts +14 -15
  252. package/scripts/epic/epic-close.ts +25 -29
  253. package/scripts/epic/epic-cross-repo.ts +18 -21
  254. package/scripts/epic/epic-decision.ts +14 -18
  255. package/scripts/epic/epic-fetch.ts +25 -31
  256. package/scripts/epic/epic-graph.ts +15 -17
  257. package/scripts/epic/epic-index.ts +14 -16
  258. package/scripts/epic/epic-issue.ts +9 -11
  259. package/scripts/epic/epic-label-age.ts +74 -0
  260. package/scripts/epic/epic-lane-offer.ts +35 -24
  261. package/scripts/epic/epic-nested.ts +1 -1
  262. package/scripts/epic/epic-next-read.ts +8 -8
  263. package/scripts/epic/epic-next-views.ts +12 -12
  264. package/scripts/epic/epic-next.ts +29 -33
  265. package/scripts/epic/epic-outside-blocker.ts +11 -10
  266. package/scripts/epic/epic-parse.ts +22 -24
  267. package/scripts/epic/epic-promote.ts +3 -2
  268. package/scripts/epic/epic-rank.ts +1 -1
  269. package/scripts/epic/epic-read.ts +10 -8
  270. package/scripts/epic/epic-reconcile.ts +8 -6
  271. package/scripts/epic/epic-reference.ts +5 -4
  272. package/scripts/epic/epic-relation-recheck.ts +10 -11
  273. package/scripts/epic/epic-relations.ts +9 -8
  274. package/scripts/epic/epic-remove-plan.ts +4 -5
  275. package/scripts/epic/epic-remove.ts +7 -5
  276. package/scripts/epic/epic-report.ts +18 -20
  277. package/scripts/epic/epic-run.ts +6 -5
  278. package/scripts/epic/epic-sections.ts +2 -2
  279. package/scripts/epic/epic-shape.ts +3 -3
  280. package/scripts/epic/epic-solo-stale.ts +3 -2
  281. package/scripts/epic/epic-solo.ts +8 -8
  282. package/scripts/epic/epic-triage.ts +5 -4
  283. package/scripts/epic/epic-validate.ts +8 -7
  284. package/scripts/epic/epic.ts +5 -5
  285. package/scripts/exports/unused-members-cli.ts +1 -1
  286. package/scripts/followup/followup-issue-number.ts +1 -2
  287. package/scripts/followup/git-followup-cleanup.ts +6 -7
  288. package/scripts/followup/git-followup-finish.ts +11 -13
  289. package/scripts/followup/git-followup-flush.ts +11 -7
  290. package/scripts/followup/git-followup-issue-close.ts +16 -13
  291. package/scripts/followup/git-followup-label.ts +9 -6
  292. package/scripts/followup/git-followup-merged.ts +1 -1
  293. package/scripts/followup/git-followup-pending.ts +7 -9
  294. package/scripts/followup/git-followup-stages.ts +28 -17
  295. package/scripts/followup/git-followup-workflow.ts +19 -21
  296. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  297. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  298. package/scripts/followup/git-pr-followup.ts +18 -17
  299. package/scripts/gate/core-admission.ts +2 -2
  300. package/scripts/gate/core-budget.ts +15 -26
  301. package/scripts/gate/gate-ledger.ts +114 -0
  302. package/scripts/gate/gate-log.ts +7 -9
  303. package/scripts/gate/gate-plan.ts +70 -35
  304. package/scripts/gate/gate-report.ts +14 -15
  305. package/scripts/gate/gate-skip.ts +11 -13
  306. package/scripts/gate/gate-steps.ts +5 -1
  307. package/scripts/gate/gate-tree.ts +3 -4
  308. package/scripts/gate/hook-gate-reuse.ts +9 -9
  309. package/scripts/gate/machine-capacity.ts +168 -30
  310. package/scripts/gate/pre-commit-type-check.ts +4 -4
  311. package/scripts/gate/project-checks.ts +12 -4
  312. package/scripts/gate/scoped-green.ts +11 -18
  313. package/scripts/gate/type-check-command.ts +2 -2
  314. package/scripts/gate/type-check-step.ts +4 -4
  315. package/scripts/gate/verification-gate.ts +53 -51
  316. package/scripts/gh/gh-spawn.ts +2 -2
  317. package/scripts/gh/git-ai-review-scan.ts +3 -2
  318. package/scripts/gh/git-gh-api-path.ts +10 -11
  319. package/scripts/gh/git-gh-exec.ts +43 -48
  320. package/scripts/gh/git-gh-failure.ts +6 -9
  321. package/scripts/gh/git-gh-helpers.ts +1 -1
  322. package/scripts/gh/git-gh-issue-list.ts +15 -19
  323. package/scripts/gh/git-gh-issue-read.ts +43 -60
  324. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  325. package/scripts/gh/git-gh-issue-write.ts +52 -40
  326. package/scripts/gh/git-gh-issue.ts +23 -24
  327. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  328. package/scripts/gh/git-gh-pr-read.ts +46 -50
  329. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  330. package/scripts/gh/git-gh-pr-review.ts +2 -2
  331. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  332. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  333. package/scripts/gh/git-gh-pr.ts +16 -16
  334. package/scripts/gh/git-gh-reachability.ts +11 -12
  335. package/scripts/gh/git-gh-repo.ts +2 -3
  336. package/scripts/gh/git-gh-rest-state.ts +1 -1
  337. package/scripts/gh/git-pr-ai-review.ts +6 -5
  338. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  339. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  340. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  341. package/scripts/gh/git-pr-checks.ts +20 -23
  342. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  343. package/scripts/gh/git-pr-confirmation.ts +5 -5
  344. package/scripts/gh/git-pr-managed-config.ts +7 -9
  345. package/scripts/gh/git-pr-messages.ts +1 -1
  346. package/scripts/gh/git-pr.ts +15 -16
  347. package/scripts/gh/github-issue-url.ts +8 -9
  348. package/scripts/git/base-tree.ts +66 -0
  349. package/scripts/git/change-base.ts +42 -2
  350. package/scripts/git/changed-file-scope.ts +5 -5
  351. package/scripts/git/changed-paths.ts +1 -2
  352. package/scripts/git/constants.ts +2 -2
  353. package/scripts/git/git-branch.ts +1 -1
  354. package/scripts/git/git-closes-keyword.ts +3 -3
  355. package/scripts/git/git-command.ts +53 -41
  356. package/scripts/git/git-common-directory.ts +3 -3
  357. package/scripts/git/git-diff-reads.ts +14 -15
  358. package/scripts/git/git-error.ts +1 -1
  359. package/scripts/git/git-execa-error.ts +1 -2
  360. package/scripts/git/git-issue.ts +10 -8
  361. package/scripts/git/git-location-environment.ts +3 -4
  362. package/scripts/git/git-ls-remote.ts +6 -8
  363. package/scripts/git/git-pre-push-hook.ts +11 -10
  364. package/scripts/git/git-preflight.ts +5 -5
  365. package/scripts/git/git-push-transport.ts +2 -2
  366. package/scripts/git/git-remote-branch.ts +1 -2
  367. package/scripts/git/git-schemas.ts +16 -23
  368. package/scripts/git/git-spawn-sync.ts +1 -1
  369. package/scripts/git/git-spawn.ts +37 -14
  370. package/scripts/git/git-ssh-keepalive.ts +12 -5
  371. package/scripts/git/git-staging.ts +7 -8
  372. package/scripts/git/git-workflow.ts +1 -1
  373. package/scripts/git/git-worktree.ts +35 -27
  374. package/scripts/git/gone-branch.ts +2 -2
  375. package/scripts/git/listing-cutoff.ts +1 -2
  376. package/scripts/git/lockfile-sync.ts +65 -0
  377. package/scripts/git/main-merge-guard.ts +1 -2
  378. package/scripts/git/main-merge.ts +7 -7
  379. package/scripts/git/main-sync.ts +23 -8
  380. package/scripts/git/parse-json-array.ts +18 -23
  381. package/scripts/git/repository-lock.ts +34 -2
  382. package/scripts/git/stash/git-stash.ts +4 -5
  383. package/scripts/git/stash/stash-orphans.ts +5 -3
  384. package/scripts/git/stash/stash-pop-args.ts +1 -1
  385. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  386. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  387. package/scripts/hooks/batch-guard.ts +11 -13
  388. package/scripts/hooks/check-commit-message.ts +12 -9
  389. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  390. package/scripts/hooks/edited-cspell.ts +3 -4
  391. package/scripts/hooks/format-edited-cli.ts +1 -1
  392. package/scripts/hooks/format-edited-file.ts +11 -17
  393. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  394. package/scripts/hooks/pre-push-unit.ts +10 -14
  395. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  396. package/scripts/hooks/pretool-guard.ts +93 -18
  397. package/scripts/hooks/reserved-run.ts +2 -2
  398. package/scripts/hooks/step-zero-notice.ts +1 -1
  399. package/scripts/hooks/stop-guard.ts +21 -10
  400. package/scripts/init/basic-path-migration.ts +2 -2
  401. package/scripts/init/claude-kit-only-settings.ts +2 -2
  402. package/scripts/init/claude-plugin-config.ts +2 -2
  403. package/scripts/init/distributed-paths.ts +4 -4
  404. package/scripts/init/hook-command-rewrite.ts +3 -3
  405. package/scripts/init/hook-launch.ts +5 -5
  406. package/scripts/init/init-actions.ts +13 -0
  407. package/scripts/init/init-ai-copy.ts +11 -11
  408. package/scripts/init/init-bootstrap.ts +3 -3
  409. package/scripts/init/init-copy-content.ts +4 -4
  410. package/scripts/init/init-logic-json-merge.ts +7 -9
  411. package/scripts/init/init-logic-migrate.ts +1 -1
  412. package/scripts/init/init-logic-templates.ts +1 -1
  413. package/scripts/init/init-logic-workspace.ts +4 -4
  414. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  415. package/scripts/init/init-logic.ts +19 -22
  416. package/scripts/init/init.ts +7 -7
  417. package/scripts/init/kit-base-preset.ts +1 -1
  418. package/scripts/init/kit-setup-state.ts +1 -1
  419. package/scripts/init/kit-written-paths.ts +1 -2
  420. package/scripts/init/package-manager-pin.ts +1 -1
  421. package/scripts/init/project-profile-cli.ts +1 -1
  422. package/scripts/init/project-profile.ts +3 -3
  423. package/scripts/init/session-language-environment.ts +1 -1
  424. package/scripts/init/start-exec.ts +3 -4
  425. package/scripts/init/start-plan.ts +2 -2
  426. package/scripts/init/start-setup-pr.ts +3 -2
  427. package/scripts/init/start-steps.ts +2 -2
  428. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  429. package/scripts/init/vscode-tasks.ts +62 -0
  430. package/scripts/issue/baseline-measure.ts +2 -2
  431. package/scripts/issue/behavior-change-lint.ts +2 -2
  432. package/scripts/issue/defect-rate-cli.ts +6 -7
  433. package/scripts/issue/defect-rate.ts +37 -27
  434. package/scripts/issue/git-next-issues.ts +9 -8
  435. package/scripts/issue/issue-auto-ok.ts +24 -11
  436. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  437. package/scripts/issue/issue-backlinks.ts +6 -6
  438. package/scripts/issue/issue-cite-cli.ts +20 -18
  439. package/scripts/issue/issue-cite.ts +18 -8
  440. package/scripts/issue/issue-closing-pr.ts +4 -4
  441. package/scripts/issue/issue-comment-cli.ts +6 -4
  442. package/scripts/issue/issue-file-cli.ts +52 -15
  443. package/scripts/issue/issue-file-fold.ts +155 -0
  444. package/scripts/issue/issue-file.ts +9 -6
  445. package/scripts/issue/issue-fold-cli.ts +14 -9
  446. package/scripts/issue/issue-fold.ts +23 -8
  447. package/scripts/issue/issue-labels.ts +34 -38
  448. package/scripts/issue/issue-lint-cli.ts +2 -2
  449. package/scripts/issue/issue-lint.ts +1 -1
  450. package/scripts/issue/issue-merged.ts +10 -4
  451. package/scripts/issue/issue-number-shape.ts +27 -0
  452. package/scripts/issue/issue-rank.ts +1 -1
  453. package/scripts/issue/issue-read-cli.ts +4 -5
  454. package/scripts/issue/issue-read.ts +4 -5
  455. package/scripts/issue/issue-reference.ts +5 -5
  456. package/scripts/issue/issue-release-cli.ts +17 -7
  457. package/scripts/issue/issue-release.ts +3 -3
  458. package/scripts/issue/issue-report-failures.ts +7 -4
  459. package/scripts/issue/issue-scout-cli.ts +11 -11
  460. package/scripts/issue/issue-scout-closed.ts +4 -4
  461. package/scripts/issue/issue-scout.ts +4 -5
  462. package/scripts/issue/issue-state-cli.ts +17 -10
  463. package/scripts/issue/issue-state.ts +12 -13
  464. package/scripts/issue/issue-wip.ts +7 -7
  465. package/scripts/issue/markdown-section.ts +3 -3
  466. package/scripts/issue/measure-rerun-cli.ts +10 -9
  467. package/scripts/issue/reproduction-measure.ts +3 -3
  468. package/scripts/issue/session-cite.ts +56 -0
  469. package/scripts/josh/agent-session-environment.ts +10 -8
  470. package/scripts/josh/cli-body.ts +2 -2
  471. package/scripts/josh/command-suggest.ts +1 -1
  472. package/scripts/josh/file-map-stamp.ts +20 -23
  473. package/scripts/josh/hook-decision.ts +24 -28
  474. package/scripts/josh/josh-command-map.ts +4 -1
  475. package/scripts/josh/josh-command-types.ts +30 -35
  476. package/scripts/josh/josh-commands-ai.ts +6 -6
  477. package/scripts/josh/josh-commands-backlog.ts +15 -3
  478. package/scripts/josh/josh-commands-clone.ts +1 -1
  479. package/scripts/josh/josh-commands-development.ts +25 -4
  480. package/scripts/josh/josh-commands-document.ts +3 -3
  481. package/scripts/josh/josh-commands-guard.ts +3 -3
  482. package/scripts/josh/josh-commands-issue.ts +4 -5
  483. package/scripts/josh/josh-commands-lane.ts +14 -4
  484. package/scripts/josh/josh-commands-lint.ts +1 -1
  485. package/scripts/josh/josh-commands-run.ts +21 -7
  486. package/scripts/josh/josh-commands-split.ts +1 -2
  487. package/scripts/josh/josh-commands-versioning.ts +5 -5
  488. package/scripts/josh/josh-commands-workflow.ts +30 -22
  489. package/scripts/josh/josh-environment-file.ts +1 -1
  490. package/scripts/josh/josh-in-process.ts +3 -3
  491. package/scripts/josh/josh-logic.ts +6 -7
  492. package/scripts/josh/josh-run.ts +3 -3
  493. package/scripts/josh/josh-verdict.ts +9 -12
  494. package/scripts/josh/josh.ts +3 -3
  495. package/scripts/josh/kit-only.ts +2 -2
  496. package/scripts/josh/path-decision.ts +3 -3
  497. package/scripts/josh/platform-temporary.ts +7 -5
  498. package/scripts/josh/process-identity.ts +24 -6
  499. package/scripts/josh/process-owner.ts +4 -4
  500. package/scripts/josh/session-language-cli.ts +53 -11
  501. package/scripts/josh/session-language.ts +1 -1
  502. package/scripts/josh/stamp-file.ts +48 -29
  503. package/scripts/josh/stamp-record.ts +57 -0
  504. package/scripts/lane/lane-await.ts +35 -11
  505. package/scripts/lane/lane-cache.ts +6 -6
  506. package/scripts/lane/lane-capacity.ts +32 -17
  507. package/scripts/lane/lane-child-invocation.ts +17 -15
  508. package/scripts/lane/lane-child-marker.ts +12 -12
  509. package/scripts/lane/lane-cli.ts +12 -13
  510. package/scripts/lane/lane-close.ts +6 -6
  511. package/scripts/lane/lane-dispatch.ts +61 -72
  512. package/scripts/lane/lane-environment.ts +5 -5
  513. package/scripts/lane/lane-guard-policy.ts +7 -21
  514. package/scripts/lane/lane-handoff.ts +2 -2
  515. package/scripts/lane/lane-install.ts +9 -10
  516. package/scripts/lane/lane-launch-cli.ts +13 -8
  517. package/scripts/lane/lane-ledger.ts +73 -11
  518. package/scripts/lane/lane-leftover.ts +2 -2
  519. package/scripts/lane/lane-limit-cli.ts +160 -0
  520. package/scripts/lane/lane-limit-override.ts +74 -0
  521. package/scripts/lane/lane-load.ts +19 -68
  522. package/scripts/lane/lane-measure-cli.ts +15 -25
  523. package/scripts/lane/lane-occupancy.ts +6 -4
  524. package/scripts/lane/lane-open.ts +20 -19
  525. package/scripts/lane/lane-output.ts +4 -3
  526. package/scripts/lane/lane-paths.ts +12 -11
  527. package/scripts/lane/lane-phase.ts +33 -0
  528. package/scripts/lane/lane-reap.ts +2 -2
  529. package/scripts/lane/lane-registry.ts +16 -15
  530. package/scripts/lane/lane-relaunch.ts +9 -9
  531. package/scripts/lane/lane-report.ts +5 -4
  532. package/scripts/lane/lane-resume.ts +2 -2
  533. package/scripts/lane/lane-sampler.ts +55 -0
  534. package/scripts/lane/lane-seed.ts +7 -7
  535. package/scripts/lane/lane-stage-stats.ts +135 -0
  536. package/scripts/lane/lane-start-point.ts +8 -11
  537. package/scripts/lane/lane-stats.ts +60 -15
  538. package/scripts/lane/lane-stray.ts +1 -1
  539. package/scripts/lane/lane-vacant.ts +1 -1
  540. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  541. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  542. package/scripts/lane/openai-review-broker.ts +2 -4
  543. package/scripts/lib/ancestor-directories.ts +1 -1
  544. package/scripts/lib/bounded-pool.ts +2 -2
  545. package/scripts/lib/buffered-process.ts +4 -6
  546. package/scripts/lib/caddy-logs.sh +0 -0
  547. package/scripts/lib/cli-flags.ts +39 -6
  548. package/scripts/lib/error-message.ts +1 -1
  549. package/scripts/lib/json-value.ts +17 -3
  550. package/scripts/lib/poll.ts +1 -1
  551. package/scripts/lib/status-icons.ts +3 -3
  552. package/scripts/lib/timed-fetch.ts +1 -1
  553. package/scripts/lib/timeouts.ts +1 -1
  554. package/scripts/lines/bytes-command.ts +3 -4
  555. package/scripts/lines/effective-limit.ts +25 -12
  556. package/scripts/lines/line-budget.ts +47 -55
  557. package/scripts/lines/line-targets.ts +6 -2
  558. package/scripts/lines/lines-command.ts +3 -3
  559. package/scripts/lint/cross-file-recheck.ts +155 -0
  560. package/scripts/lint/cspell-cached.ts +1 -1
  561. package/scripts/lint/format.ts +1 -2
  562. package/scripts/lint/lint-parallel.ts +35 -19
  563. package/scripts/lint/lint-related-scope.ts +25 -15
  564. package/scripts/lint/lint-related.ts +6 -7
  565. package/scripts/managed-marker/index.ts +1 -1
  566. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  567. package/scripts/notify/git-notify.ts +9 -7
  568. package/scripts/notify/telegram-notify.ts +53 -37
  569. package/scripts/notify/telegram-test-logic.ts +3 -3
  570. package/scripts/notify/telegram-test.ts +45 -30
  571. package/scripts/observations/observation-ledger-home.ts +14 -8
  572. package/scripts/observations/observation-ledger-line.ts +3 -2
  573. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  574. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  575. package/scripts/observations/observation-ledger.ts +14 -15
  576. package/scripts/observations/observation-record-cli.ts +83 -0
  577. package/scripts/observations/observation-record.ts +91 -0
  578. package/scripts/observations/observations-flush-cli.ts +1 -1
  579. package/scripts/observations/observations-flush-landing.ts +7 -6
  580. package/scripts/observations/observations-flush.ts +26 -27
  581. package/scripts/overrides/overrides-check.ts +18 -8
  582. package/scripts/package/package-scout-cli.ts +1 -1
  583. package/scripts/package/package-scout-format.ts +2 -2
  584. package/scripts/package/package-scout.ts +1 -1
  585. package/scripts/propagate/propagate-git-failure.ts +1 -1
  586. package/scripts/propagate/propagate-git.ts +7 -7
  587. package/scripts/propagate/propagate-plan.ts +2 -2
  588. package/scripts/propagate/propagate-publish.ts +2 -3
  589. package/scripts/propagate/propagate-run.ts +5 -7
  590. package/scripts/propagate/propagate-select.ts +1 -1
  591. package/scripts/propagate/propagate-steps.ts +19 -20
  592. package/scripts/propagate/propagate-targets.ts +6 -10
  593. package/scripts/propagate/propagate.ts +5 -5
  594. package/scripts/refactor/import-graph.ts +1 -1
  595. package/scripts/refactor/refactor-lint.ts +4 -10
  596. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  597. package/scripts/refactor/refactor-scan.ts +2 -2
  598. package/scripts/refactor/refactor-targets.ts +1 -1
  599. package/scripts/release/github-release-cli.ts +25 -3
  600. package/scripts/release/github-release-runs.ts +1 -1
  601. package/scripts/release/release-cli.ts +21 -4
  602. package/scripts/release/release-history.ts +6 -10
  603. package/scripts/release/release-plan.ts +3 -3
  604. package/scripts/release/release-progress.ts +3 -4
  605. package/scripts/release/release-publish.ts +8 -9
  606. package/scripts/release/release-scope-cli.ts +8 -10
  607. package/scripts/release/release-tag.ts +6 -8
  608. package/scripts/release/release-worktree.ts +5 -5
  609. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  610. package/scripts/repo/auto-merge-setting.ts +1 -1
  611. package/scripts/repo/repo-setting.ts +4 -4
  612. package/scripts/repo/repository-labels.ts +1 -1
  613. package/scripts/repo/required-checks-logic.ts +3 -3
  614. package/scripts/repo/required-checks-report.ts +1 -1
  615. package/scripts/repo/ruleset-check-cli.ts +1 -1
  616. package/scripts/repo/ruleset-check.ts +1 -1
  617. package/scripts/report/report-format-reference.ts +26 -0
  618. package/scripts/report/report-lint-cli.ts +2 -2
  619. package/scripts/report/report-lint.ts +16 -2
  620. package/scripts/review/disposition-cli.ts +2 -2
  621. package/scripts/review/disposition-logic.ts +1 -1
  622. package/scripts/review/live-evidence.ts +9 -6
  623. package/scripts/review/review-attest-cli.ts +1 -2
  624. package/scripts/review/review-attest.ts +3 -3
  625. package/scripts/review/review-brief-cli.ts +19 -20
  626. package/scripts/review/review-brief.ts +29 -32
  627. package/scripts/review/review-checkout.ts +2 -2
  628. package/scripts/review/review-diff-parts.ts +3 -5
  629. package/scripts/review/review-diff-write.ts +1 -1
  630. package/scripts/review/review-finding-ledger.ts +7 -4
  631. package/scripts/review/review-findings-cli.ts +2 -2
  632. package/scripts/review/review-level.ts +4 -7
  633. package/scripts/review/review-record-cli.ts +73 -16
  634. package/scripts/review/review-record.ts +5 -4
  635. package/scripts/review/review-round2-cli.ts +2 -3
  636. package/scripts/review/review-round2.ts +13 -21
  637. package/scripts/review/review-stamps.ts +9 -71
  638. package/scripts/review/review-tree.ts +4 -5
  639. package/scripts/rules/bash-triggers.ts +4 -4
  640. package/scripts/rules/decision-oracle-batch.ts +6 -7
  641. package/scripts/rules/decision-oracle-stage.ts +1 -1
  642. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  643. package/scripts/rules/decision-oracle.ts +2 -2
  644. package/scripts/rules/delivered-rules.ts +61 -406
  645. package/scripts/rules/destructive-command.ts +2 -2
  646. package/scripts/rules/direct-filing.ts +4 -4
  647. package/scripts/rules/direct-pr-create.ts +2 -2
  648. package/scripts/rules/early-heartbeat.ts +15 -19
  649. package/scripts/rules/file-body.ts +5 -6
  650. package/scripts/rules/filing-cap.ts +6 -7
  651. package/scripts/rules/filing-offer.ts +1 -1
  652. package/scripts/rules/firing-point.ts +6 -6
  653. package/scripts/rules/gh-api.ts +2 -2
  654. package/scripts/rules/git-argv.ts +3 -3
  655. package/scripts/rules/git-force.ts +2 -2
  656. package/scripts/rules/hook-context-line.ts +31 -0
  657. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  658. package/scripts/rules/implementation-cut.ts +35 -32
  659. package/scripts/rules/index-guard.ts +2 -2
  660. package/scripts/rules/issue-citation.ts +7 -7
  661. package/scripts/rules/issue-comments.ts +21 -13
  662. package/scripts/rules/josh-git-bare.ts +2 -2
  663. package/scripts/rules/lane-background.ts +14 -16
  664. package/scripts/rules/lane-carry-conflict.ts +41 -5
  665. package/scripts/rules/lane-interactive-ask.ts +6 -9
  666. package/scripts/rules/lane-park.ts +12 -16
  667. package/scripts/rules/lane-split-park.ts +1 -2
  668. package/scripts/rules/lane-switch-main.ts +10 -13
  669. package/scripts/rules/last-prompt.ts +1 -1
  670. package/scripts/rules/oracle-consulted.ts +5 -5
  671. package/scripts/rules/oracle-firing.ts +6 -9
  672. package/scripts/rules/oracle-list-cli.ts +2 -2
  673. package/scripts/rules/permission-guards.ts +2 -2
  674. package/scripts/rules/piped-verification.ts +79 -9
  675. package/scripts/rules/poll-loop.ts +9 -11
  676. package/scripts/rules/pre-gate-cut.ts +33 -30
  677. package/scripts/rules/prior-comment-read.ts +3 -3
  678. package/scripts/rules/protected-files.ts +25 -13
  679. package/scripts/rules/raw-field-body.ts +3 -4
  680. package/scripts/rules/reply-language.ts +1 -1
  681. package/scripts/rules/rule-body-guard.ts +10 -12
  682. package/scripts/rules/rule-guard.ts +1 -1
  683. package/scripts/rules/rule-list.ts +51 -0
  684. package/scripts/rules/rule-registry-rows.ts +282 -0
  685. package/scripts/rules/rule-registry.ts +109 -0
  686. package/scripts/rules/rule-value-cache.ts +2 -2
  687. package/scripts/rules/rule-value-cli.ts +6 -4
  688. package/scripts/rules/rule-value.ts +61 -22
  689. package/scripts/rules/run-tail-rule.ts +11 -15
  690. package/scripts/rules/shell-body-trigger.ts +7 -7
  691. package/scripts/rules/shell-segments.ts +2 -4
  692. package/scripts/rules/stop-rules.ts +54 -41
  693. package/scripts/rules/tail-commands.ts +1 -1
  694. package/scripts/rules/test-declared-commit.ts +2 -2
  695. package/scripts/rules/third-party-write.ts +3 -3
  696. package/scripts/rules/worktree-guard.ts +12 -5
  697. package/scripts/run/add/run-add-cli.ts +165 -0
  698. package/scripts/run/add/run-add.ts +124 -0
  699. package/scripts/run/board/run-board-cli.ts +207 -0
  700. package/scripts/run/board/run-board-closed.ts +95 -0
  701. package/scripts/run/board/run-board-every.ts +60 -0
  702. package/scripts/run/board/run-board-fetch.ts +38 -0
  703. package/scripts/run/board/run-board-fit.ts +219 -0
  704. package/scripts/run/board/run-board-github.ts +162 -0
  705. package/scripts/run/board/run-board-header.ts +275 -0
  706. package/scripts/run/board/run-board-kind.ts +35 -0
  707. package/scripts/run/board/run-board-labels.ts +299 -0
  708. package/scripts/run/board/run-board-layout.ts +222 -0
  709. package/scripts/run/board/run-board-link.ts +31 -0
  710. package/scripts/run/board/run-board-machine.ts +198 -0
  711. package/scripts/run/board/run-board-notes.ts +103 -0
  712. package/scripts/run/board/run-board-phase.ts +136 -0
  713. package/scripts/run/board/run-board-plan.ts +129 -0
  714. package/scripts/run/board/run-board-read.ts +62 -0
  715. package/scripts/run/board/run-board-render-legend.ts +82 -0
  716. package/scripts/run/board/run-board-render-notes.ts +77 -0
  717. package/scripts/run/board/run-board-render-slot.ts +50 -0
  718. package/scripts/run/board/run-board-render.ts +407 -0
  719. package/scripts/run/board/run-board-scope.ts +17 -0
  720. package/scripts/run/board/run-board-screen.ts +43 -0
  721. package/scripts/run/board/run-board-span.ts +66 -0
  722. package/scripts/run/board/run-board-spin.ts +115 -0
  723. package/scripts/run/board/run-board-state.ts +113 -0
  724. package/scripts/run/board/run-board-status.ts +279 -0
  725. package/scripts/run/board/run-board-tick.ts +210 -0
  726. package/scripts/run/board/run-board-track.ts +22 -0
  727. package/scripts/run/board/run-board-usage-read.ts +255 -0
  728. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  729. package/scripts/run/board/run-board-usage-text.ts +80 -0
  730. package/scripts/run/board/run-board-usage.ts +165 -0
  731. package/scripts/run/carry/run-carry-added.ts +62 -0
  732. package/scripts/run/carry/run-carry-args.ts +25 -22
  733. package/scripts/run/carry/run-carry-change.ts +1 -1
  734. package/scripts/run/carry/run-carry-cli.ts +71 -48
  735. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  736. package/scripts/run/carry/run-carry-ended.ts +85 -0
  737. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  738. package/scripts/run/carry/run-carry-stash.ts +3 -2
  739. package/scripts/run/carry/run-carry-streak.ts +8 -10
  740. package/scripts/run/carry/run-carry.ts +85 -89
  741. package/scripts/run/cut/run-cut-args.ts +7 -7
  742. package/scripts/run/cut/run-cut-cli.ts +54 -36
  743. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  744. package/scripts/run/cut/run-cut-report.ts +37 -16
  745. package/scripts/run/cut/run-cut.ts +63 -77
  746. package/scripts/run/detached-launch.ts +35 -50
  747. package/scripts/run/entry/run-entry-cli.ts +48 -27
  748. package/scripts/run/entry/run-entry-stop.ts +7 -9
  749. package/scripts/run/entry/run-entry.ts +5 -6
  750. package/scripts/run/event/run-event-cli.ts +5 -6
  751. package/scripts/run/event/run-event-filed.ts +69 -0
  752. package/scripts/run/event/run-event-follow.ts +3 -3
  753. package/scripts/run/event/run-event-plan.ts +38 -0
  754. package/scripts/run/event/run-event-render.ts +9 -4
  755. package/scripts/run/event/run-event-scope.ts +47 -18
  756. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  757. package/scripts/run/event/run-event-stream.ts +171 -46
  758. package/scripts/run/event/run-event-watch.ts +4 -6
  759. package/scripts/run/hold/run-hold-cli.ts +65 -62
  760. package/scripts/run/hold/run-hold.ts +88 -46
  761. package/scripts/run/merge/run-merge-cli.ts +116 -77
  762. package/scripts/run/merge/run-merge-collect.ts +107 -0
  763. package/scripts/run/merge/run-merge-steps.ts +112 -65
  764. package/scripts/run/merge/run-merge-token.ts +30 -0
  765. package/scripts/run/merge/run-merge.ts +31 -22
  766. package/scripts/run/progress/run-progress-args.ts +4 -4
  767. package/scripts/run/progress/run-progress-cli.ts +39 -50
  768. package/scripts/run/progress/run-progress-clock.ts +25 -32
  769. package/scripts/run/progress/run-progress-config.ts +6 -9
  770. package/scripts/run/progress/run-progress-read.ts +9 -10
  771. package/scripts/run/progress/run-progress.ts +48 -53
  772. package/scripts/run/review/run-review-cli.ts +6 -6
  773. package/scripts/run/review/run-review-steps.ts +6 -6
  774. package/scripts/run/review/run-review.ts +9 -11
  775. package/scripts/run/run-cli-fault.ts +29 -0
  776. package/scripts/run/run-ending-cli.ts +3 -3
  777. package/scripts/run/run-ending.ts +10 -14
  778. package/scripts/run/run-halfrun-resume.ts +6 -8
  779. package/scripts/run/run-headless.ts +26 -12
  780. package/scripts/run/run-invocation.ts +17 -22
  781. package/scripts/run/run-label.ts +7 -5
  782. package/scripts/run/run-liveness-cli.ts +19 -6
  783. package/scripts/run/run-liveness.ts +27 -38
  784. package/scripts/run/run-next-cli.ts +5 -9
  785. package/scripts/run/run-next.ts +4 -5
  786. package/scripts/run/run-parent-cut-hook.ts +10 -12
  787. package/scripts/run/run-preflight.ts +25 -29
  788. package/scripts/run/run-prep-cli.ts +17 -13
  789. package/scripts/run/run-prep-locate.ts +4 -5
  790. package/scripts/run/run-prep.ts +7 -10
  791. package/scripts/run/run-prrun-resume.ts +2 -2
  792. package/scripts/run/run-report-cli.ts +4 -4
  793. package/scripts/run/run-report.ts +9 -14
  794. package/scripts/run/run-retrospective.ts +3 -3
  795. package/scripts/run/run-section.ts +42 -0
  796. package/scripts/run/run-stage-read.ts +2 -2
  797. package/scripts/run/run-stage.ts +6 -4
  798. package/scripts/run/run-status-cli.ts +7 -5
  799. package/scripts/run/run-status.ts +6 -7
  800. package/scripts/run/run-step-cli.ts +64 -18
  801. package/scripts/run/run-step.ts +107 -51
  802. package/scripts/run/run-stop-notify.ts +7 -8
  803. package/scripts/run/run-stranded-cli.ts +1 -1
  804. package/scripts/run/run-stranded-detect.ts +4 -4
  805. package/scripts/run/run-stranded.ts +11 -13
  806. package/scripts/run/run-tail-cli.ts +15 -16
  807. package/scripts/run/run-tail.ts +14 -33
  808. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  809. package/scripts/run/run-watcher-guard.ts +11 -12
  810. package/scripts/run/run-watcher-hook.ts +6 -12
  811. package/scripts/run/ship/run-ship-cli.ts +67 -33
  812. package/scripts/run/ship/run-ship-detach.ts +15 -13
  813. package/scripts/run/ship/run-ship-lock.ts +1 -1
  814. package/scripts/run/ship/run-ship-next.ts +7 -8
  815. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  816. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  817. package/scripts/run/ship/run-ship-probe.ts +4 -4
  818. package/scripts/run/ship/run-ship-return.ts +1 -1
  819. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  820. package/scripts/run/ship/run-ship-review.ts +12 -14
  821. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  822. package/scripts/run/ship/run-ship-stage.ts +80 -26
  823. package/scripts/run/ship/run-ship-steps.ts +26 -16
  824. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  825. package/scripts/run/ship/run-ship-sync.ts +9 -8
  826. package/scripts/run/ship/run-ship.ts +17 -32
  827. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  828. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  829. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  830. package/scripts/run/tidy/run-tidy.ts +4 -3
  831. package/scripts/run/wake/run-wake-cli.ts +27 -32
  832. package/scripts/run/wake/run-wake-describe.ts +24 -28
  833. package/scripts/run/wake/run-wake-driver.ts +14 -14
  834. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  835. package/scripts/run/wake/run-wake-loop.ts +9 -9
  836. package/scripts/run/wake/run-wake-restart.ts +4 -5
  837. package/scripts/run/wake/run-wake-session.ts +23 -27
  838. package/scripts/run/wake/run-wake.ts +57 -279
  839. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  840. package/scripts/safe-chain/pack-hook.ts +2 -2
  841. package/scripts/safe-chain/preinstall-command.ts +2 -2
  842. package/scripts/security/security-audit-logic.ts +1 -1
  843. package/scripts/security/security-audit-provision-logic.ts +1 -1
  844. package/scripts/security/security-audit-provision.ts +2 -2
  845. package/scripts/security/security-audit.ts +5 -5
  846. package/scripts/security/security-updates-logic.ts +2 -3
  847. package/scripts/security/security-updates.ts +2 -4
  848. package/scripts/self-sync-guard/index.ts +1 -1
  849. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  850. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  851. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  852. package/scripts/sonar/sonar-hotspots.ts +1 -1
  853. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  854. package/scripts/sonar/sonar-new-code.ts +1 -1
  855. package/scripts/sonar/sonar-project.ts +1 -1
  856. package/scripts/split/split-assess-cli.ts +1 -1
  857. package/scripts/split/split-assess.ts +3 -3
  858. package/scripts/sync/directory-copy-guard.ts +2 -3
  859. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  860. package/scripts/sync/managed-config-scope.ts +4 -4
  861. package/scripts/sync/plugin-skill-directories.ts +2 -2
  862. package/scripts/sync/reconcile-templates.ts +17 -8
  863. package/scripts/sync/removed-skill-manifest.ts +2 -3
  864. package/scripts/sync/sync-ai-files.ts +7 -7
  865. package/scripts/sync/sync-configs.ts +30 -3
  866. package/scripts/sync/sync-hook-safety.ts +2 -2
  867. package/scripts/sync/sync.ts +23 -10
  868. package/scripts/sync/synced-paths.ts +2 -1
  869. package/scripts/sync/workflow-pin-logic.ts +1 -1
  870. package/scripts/test/test-declared-changed.ts +4 -4
  871. package/scripts/test/test-declared-logic.ts +2 -3
  872. package/scripts/test/test-declared-match.ts +25 -4
  873. package/scripts/test/test-declared.ts +26 -9
  874. package/scripts/test/test-red-commit.ts +3 -2
  875. package/scripts/test/test-red-logic.ts +7 -14
  876. package/scripts/test/test-red.ts +12 -47
  877. package/scripts/test/test-related-scope.ts +2 -3
  878. package/scripts/test/test-related.ts +3 -3
  879. package/scripts/test/test-type-logic.ts +1 -2
  880. package/scripts/test/test-unit-guard.ts +13 -17
  881. package/scripts/test/unit-worker-share.ts +7 -8
  882. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  883. package/scripts/time-runtime/time-background.ts +17 -21
  884. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  885. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  886. package/scripts/time-runtime/time-bundles.ts +11 -12
  887. package/scripts/time-runtime/time-call-identity.ts +1 -1
  888. package/scripts/time-runtime/time-command-key.ts +2 -2
  889. package/scripts/time-runtime/time-density-hook.ts +8 -11
  890. package/scripts/time-runtime/time-density.ts +5 -5
  891. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  892. package/scripts/time-runtime/time-format.ts +5 -5
  893. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  894. package/scripts/time-runtime/time-instant.ts +1 -1
  895. package/scripts/time-runtime/time-markers.ts +15 -19
  896. package/scripts/time-runtime/time-phase-names.ts +3 -3
  897. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  898. package/scripts/time-runtime/time-round-trips.ts +20 -23
  899. package/scripts/time-runtime/time-shell.ts +8 -8
  900. package/scripts/time-runtime/time-single-check.ts +1 -2
  901. package/scripts/time-runtime/time-spans.ts +35 -40
  902. package/scripts/time-runtime/time-tool-call.ts +15 -16
  903. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  904. package/scripts/time-runtime/time-writes.ts +5 -5
  905. package/scripts/ui/ui-routes-cli.ts +1 -2
  906. package/scripts/ui/ui-routes.ts +1 -2
  907. package/scripts/version/bump-version.ts +1 -1
  908. package/scripts/version/fresh-metadata-cache.ts +2 -2
  909. package/scripts/version/latest-corepack.ts +26 -26
  910. package/scripts/version/latest-lane-guard.ts +1 -1
  911. package/scripts/version/latest-scope-cli.ts +2 -2
  912. package/scripts/version/latest-stamp.ts +1 -2
  913. package/scripts/version/latest-update.ts +2 -2
  914. package/scripts/version/npm-registry.ts +2 -2
  915. package/scripts/version/package-manager-version.ts +18 -0
  916. package/scripts/version/publishable-range-check.ts +2 -1
  917. package/scripts/version/publishable-range.ts +1 -1
  918. package/scripts/version/release-age.ts +11 -11
  919. package/scripts/version/release-hold.ts +2 -2
  920. package/scripts/version/safe-chain-version-update.ts +3 -3
  921. package/scripts/version/version-check-logic.ts +2 -3
  922. package/scripts/version/version-check.ts +1 -2
  923. package/scripts/version/version-command-config.ts +2 -2
  924. package/scripts/version/version-commands.ts +3 -3
  925. package/scripts/version/version-remote.ts +4 -4
  926. package/scripts/version/version-targets.ts +2 -2
  927. package/templates/gitignore +7 -0
  928. package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
  929. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  930. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  931. package/scripts/backlog/backlog-restructure.ts +0 -152
  932. package/scripts/rules/issue-fold-rule.ts +0 -72
  933. package/scripts/rules/wip-cap.ts +0 -63
  934. package/scripts/run/run-issue-number.ts +0 -19
@@ -1,19 +1,19 @@
1
1
  import { epic_parse } from '#scripts/epic/epic-parse'
2
2
  import { git_gh_command } from '#scripts/gh/git-gh-command'
3
- import { parse_json_object_safe } from '#scripts/git/parse-json-array'
3
+ import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
4
+ import { session_cite } from '#scripts/issue/session-cite'
4
5
  import { poll, type PollOptions } from '#scripts/lib/poll'
5
6
  import { z } from 'zod'
6
7
 
7
- // **A merged pull request whose `closes #N` GitHub did not apply** (joshuafolkken/kit#2770). From
8
- // 2026-09-30 06:34Z every merge `followup` made left its issue open — seven in a row, where every
9
- // earlier one was closed by the pull request within a second — although the merge request, the
10
- // merging account and the `closes #N` first line were all the same as before. The run then reported
11
- // success, and a `backlogrun` read the still-open child as a failure and stopped.
8
+ // **A merged pull request whose `closes #N` GitHub did not apply**. GitHub can leave the issue open
9
+ // although the merge request, the merging account and the `closes #N` first line are all correct;
10
+ // the run would then report success, and a `backlogrun` would read the still-open child as a failure
11
+ // and stop.
12
12
  //
13
13
  // **The issue's state is what is checked, not `closingIssuesReferences`.** That field is GraphQL-only
14
- // (a cloud session is answered 403 there, joshuafolkken/kit#1022) and it is not the fact that failed:
15
- // PR #2768 answered it empty at the time and names #2761 now, while #2761 was never closed by it. The
16
- // observable defect is an issue left open, so that is what is read, and what is repaired.
14
+ // (a cloud session is answered 403 there) and it is not the fact that fails: it can name an issue
15
+ // the pull request never closed. The observable defect is an issue left open, so that is what is
16
+ // read, and what is repaired.
17
17
  //
18
18
  // **A short wait first**, because GitHub applies the keyword asynchronously — the closes it did apply
19
19
  // landed within a second of the merge. Closing on the first read would take the close away from the
@@ -26,7 +26,8 @@ const state_read_schema = z.object({ state: z.string().optional() })
26
26
 
27
27
  async function is_issue_closed(issue_number: string): Promise<boolean> {
28
28
  const raw = await git_gh_command.issue_get_state_and_relations(issue_number)
29
- const parsed = raw === undefined ? undefined : parse_json_object_safe(raw, state_read_schema)
29
+ const parsed =
30
+ raw === undefined ? undefined : parse_json_object_or_undefined(raw, state_read_schema)
30
31
 
31
32
  return epic_parse.is_state_closed(parsed?.state)
32
33
  }
@@ -36,7 +37,7 @@ const FOLLOWUP_CLOSER = 'pnpm josh followup'
36
37
  // English, like every other string a script posts: the comment says why the close came from this
37
38
  // command rather than from the pull request, so a reader of the issue is not left guessing. `closer`
38
39
  // names the command that closed it — `followup` at the merge, or `run:merge` when a `backlogrun`
39
- // finds the child still open afterwards (joshuafolkken/kit#2769).
40
+ // finds the child still open afterwards.
40
41
  function build_close_comment(pr_url: string | undefined, closer: string = FOLLOWUP_CLOSER): string {
41
42
  return (
42
43
  `Closed by \`${closer}\`: ${pr_url ?? 'the merged pull request'} merged, ` +
@@ -58,11 +59,13 @@ async function ensure_issue_closed(
58
59
  (await poll.poll_until(async () => await is_issue_closed(issue_number), wait))
59
60
  if (is_done) return
60
61
 
61
- console.warn(`⚠️ Issue #${issue_number} is still open after the merge — closing it.`)
62
+ console.warn(
63
+ `⚠️ Issue ${session_cite.issue(issue_number)} is still open after the merge — closing it.`,
64
+ )
62
65
  const comment = build_close_comment(input.pr_url, input.closer)
63
66
 
64
67
  if (!(await git_gh_command.issue_close(issue_number, comment))) {
65
- throw new Error(`gh api could not close issue #${issue_number}`)
68
+ throw new Error(`gh api could not close issue ${session_cite.issue(issue_number)}`)
66
69
  }
67
70
  }
68
71
 
@@ -1,11 +1,12 @@
1
1
  import { git_gh_command } from '#scripts/gh/git-gh-command'
2
2
  import { issue_label_schema } from '#scripts/git/git-schemas'
3
- import { parse_json_object_safe } from '#scripts/git/parse-json-array'
3
+ import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
4
4
  import { IN_PROGRESS_LABEL, label_name_of } from '#scripts/issue/issue-labels'
5
+ import { session_cite } from '#scripts/issue/session-cite'
5
6
  import { z } from 'zod'
6
7
 
7
8
  // **`in-progress` means "a run is holding this issue right now", and a merged run is not holding
8
- // anything** (joshuafolkken/kit#1794). `pnpm josh followup` merged the pull request and closed the
9
+ // anything**. `pnpm josh followup` merged the pull request and closed the
9
10
  // issue and left the label on it, so the mark stopped meaning what it says: the ledger entry
10
11
  // `k:followup-leaves-in-progress-label` recorded it on 2026-09-11 and a second sighting the same day
11
12
  // — both issues of one `queue` answering `labels: in-progress` after they had closed.
@@ -26,18 +27,20 @@ const labels_read_schema = z.object({ labels: z.array(issue_label_schema).option
26
27
 
27
28
  // **Read, then removed — never removed on a guess.** The removal names the label in the request
28
29
  // path, so it has to name the spelling GitHub stored: GitHub keeps the casing a label was created
29
- // with and treats `In-Progress` as the same label, and a repository spelling it that way is exactly
30
- // the one joshuafolkken/kit#1132 was filed about. The comparison is `label_name_of`'s, the same one
30
+ // with and treats `In-Progress` as the same label, so a repository may spell it that way. The
31
+ // comparison is `label_name_of`'s, the same one
31
32
  // every other membership test in this codebase goes through.
32
33
  function unreadable_error(issue_number: string): Error {
33
- return new Error(`gh api answered no readable labels for issue #${issue_number}`)
34
+ return new Error(
35
+ `gh api answered no readable labels for issue ${session_cite.issue(issue_number)}`,
36
+ )
34
37
  }
35
38
 
36
39
  async function read_label_names(issue_number: string): Promise<ReadonlyArray<string>> {
37
40
  const raw = await git_gh_command.issue_get_labels_and_body(issue_number)
38
41
  if (raw === undefined) throw unreadable_error(issue_number)
39
42
 
40
- const parsed = parse_json_object_safe(raw, labels_read_schema)
43
+ const parsed = parse_json_object_or_undefined(raw, labels_read_schema)
41
44
  if (parsed === undefined) throw unreadable_error(issue_number)
42
45
 
43
46
  return (parsed.labels ?? []).map((label) => label.name)
@@ -3,7 +3,7 @@ import type { PullMergeState } from '#scripts/gh/git-gh-pr-read'
3
3
  import { json_value } from '#scripts/lib/json-value'
4
4
  import { z } from 'zod'
5
5
 
6
- // joshuafolkken/kit#3023: `prrun` stops at a green, mergeable pull request and a person merges it by
6
+ // `prrun` stops at a green, mergeable pull request and a person merges it by
7
7
  // hand. Re-running `pnpm josh followup` then has to finish what a merged `fullrun` finishes — the
8
8
  // completion report, the epic close, the merged issue's close, the `in-progress` removal, the hold
9
9
  // release and the completion Telegram — **from the one tail `followup` already runs**, not a copy of
@@ -3,13 +3,11 @@ import { release_history, type HistoryReader } from '#scripts/release/release-hi
3
3
  import { release_plan } from '#scripts/release/release-plan'
4
4
  import { version_targets } from '#scripts/version/version-targets'
5
5
 
6
- // What the completion notification says about versions, now that children do not set one
7
- // (joshuafolkken/kit#1486).
6
+ // What the completion notification says about versions, now that children do not set one.
8
7
  //
9
- // **It used to read `package.json` and print `📦 project version: <v>`.** While every child ran
10
- // `pnpm josh bump minor` that value was this run's shipping version. Children no longer bump — the
11
- // version is decided from main's history by `pnpm josh release` — so the same read now returns the
12
- // **previous** release, and printing it presents an unconfirmed shipping version as a fact.
8
+ // **It does not print the `package.json` version.** Children do not bump — the version is decided
9
+ // from main's history by `pnpm josh release` — so that read returns the **previous** release, and
10
+ // printing it presents an unconfirmed shipping version as a fact.
13
11
  //
14
12
  // **What goes out instead is the number a release is made of**: how many merges main has taken since
15
13
  // the version last changed. It is the count `pnpm josh release` itself acts on, taken from that
@@ -23,7 +21,7 @@ import { version_targets } from '#scripts/version/version-targets'
23
21
  // passes `false` and carries no note, because by then the merge is on the remote and the fetch below
24
22
  // brings it in; `git-followup-finish.ts` is that caller, so **both branches of this flag
25
23
  // are live**. What a run *does* about the count is `pnpm josh release:scope`, asked after the merge,
26
- // which reads `read_pending` below rather than this line (joshuafolkken/kit#1582).
24
+ // which reads `read_pending` below rather than this line.
27
25
  const MERGE_PENDING_NOTE = "— this run's merge is not counted; it lands next"
28
26
 
29
27
  interface PendingReadOptions {
@@ -34,7 +32,7 @@ interface PendingReadOptions {
34
32
  tip?: string
35
33
  }
36
34
 
37
- // **The note belongs to the line, not to the count** (joshuafolkken/kit#1582). `read_pending`
35
+ // **The note belongs to the line, not to the count**. `read_pending`
38
36
  // returns a number and has no sentence to annotate, so `pnpm josh release:scope` — which wants the
39
37
  // number alone — would otherwise have to pass a flag about wording it never prints.
40
38
  interface PendingLineOptions extends PendingReadOptions {
@@ -46,7 +44,7 @@ interface PendingLineOptions extends PendingReadOptions {
46
44
  // merge main took after the branch was cut is not even an ancestor, so the number would be silently
47
45
  // low and the line still say "on main". Fetching first is what makes it current, which is also what
48
46
  // lets the post-merge console line — and `pnpm josh release:scope`, asked from a lane or a feature
49
- // branch — count the merge that just landed (joshuafolkken/kit#1582).
47
+ // branch — count the merge that just landed.
50
48
  async function read_tip(options: PendingReadOptions): Promise<string> {
51
49
  if (options.tip !== undefined) return options.tip
52
50
 
@@ -1,21 +1,17 @@
1
1
  import { PrConflictError } from '#scripts/gh/git-pr-checks-eval'
2
+ import { lane_ledger } from '#scripts/lane/lane-ledger'
2
3
  import { time_format } from '#scripts/time-runtime/time-format'
3
4
 
4
- // Where `pnpm josh followup` spends its own wall clock (joshuafolkken/kit#1349).
5
+ // Where `pnpm josh followup` spends its own wall clock.
5
6
  //
6
- // joshuafolkken/kit#1333 removed 19 seconds of dead air between reading a clean review and issuing
7
- // the merge, and left the next stretch of the same 134 seconds unexamined: the **44 seconds
8
- // `followup` spends on itself**. One invocation did nine things in order — the `closes #N`
9
- // check, the three GitHub reads the notification needs, the required-check wait, the CodeRabbit line
10
- // comments, the AI reviewers' top-level comments, the completion Telegram, the merge request, the
11
- // completion comment and the epic auto-close — and not one of them had ever been timed. So every
12
- // proposal to shorten it was a guess, and a guess made under time pressure falls on whichever stretch
13
- // is easiest to cut rather than on the one that is long: the notification and the auto-close, which is
14
- // exactly where the merge gate lives.
7
+ // One invocation does nine things in order — the `closes #N` check, the three GitHub reads the
8
+ // notification needs, the required-check wait, the CodeRabbit line comments, the AI reviewers'
9
+ // top-level comments, the completion Telegram, the merge request, the completion comment and the
10
+ // epic auto-close. Untimed, every proposal to shorten it is a guess, and a guess made under time
11
+ // pressure falls on whichever stretch is easiest to cut rather than on the one that is long.
15
12
  //
16
- // **Those nine are seven printed rows now** (joshuafolkken/kit#1446): the four reads in front of the
17
- // wait go out together and so do the two steps after the merge, and a lap measures an interval rather
18
- // than a call. `STAGE` below is the list; the two names carrying `and` are the batches.
13
+ // **Those nine are seven printed rows**: the four reads in front of the wait go out together and so
14
+ // 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.
19
15
  //
20
16
  // **Laps, not a wrapper per stage.** The alternative was a `measure(name, () => …)` closure around
21
17
  // each call, which reads well and rewrites every call site in the file it instruments — nine
@@ -43,7 +39,7 @@ const STAGE_TOTAL_PREFIX = 'followup stages total: '
43
39
  // One wider than the longest name below, so the durations line up in one column without the reader
44
40
  // having to count. **The extra one is load-bearing**: `padEnd` adds nothing once a name reaches the
45
41
  // width, and `completion-and-epic-close` is 25 characters, so at 25 that row alone would run its
46
- // duration straight onto its name (joshuafolkken/kit#1446). Parsing is unaffected either way — the
42
+ // duration straight onto its name. Parsing is unaffected either way — the
47
43
  // fields are whitespace-separated.
48
44
  const STAGE_NAME_WIDTH = 26
49
45
  // Where the duration column starts, so the total lands under the stage durations rather than beside
@@ -55,7 +51,7 @@ const NO_DURATION = 0
55
51
  // The stages, named once. They are the units a proposal to shorten `followup` would be written
56
52
  // against, so a rename has to move the printer and whatever reads it together.
57
53
  //
58
- // **Two names say `and` because two stages became one** (joshuafolkken/kit#1446). Requests that need
54
+ // **Two names say `and` because two stages became one**. Requests that need
59
55
  // nothing from one another are now issued together, and a lap records an interval rather than a
60
56
  // call — so a batch is one interval, and what it holds has to be readable from its name or the
61
57
  // shortening becomes invisible to the very measurement that found it. `closes-and-context` is the
@@ -74,8 +70,8 @@ const STAGE = {
74
70
  // blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
75
71
  // them would leave the measurement blind to exactly the invocations worth measuring.
76
72
  interrupted: 'interrupted',
77
- // The interrupted lap when the wait failed on a merge conflict (joshuafolkken/kit#3221), so the
78
- // stage block names the cause a resumed session used to look up with `gh pr view`.
73
+ // The interrupted lap when the wait failed on a merge conflict, so the
74
+ // stage block names the cause a resumed session would otherwise look up with `gh pr view`.
79
75
  conflict: 'conflict',
80
76
  } as const
81
77
 
@@ -142,6 +138,20 @@ function print_stages(log: StageLog): void {
142
138
  for (const line of format_stages(log)) console.info(line)
143
139
  }
144
140
 
141
+ // The wait for CI goes to the lane ledger as well, where `josh lane:stats` reads it beside the review
142
+ // round it would overlap: the printed block reaches only this run's reader. A wait that threw is the
143
+ // `interrupted` lap and records nothing here.
144
+ async function record_ci_wait(log: StageLog): Promise<void> {
145
+ const wait = log.stages.find((stage) => stage.name === STAGE.checks_wait)
146
+
147
+ if (wait === undefined) return
148
+
149
+ await lane_ledger.record_stage({
150
+ stage: lane_ledger.CI_WAIT_STAGE,
151
+ elapsed_ms: wait.duration_ms,
152
+ })
153
+ }
154
+
145
155
  const git_followup_stages = {
146
156
  STAGE,
147
157
  STAGE_LINE_PREFIX,
@@ -151,6 +161,7 @@ const git_followup_stages = {
151
161
  total_ms,
152
162
  format_stages,
153
163
  print_stages,
164
+ record_ci_wait,
154
165
  stopped_lap,
155
166
  }
156
167
 
@@ -2,6 +2,7 @@
2
2
  import { parseArgs } from 'node:util'
3
3
  import { git_branch } from '#scripts/git/git-branch'
4
4
  import { git_error } from '#scripts/git/git-error'
5
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
5
6
  import { cli_body } from '#scripts/josh/cli-body'
6
7
  import { josh_environment_file } from '#scripts/josh/josh-environment-file'
7
8
  import { git_notify, type GitNotifyConfig } from '#scripts/notify/git-notify'
@@ -41,7 +42,7 @@ interface CliArguments {
41
42
  // The text is a constant rather than an inline literal: it is one option per supported flag, so it
42
43
  // grows with the command and would otherwise push `display_help` past the function line limit every
43
44
  // time a flag is added — a limit that exists to catch functions doing several things, which this one
44
- // never was (joshuafolkken/kit#1578).
45
+ // never was.
45
46
  const HELP_TEXT = `
46
47
  🚦 PR Followup Workflow
47
48
 
@@ -99,8 +100,8 @@ async function resolve_branch_name(raw_branch: string | undefined): Promise<stri
99
100
  // The message is resolved here rather than inside `git_notify`, so the file form reaches the config
100
101
  // as text and the config keeps one `message` field. `--notify-message-file` exists because the inline
101
102
  // form is a double-quoted shell argument: a backtick or a `$` in the body is evaluated before this
102
- // process starts, and joshuafolkken/kit#1198 recorded both halves of that — a Telegram body that
103
- // silently lost a word, and a comment body whose text ran as git commands.
103
+ // process starts — a Telegram body can silently lose a word, and a comment body's text can run as
104
+ // git commands.
104
105
  function build_notify_config(values: CliArguments['values']): GitNotifyConfig | undefined {
105
106
  return git_notify.build_notify_config({
106
107
  raw_target: values['notify-target'] ?? 'issue',
@@ -118,13 +119,13 @@ function is_merge_resolved(values: CliArguments['values']): boolean {
118
119
  return values['no-merge'] !== true
119
120
  }
120
121
 
121
- // joshuafolkken/kit#1522: `/code-review` is forked by the harness and inherits the *session's*
122
- // working directory, so a run implementing in a lane can be reviewed against a different tree
123
- // entirely — one holding the previous child's already-merged code. That review finds nothing wrong
124
- // and says so, and the run reads the silence as a clean round. **This is the seam where that stops
125
- // being free**: a merge is refused unless the review attested the checkout it was briefed on.
122
+ // `/code-review` is forked by the harness and inherits the *session's* working directory, so a run
123
+ // implementing in a lane can be reviewed against a different tree entirely — one holding the
124
+ // previous child's already-merged code. That review finds nothing wrong and says so, and the run
125
+ // would read the silence as a clean round. **This is the seam where that is caught**: a merge is
126
+ // refused unless the review attested the checkout it was briefed on.
126
127
  //
127
- // **Absence is a refusal, not a pass.** The defect produced *no* signal, so a check that only
128
+ // **Absence is a refusal, not a pass.** The defect produces *no* signal, so a check that only
128
129
  // compared two present records would answer `ok` in exactly the state it exists to catch.
129
130
  //
130
131
  // **Scoped to a checkout that actually briefed a review.** `review_attest.check` answers
@@ -141,10 +142,8 @@ function is_merge_permitted(status: string): boolean {
141
142
  return status === 'ok' || status === 'not-required'
142
143
  }
143
144
 
144
- const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
145
-
146
145
  function is_valid_issue(issue_number: string | undefined): boolean {
147
- return issue_number !== undefined && ISSUE_NUMBER_PATTERN.test(issue_number)
146
+ return issue_number !== undefined && issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue_number)
148
147
  }
149
148
 
150
149
  async function assert_review_attested(should_merge: boolean): Promise<void> {
@@ -157,13 +156,12 @@ async function assert_review_attested(should_merge: boolean): Promise<void> {
157
156
  throw new Error(review_attest.refusal_message(verdict))
158
157
  }
159
158
 
160
- // joshuafolkken/kit#2343: recording a review round was prose, and prose failed — eleven merges after
161
- // the instruction landed, `review:record` had never run once, so the recurrence ledger stayed blind.
162
- // **This is the seam where that stops being a request and becomes a gate**: a merge is refused unless
163
- // the round left a `- rf:` line for its issue, a zero-finding `none` line included.
159
+ // Recording a review round as a prose request leaves the recurrence ledger blind whenever it is
160
+ // skipped. **This is the seam where it is a gate instead**: a merge is refused unless the round left
161
+ // a `- rf:` line for its issue, a zero-finding `none` line included.
164
162
  //
165
163
  // **Absence is a refusal, `missing` exactly as `assert_review_attested`'s is** — the defect this
166
- // exists for produced *no* line, so silence must not read as success. A checkout that keeps no ledger
164
+ // exists for produces *no* line, so silence must not read as success. A checkout that keeps no ledger
167
165
  // answers `not-required` and merges as before, and a run whose issue the followup cannot identify has
168
166
  // no key to check, so it carries on rather than blocking on missing information.
169
167
  async function assert_review_recorded(
@@ -180,7 +178,7 @@ async function assert_review_recorded(
180
178
  throw new Error(review_record.refusal_message(issue))
181
179
  }
182
180
 
183
- // joshuafolkken/kit#2446: a runtime change merges only with its acceptance criteria run for real and
181
+ // A runtime change merges only with its acceptance criteria run for real and
184
182
  // recorded in the pull request body — `live_evidence` carries the why. `exempt` (no runtime path
185
183
  // changed) merges as before, and a `--no-merge` run has not reached the gate at all.
186
184
  async function assert_live_evidence(should_merge: boolean, branch_name: string): Promise<void> {
@@ -205,8 +203,8 @@ async function assert_merge_gates(
205
203
  }
206
204
 
207
205
  // After the gates, before the CI wait: a line appended since the run's commit rides the pull request
208
- // itself, so it merges with it — a lane's included (joshuafolkken/kit#2919). **A pull request that has
209
- // already merged skips both** (joshuafolkken/kit#3023): the gates guard a merge this run no longer
206
+ // itself, so it merges with it — a lane's included. **A pull request that has
207
+ // already merged skips both**: the gates guard a merge this run no longer
210
208
  // makes, and a ledger commit would land on a branch that has already gone in.
211
209
  async function prepare_merge(
212
210
  plan: MergePlan,
@@ -235,7 +233,7 @@ async function main(): Promise<void> {
235
233
 
236
234
  await prepare_merge(plan, issue_number, branch_name)
237
235
  // **The number the run reports on is the one it used**, which is the number the pull request
238
- // closes where the invocation named none (joshuafolkken/kit#1539). Recovered inside `run`, so the
236
+ // closes where the invocation named none. Recovered inside `run`, so the
239
237
  // tail records a run the command line could not identify rather than silently skipping it.
240
238
  const used_issue_number = await git_pr_followup.run({
241
239
  branch_name,
@@ -10,23 +10,19 @@ import { CHECK_STATUS_PASS, type PrStateSnapshot } from '#scripts/gh/git-pr-chec
10
10
  import { json_value } from '#scripts/lib/json-value'
11
11
 
12
12
  // The check wait and the notes read off its snapshot — split out of `git-pr-followup.ts` when it
13
- // reached its line limit (joshuafolkken/kit#3264). `git-pr-followup` re-exports each name it always
13
+ // reached its line limit. `git-pr-followup` re-exports each name it always
14
14
  // exported, so the move changed no call site and no suite that imports from it.
15
15
 
16
- // Named so a test can pin the note without restating it (joshuafolkken/kit#999).
16
+ // Named so a test can pin the note without restating it.
17
17
  const WATCH_FAILED_NOTE = 'pr checks --watch failed; falling through to polling'
18
18
 
19
19
  // The watch is a look ahead, not a gate. It fails when **any** check has failed — CodeRabbit
20
- // included — and letting that escape ended the run before `evaluate_pr_state` could apply kit#753's
21
- // CodeRabbit exemption at all. It only ever bit where every check finished inside the two-minute
22
- // window, so a repository with a slow E2E never saw it and a fast one always would
23
- // (joshuafolkken/kit#999). What the watch is has since changed — `gh pr checks --watch` went through
24
- // GraphQL, so joshuafolkken/kit#1028 replaced it with the same poll loop bounded to two minutes —
25
- // but its place here has not.
20
+ // included — and letting that escape would end the run before `evaluate_pr_state` could apply the
21
+ // CodeRabbit exemption at all, wherever every check finishes inside the two-minute window.
26
22
  //
27
23
  // Falling through costs nothing: whether the merge may proceed is decided in one place below, and a
28
- // genuinely failing non-CodeRabbit check still ends the wait on the first poll by kit#990's
29
- // fast-fail rather than by that failure.
24
+ // genuinely failing non-CodeRabbit check still ends the wait on the first poll by the fast-fail
25
+ // rather than by that failure.
30
26
  // The watch fails for two different reasons — "a check failed" and "no checks reported on this
31
27
  // branch" — and its own error does not say which. The pull request itself can: a failed check leaves
32
28
  // a rollup, and a branch with no checks leaves it empty. Falling through on the empty case would
@@ -53,8 +49,7 @@ function reads_as_empty_rollup(raw_json: string): boolean {
53
49
  // The read throws rather than answering `undefined`, so the `catch` is its only failure path.
54
50
  //
55
51
  // The **checks** half, not the whole snapshot: the question here is about `statusCheckRollup` alone,
56
- // and reading the review listing to answer it paged a whole conversation for nothing
57
- // (joshuafolkken/kit#1043).
52
+ // and reading the review listing to answer it paged a whole conversation for nothing.
58
53
  async function has_no_checks(branch_name: string): Promise<boolean> {
59
54
  try {
60
55
  const checks = await git_gh_command.pr_get_checks_snapshot(branch_name)
@@ -70,12 +65,11 @@ async function has_no_checks(branch_name: string): Promise<boolean> {
70
65
  async function handle_watch_failure(branch_name: string, error: unknown): Promise<void> {
71
66
  if (await has_no_checks(branch_name)) throw error
72
67
 
73
- // Swallowed, but never silently: the reason a run stopped early used to be this line, so it
74
- // stays visible even though it no longer decides anything.
68
+ // Swallowed, but never silently: the line stays visible even though it decides nothing.
75
69
  console.info(`⚠️ ${WATCH_FAILED_NOTE}: ${git_gh_helpers.get_error_message_with_stderr(error)}`)
76
70
  }
77
71
 
78
- // **Returns whether the watch confirmed completion** (joshuafolkken/kit#2029): `true` only when
72
+ // **Returns whether the watch confirmed completion**: `true` only when
79
73
  // `pr_checks_watch` saw every check finish, `false` when it timed out with checks still pending or
80
74
  // fell through to polling on a swallowed failure. `run_checks` reads it to decide how many stable poll
81
75
  // reads the wait still needs. A timed-out watch (`timed_out: true`) never spanned the pending→settled
@@ -96,7 +90,7 @@ async function watch_before_polling(branch_name: string): Promise<boolean> {
96
90
  }
97
91
  }
98
92
 
99
- // **A confirmed watch lowers the poll's stable-read requirement to one** (joshuafolkken/kit#2029). The
93
+ // **A confirmed watch lowers the poll's stable-read requirement to one**. The
100
94
  // watch is the first confirmation that every check settled, so the poll that follows need only agree
101
95
  // once rather than twice — which removes the extra interval `followup` spent re-proving a settled run.
102
96
  // A skipped or fallen-through watch keeps `DEFAULT_STABLE_READS`, and a check that turned red is still
@@ -111,7 +105,7 @@ async function run_checks(input: {
111
105
  return await git_pr_checks.wait_for_pr_success(input.branch_name, stable_reads)
112
106
  }
113
107
 
114
- // Temporary (kit#753): record every CodeRabbit check that was not passing when the merge gate
108
+ // Temporary: record every CodeRabbit check that was not passing when the merge gate
115
109
  // opened, so a merge shipped without CodeRabbit review stays auditable.
116
110
  function read_coderabbit_skip_notes(snapshot: PrStateSnapshot): Array<string> {
117
111
  return snapshot.rollup
@@ -124,9 +118,8 @@ function read_coderabbit_skip_notes(snapshot: PrStateSnapshot): Array<string> {
124
118
  }
125
119
 
126
120
  // The skip is printed where the run is being watched, not only carried into the Telegram body it
127
- // ends up in. A merge that went ahead while CodeRabbit had not come back is the one thing kit#753's
128
- // exemption trades away, and it used to be invisible in `followup`'s own output
129
- // (joshuafolkken/kit#1217).
121
+ // ends up in. A merge that went ahead while CodeRabbit had not come back is the one thing the
122
+ // CodeRabbit exemption trades away, so it must be visible in `followup`'s own output.
130
123
  function log_skip_notes(notes: ReadonlyArray<string>): void {
131
124
  for (const note of notes) {
132
125
  console.info(`⏭ ${note}`)
@@ -26,17 +26,17 @@ interface WrapupInput {
26
26
  branch_name: string
27
27
  issue_number: string | undefined
28
28
  // The number the pull request body's `closes #N` names — the only issue the merge claimed to
29
- // close, so the only one the merged-issue close may write to (joshuafolkken/kit#2770).
29
+ // close, so the only one the merged-issue close may write to.
30
30
  closes_number: string | undefined
31
31
  notify_config: GitNotifyConfig | undefined
32
32
  pr_url: string | undefined
33
33
  should_merge: boolean
34
34
  // The managed config-file report, which reaches the completion report on the Issue as well as the
35
- // completion notification (joshuafolkken/kit#1592). Empty on a run that changed nothing `josh sync`
35
+ // completion notification. Empty on a run that changed nothing `josh sync`
36
36
  // distributes, and an empty one adds no line.
37
37
  managed_notes: ReadonlyArray<string>
38
38
  // A pull request merged before this run is not merged again, and a tail whose completion report is
39
- // already on the issue does not post it twice (joshuafolkken/kit#3023, `git-followup-merged.ts`).
39
+ // already on the issue does not post it twice (`git-followup-merged.ts`).
40
40
  is_merged?: boolean | undefined
41
41
  is_completion_recorded?: boolean | undefined
42
42
  }
@@ -112,7 +112,7 @@ async function post_completion_notification(input: {
112
112
  }
113
113
  }
114
114
 
115
- // **Guarded only once the merge has landed** (joshuafolkken/kit#1539) — the rule and its reason are
115
+ // **Guarded only once the merge has landed** — the rule and its reason are
116
116
  // `git-followup-cleanup.ts`, so this module and the run's tail cannot disagree about it. After the
117
117
  // merge, a step that throws is reported and the ones after it still run, rather than taking the epic
118
118
  // close and the working-tree hold release down with it.
@@ -150,7 +150,7 @@ async function epic_close_step(input: WrapupInput): Promise<void> {
150
150
  })
151
151
  }
152
152
 
153
- // **The run's own mark, taken off at the end of the run that wrote it** (joshuafolkken/kit#1794).
153
+ // **The run's own mark, taken off at the end of the run that wrote it**.
154
154
  // `in-progress` is added by every entry point before it implements, and nothing took it off on the
155
155
  // ordinary ending: the pull request merged, the issue closed, and the mark stayed. Removed here
156
156
  // rather than by the workflow procedure because this is the one step that knows the merge landed.
@@ -173,7 +173,7 @@ async function in_progress_step(input: WrapupInput): Promise<void> {
173
173
  })
174
174
  }
175
175
 
176
- // **The merged issue's close, confirmed rather than assumed** (joshuafolkken/kit#2770): GitHub stopped
176
+ // **The merged issue's close, confirmed rather than assumed**: GitHub stopped
177
177
  // applying `closes #N` on some merges, and nothing noticed. The epic auto-close does not wait on it —
178
178
  // it already excludes the merged issue from its reads — so it runs beside the other steps. It acts on
179
179
  // the body's `closes #N` rather than the run's issue number: a pull request that closes nothing, or
@@ -193,7 +193,7 @@ async function issue_close_step(input: WrapupInput): Promise<void> {
193
193
  })
194
194
  }
195
195
 
196
- // **The steps after the merge are issued together** (joshuafolkken/kit#1446). The completion
196
+ // **The steps after the merge are issued together**. The completion
197
197
  // comment writes to the issue or the pull request, the auto-close reads the open epics, the label
198
198
  // removal reads and writes the issue's labels, and the merged-issue close reads and may close the
199
199
  // issue; none needs another's answer, and measured
@@ -45,7 +45,7 @@ function build_telegram_input(input: {
45
45
 
46
46
  // The sibling issue URL of a pull request: same repository, the number this run is closing. Read
47
47
  // through the shared parser rather than a second pattern here, so the two cannot disagree about what
48
- // a github.com URL looks like (joshuafolkken/kit#994).
48
+ // a github.com URL looks like.
49
49
  function build_issue_url(
50
50
  pr_url: string | undefined,
51
51
  issue_number: string | undefined,
@@ -65,7 +65,7 @@ interface FollowupInput {
65
65
  ai_review_ignore_reason: string | undefined
66
66
  is_skip_watch: boolean
67
67
  should_merge: boolean
68
- // The pull request merged before this run (joshuafolkken/kit#3023): only the tail is left to run.
68
+ // The pull request merged before this run: only the tail is left to run.
69
69
  is_merged?: boolean | undefined
70
70
  // When it merged — a completion report posted before it is the `prrun` stop's, not this tail's.
71
71
  merged_at?: string | undefined
@@ -77,9 +77,9 @@ function has_closes_keyword(body: string | undefined): boolean {
77
77
  return parse_closes_issue_number(body) !== undefined
78
78
  }
79
79
 
80
- // **Returns the number it warned about the absence of** (joshuafolkken/kit#1539). The issue number
81
- // used to reach the notification from the command line alone, so an invocation that omitted it threw
82
- // after the merge had already landed. This stage reads the pull request body anyway, and that body
80
+ // **Returns the number it warned about the absence of**. Taking the issue number from the command
81
+ // line alone would make an invocation that omitted it throw after the merge had already landed. This
82
+ // stage reads the pull request body anyway, and that body
83
83
  // carries the number in its `closes #N` keyword — so the read the warning already makes is what
84
84
  // recovers it, at no extra request.
85
85
  async function warn_if_missing_closes(branch_name: string): Promise<string | undefined> {
@@ -99,7 +99,7 @@ async function warn_if_missing_closes(branch_name: string): Promise<string | und
99
99
  }
100
100
 
101
101
  // **The one read of the four that can depend on another.** Without an issue number on the command
102
- // line it is the pull request body that names it (joshuafolkken/kit#1539), so the title read waits
102
+ // line it is the pull request body that names it, so the title read waits
103
103
  // for exactly that one and for nothing else. With a number in hand the `??` short-circuits and the
104
104
  // promise is never awaited at all, which is what lets this read go out in the same tick as the other
105
105
  // three.
@@ -119,7 +119,7 @@ interface RunContext {
119
119
  context: TelegramContext
120
120
  }
121
121
 
122
- // **The four reads in front of the check wait are issued together** (joshuafolkken/kit#1446). Not one
122
+ // **The four reads in front of the check wait are issued together**. Not one
123
123
  // of them is a wait on anything: the `closes #N` check reads the pull request body, and the
124
124
  // notification needs the repository name, the issue title and the pull request URL — four requests
125
125
  // that were sent one at a time for 5.5 of `followup`'s measured 45.8 seconds, purely because they
@@ -158,7 +158,7 @@ async function read_run_context(input: {
158
158
  }
159
159
  }
160
160
 
161
- // The pending count replaces the project version line (joshuafolkken/kit#1486): children no longer
161
+ // The pending count replaces the project version line: children no longer
162
162
  // bump, so the local `package.json` names the previous release rather than what this run ships.
163
163
  // A count that could not be read contributes no line at all, rather than a zero nobody measured.
164
164
  async function notify_completion(
@@ -170,7 +170,7 @@ async function notify_completion(
170
170
  const lines = pending_line === undefined ? skip_notes : [pending_line, ...skip_notes]
171
171
  const body = lines.join('\n')
172
172
 
173
- // **The tolerant send** (joshuafolkken/kit#1564): this runs on the way to the merge, so a Telegram
173
+ // **The tolerant send**: this runs on the way to the merge, so a Telegram
174
174
  // gateway timeout must not leave a reviewed, green pull request unmerged. The failure is reported
175
175
  // under `❗` and the run carries on.
176
176
  //
@@ -212,10 +212,10 @@ async function run_comment_scans(
212
212
  return [...comment_notes, ...ai_review_notes]
213
213
  }
214
214
 
215
- // **The managed config-file read runs first, ahead of the check wait** (joshuafolkken/kit#1578). It
215
+ // **The managed config-file read runs first, ahead of the check wait**. It
216
216
  // reads the branch diff and nothing else, so its answer is in hand before CI is waited on at all.
217
- // Since joshuafolkken/kit#1592 that answer stops nothing — it is a report — but the position is kept:
218
- // a read this cheap belongs beside the other things decided from the diff.
217
+ // That answer stops nothing — it is a report — but a read this cheap belongs beside the other things
218
+ // decided from the diff.
219
219
  //
220
220
  // **It laps no stage of its own.** The printed stage sequence is asserted as an exact list, and a
221
221
  // diff read this cheap is not what a measurement of `followup` is looking for; its cost lands inside
@@ -223,7 +223,7 @@ async function run_comment_scans(
223
223
  //
224
224
  // **The managed report comes back beside the notes as well as inside them**, because the two have
225
225
  // different destinations: every note reaches the completion notification, and this one alone also
226
- // reaches the completion report posted to the Issue (joshuafolkken/kit#1592). Returning it twice is
226
+ // reaches the completion report posted to the Issue. Returning it twice is
227
227
  // what lets `run_stages` hand each destination what belongs to it without re-deriving the answer.
228
228
  async function run_review_checks(
229
229
  input: FollowupInput,
@@ -249,7 +249,7 @@ async function run_review_checks(
249
249
  return { notes: [...managed, ...check_notes, ...scan_notes], managed }
250
250
  }
251
251
 
252
- // **A tail re-run after a merge does not report twice** (joshuafolkken/kit#3023): where the issue
252
+ // **A tail re-run after a merge does not report twice**: where the issue
253
253
  // already carries this pull request's completion report, the Telegram is skipped here and the comment
254
254
  // in the wrapup. Answers whether it was recorded, so the wrapup skips on the same read.
255
255
  async function notify_unless_recorded(
@@ -269,7 +269,7 @@ async function notify_unless_recorded(
269
269
  return is_recorded
270
270
  }
271
271
 
272
- // **Answers with the issue number the run actually used** (joshuafolkken/kit#1539), which is the one
272
+ // **Answers with the issue number the run actually used**, which is the one
273
273
  // the invocation named or, failing that, the one the pull request body closes. Everything downstream
274
274
  // takes it from here rather than from the input, so the Telegram context, the completion comment and
275
275
  // the epic close all name the same issue — and so the caller's own tail can record a run whose number
@@ -300,8 +300,8 @@ async function run_stages(input: FollowupInput, log: StageLog): Promise<string |
300
300
  return issue_number
301
301
  }
302
302
 
303
- // **The stage block is printed on the way out of every run, failed ones included**
304
- // (joshuafolkken/kit#1349). A `followup` that exits non-zero on an AI-review blocker or a red check is
303
+ // **The stage block is printed on the way out of every run, failed ones included**.
304
+ // A `followup` that exits non-zero on an AI-review blocker or a red check is
305
305
  // the invocation whose wait was longest, and one that printed nothing would leave the measurement
306
306
  // blind to exactly those. The `catch` marks the lap that was still running so the failing stage is
307
307
  // reported rather than dropped, and rethrows unchanged — a silent run is still a failed run.
@@ -316,6 +316,7 @@ async function run(input: FollowupInput): Promise<string | undefined> {
316
316
  throw error
317
317
  } finally {
318
318
  git_followup_stages.print_stages(log)
319
+ await git_followup_stages.record_ci_wait(log)
319
320
  }
320
321
  }
321
322