@joshuafolkken/kit 1.1035.0 → 1.1094.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 (605) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/verify-ui/SKILL.md +1 -1
  4. package/.claude/skills/workflow-commands/SKILL.md +21 -13
  5. package/.claude/skills/workflow-commands/background-commands.md +5 -4
  6. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -3
  7. package/.claude/skills/workflow-commands/backlogrun-lanes.md +9 -7
  8. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
  9. package/.claude/skills/workflow-commands/backlogrun-progress.md +31 -37
  10. package/.claude/skills/workflow-commands/backlogrun-steps.md +25 -25
  11. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  12. package/.claude/skills/workflow-commands/chain-rule.md +6 -4
  13. package/.claude/skills/workflow-commands/delegation.md +3 -3
  14. package/.claude/skills/workflow-commands/followup-reference.md +3 -3
  15. package/.claude/skills/workflow-commands/followup.md +7 -3
  16. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  17. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  18. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  19. package/.claude/skills/workflow-commands/issue-comments.md +2 -2
  20. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  21. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  23. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  24. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  25. package/.claude/skills/workflow-commands/observation-filing.md +44 -89
  26. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
  27. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  28. package/.claude/skills/workflow-commands/prrun.md +36 -0
  29. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  30. package/.claude/skills/workflow-commands/working-tree-hold.md +24 -4
  31. package/.codex/hooks.json +16 -20
  32. package/.github/actions/setup-pnpm/action.yml +93 -0
  33. package/.github/dependabot.yml +5 -1
  34. package/.github/workflows/auto-tag.yml +21 -0
  35. package/.github/workflows/ci.yml +26 -128
  36. package/.github/workflows/pr-classification.yml +5 -41
  37. package/.github/workflows/publish.yml +42 -48
  38. package/.github/workflows/sonar-qube.yml +37 -4
  39. package/AGENTS.md +12 -2
  40. package/CLAUDE.md +15 -16
  41. package/GEMINI.md +14 -2
  42. package/README.md +59 -18
  43. package/SECURITY.md +36 -6
  44. package/cspell/index.yaml +2 -1
  45. package/dist/CLAUDE.md +15 -16
  46. package/dist/config-merge/index.js +15 -3
  47. package/dist/hooks/batch-guard.js +4 -4
  48. package/dist/hooks/{chunk-Y27M6A7X.js → chunk-3C4YCCEF.js} +5 -13
  49. package/dist/hooks/{chunk-D67KVGGY.js → chunk-7ZPFAVR7.js} +17 -88
  50. package/dist/hooks/{chunk-HOYJU5RM.js → chunk-E54KGFEQ.js} +11 -4
  51. package/dist/hooks/{chunk-KG6PZD72.js → chunk-IL27YTPH.js} +2 -2
  52. package/dist/hooks/{chunk-GJT4BNVE.js → chunk-KHWHKJOM.js} +3 -3
  53. package/dist/hooks/{chunk-HU66PWWL.js → chunk-M2XDCUKD.js} +1076 -509
  54. package/dist/hooks/{chunk-GLBDBJOK.js → chunk-NKOG3XAV.js} +199 -304
  55. package/dist/hooks/{chunk-ZXNE6NY3.js → chunk-O4LL4HTI.js} +2 -7
  56. package/dist/hooks/{chunk-XPLP27WA.js → chunk-OIZUHPJI.js} +5 -27
  57. package/dist/hooks/{chunk-EIFCAJRB.js → chunk-UD24EAIL.js} +2546 -1636
  58. package/dist/hooks/codex-hook-adapter.js +10 -11
  59. package/dist/hooks/duplicate-read-guard.js +5 -5
  60. package/dist/hooks/format-edited.js +15 -34
  61. package/dist/hooks/inputs.json +279 -0
  62. package/dist/hooks/investigation-guard.js +5 -5
  63. package/dist/hooks/pretool-guard.js +23 -16
  64. package/dist/hooks/session-lang.js +0 -1
  65. package/dist/hooks/stop-guard.js +188 -509
  66. package/dist/josh.js +166 -225
  67. package/dist/managed-marker/index.js +2 -1
  68. package/dist/version/index.js +412 -64
  69. package/eslint/rules/promise.js +5 -0
  70. package/package.json +13 -8
  71. package/prompts/collaboration-workflow/file-edits.md +6 -53
  72. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  73. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  74. package/prompts/collaboration-workflow/overview.md +13 -1
  75. package/prompts/collaboration-workflow/report-format.md +1 -1
  76. package/prompts/collaboration-workflow/residency.md +4 -4
  77. package/prompts/collaboration-workflow/rule-delivery.md +5 -36
  78. package/prompts/collaboration-workflow/shell-body.md +7 -9
  79. package/prompts/collaboration-workflow/turn-batching.md +21 -37
  80. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  81. package/prompts/collaboration-workflow/wip-cap.md +36 -36
  82. package/prompts/collaboration-workflow.md +5 -8
  83. package/prompts/review-rubric.md +1 -1
  84. package/prompts/review.md +3 -3
  85. package/prompts/sonar-hotspot-handling.md +12 -4
  86. package/prompts/testing-guide.md +3 -3
  87. package/scripts/adopt/adopt-toolkits.ts +2 -2
  88. package/scripts/adopt/adopt.ts +0 -2
  89. package/scripts/agent/agent-argv.ts +0 -2
  90. package/scripts/agent/agent-diagnostics.ts +1 -1
  91. package/scripts/agent/agent-role-profile.ts +0 -7
  92. package/scripts/agent/claude-agent-argv.ts +0 -2
  93. package/scripts/agent/codex-agent-argv.ts +1 -1
  94. package/scripts/agent/codex-hooks.ts +92 -0
  95. package/scripts/agent/interactive-ask.ts +1 -1
  96. package/scripts/auto-ok/auto-ok-cli.ts +15 -25
  97. package/scripts/backlog/backlog-budget.ts +0 -2
  98. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  99. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  100. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  101. package/scripts/backlog/backlog-drive-named.ts +2 -1
  102. package/scripts/backlog/backlog-drive.ts +76 -16
  103. package/scripts/backlog/backlog-named.ts +0 -3
  104. package/scripts/backlog/backlog-next.ts +32 -22
  105. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  106. package/scripts/backlog/backlog-plan-cli.ts +6 -8
  107. package/scripts/backlog/backlog-plan.ts +1 -1
  108. package/scripts/backlog/backlog-pool.ts +34 -17
  109. package/scripts/backlog/backlog-rank.ts +106 -0
  110. package/scripts/backlog/backlog-ready.ts +19 -3
  111. package/scripts/backlog/backlog-scope.ts +1 -3
  112. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  113. package/scripts/backlog/backlog-stalled.ts +0 -1
  114. package/scripts/backlog/backlog-waves.ts +47 -31
  115. package/scripts/behavior/behavior-cli.ts +1 -1
  116. package/scripts/build/build-codex-hooks.ts +26 -0
  117. package/scripts/build/build-hooks.ts +92 -11
  118. package/scripts/build/hook-bundle-stamp.ts +111 -0
  119. package/scripts/cases/cases-cli.ts +1 -1
  120. package/scripts/cases/cases-logic.ts +1 -1
  121. package/scripts/ci/composite-actions.ts +30 -0
  122. package/scripts/ci/pr-classification.ts +3 -3
  123. package/scripts/claude/workflow-destination.ts +10 -1
  124. package/scripts/clone/clone-fingerprint.ts +0 -1
  125. package/scripts/clone/clone-scan-cli.ts +1 -1
  126. package/scripts/clone/clone-scan.ts +1 -1
  127. package/scripts/config-merge/json-format.ts +0 -1
  128. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  129. package/scripts/cost-runtime/codex-usage.ts +2 -9
  130. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  131. package/scripts/cost-runtime/cost-cli.ts +0 -3
  132. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  133. package/scripts/cost-runtime/cost-format.ts +0 -3
  134. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  135. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  136. package/scripts/delegation/delegation-cli.ts +1 -1
  137. package/scripts/delegation/delegation-policy.ts +11 -1
  138. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  139. package/scripts/delegation/fanout-cli.ts +1 -1
  140. package/scripts/delegation/fanout.ts +0 -2
  141. package/scripts/delegation/investigation-reads.ts +1 -164
  142. package/scripts/discovery/repo-map-logic.ts +0 -1
  143. package/scripts/discovery/repo-party-cli.ts +1 -1
  144. package/scripts/doctor/doctor-consumer.ts +4 -6
  145. package/scripts/doctor/doctor-logic.ts +0 -4
  146. package/scripts/doctor/doctor.ts +14 -9
  147. package/scripts/document/document-byte-budget.ts +8 -9
  148. package/scripts/document/document-byte-check.ts +0 -1
  149. package/scripts/document/document-read-cli.ts +0 -2
  150. package/scripts/document/document-section-cli.ts +1 -1
  151. package/scripts/document/document-section.ts +0 -3
  152. package/scripts/document/edit-files-cli.ts +0 -1
  153. package/scripts/document/entry-read-budget.ts +13 -4
  154. package/scripts/document/lane-child-read-set.ts +1 -6
  155. package/scripts/document/read-files-cli.ts +0 -4
  156. package/scripts/document/read-set-cli.ts +0 -2
  157. package/scripts/document/read-set-point-of-use.ts +1 -0
  158. package/scripts/document/read-set-pricing.ts +0 -1
  159. package/scripts/document/read-set-trim.ts +1 -1
  160. package/scripts/epic/epic-add.ts +1 -1
  161. package/scripts/epic/epic-audit-cli.ts +1 -4
  162. package/scripts/epic/epic-audit-orphans.ts +1 -3
  163. package/scripts/epic/epic-audit-rationale.ts +0 -1
  164. package/scripts/epic/epic-audit-report.ts +0 -2
  165. package/scripts/epic/epic-audit.ts +5 -4
  166. package/scripts/epic/epic-bundle-cli.ts +1 -1
  167. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  168. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  169. package/scripts/epic/epic-bundle.ts +0 -4
  170. package/scripts/epic/epic-busy.ts +4 -5
  171. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  172. package/scripts/epic/epic-classify.ts +2 -2
  173. package/scripts/epic/epic-cli-argv.ts +0 -1
  174. package/scripts/epic/epic-close-comment.ts +1 -1
  175. package/scripts/epic/epic-close.ts +5 -2
  176. package/scripts/epic/epic-cross-repo.ts +2 -4
  177. package/scripts/epic/epic-decision.ts +0 -1
  178. package/scripts/epic/epic-fetch.ts +2 -2
  179. package/scripts/epic/epic-index.ts +2 -3
  180. package/scripts/epic/epic-issue.ts +1 -15
  181. package/scripts/epic/epic-lane-offer.ts +20 -30
  182. package/scripts/epic/epic-nested.ts +1 -1
  183. package/scripts/epic/epic-next-read.ts +1 -3
  184. package/scripts/epic/epic-next-views.ts +0 -1
  185. package/scripts/epic/epic-next.ts +1 -10
  186. package/scripts/epic/epic-parse.ts +0 -1
  187. package/scripts/epic/epic-promote.ts +0 -9
  188. package/scripts/epic/epic-rank.ts +37 -0
  189. package/scripts/epic/epic-read.ts +1 -2
  190. package/scripts/epic/epic-reconcile.ts +1 -1
  191. package/scripts/epic/epic-reference.ts +1 -13
  192. package/scripts/epic/epic-relation-recheck.ts +1 -1
  193. package/scripts/epic/epic-relations.ts +1 -1
  194. package/scripts/epic/epic-remove.ts +1 -1
  195. package/scripts/epic/epic-report.ts +0 -1
  196. package/scripts/epic/epic-run.ts +2 -3
  197. package/scripts/epic/epic-shape.ts +1 -1
  198. package/scripts/epic/epic-solo-stale.ts +107 -0
  199. package/scripts/epic/epic-solo.ts +32 -30
  200. package/scripts/epic/epic-triage.ts +1 -1
  201. package/scripts/epic/epic-validate.ts +1 -1
  202. package/scripts/epic/epic.ts +1 -1
  203. package/scripts/exports/unused-members-cli.ts +53 -0
  204. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  205. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  206. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  207. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  208. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  209. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  210. package/scripts/followup/git-followup-merged.ts +112 -0
  211. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  212. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  213. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  214. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  215. package/scripts/gate/core-budget.ts +3 -9
  216. package/scripts/gate/gate-plan.ts +7 -4
  217. package/scripts/gate/gate-report.ts +0 -6
  218. package/scripts/gate/gate-tree.ts +1 -1
  219. package/scripts/gate/pre-commit-type-check.ts +0 -6
  220. package/scripts/gate/project-checks.ts +7 -8
  221. package/scripts/gate/scoped-green.ts +0 -1
  222. package/scripts/gate/type-check-step.ts +1 -1
  223. package/scripts/gate/verification-gate.ts +0 -2
  224. package/scripts/gh/fix-gh-packages.ts +15 -12
  225. package/scripts/gh/gh-spawn.ts +2 -2
  226. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  227. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  228. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  229. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  230. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  231. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  232. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  233. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  234. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  235. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  236. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  237. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  238. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  239. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  240. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  241. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  242. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  243. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  244. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  245. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  246. package/scripts/{git → gh}/git-pr.ts +3 -3
  247. package/scripts/git/changed-file-scope.ts +0 -1
  248. package/scripts/git/git-branch.ts +3 -6
  249. package/scripts/git/git-command.ts +1 -1
  250. package/scripts/git/git-commit.ts +1 -1
  251. package/scripts/git/git-common-directory.ts +80 -24
  252. package/scripts/git/git-error.ts +66 -9
  253. package/scripts/git/git-execa-error.ts +6 -1
  254. package/scripts/git/git-issue.ts +1 -1
  255. package/scripts/git/git-preflight.ts +24 -6
  256. package/scripts/git/git-prompt.ts +6 -31
  257. package/scripts/git/git-push-transport.ts +12 -69
  258. package/scripts/git/git-push.ts +1 -1
  259. package/scripts/git/git-spawn.ts +79 -3
  260. package/scripts/git/git-ssh-keepalive.ts +74 -0
  261. package/scripts/git/git-staging.ts +1 -0
  262. package/scripts/git/git-status.ts +1 -1
  263. package/scripts/git/git-workflow.ts +1 -1
  264. package/scripts/git/gone-branch.ts +4 -2
  265. package/scripts/git/listing-cutoff.ts +1 -1
  266. package/scripts/git/main-merge.ts +1 -1
  267. package/scripts/git/main-sync.ts +19 -1
  268. package/scripts/git/parse-json-array.ts +0 -3
  269. package/scripts/git/repository-lock.ts +16 -16
  270. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  271. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  272. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  273. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  274. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  275. package/scripts/hooks/edited-cspell.ts +1 -1
  276. package/scripts/hooks/format-edited-cli.ts +15 -0
  277. package/scripts/hooks/format-edited-file.ts +4 -9
  278. package/scripts/hooks/pre-push-unit.ts +0 -4
  279. package/scripts/hooks/pretool-guard-cli.ts +21 -0
  280. package/scripts/hooks/pretool-guard.ts +36 -19
  281. package/scripts/hooks/reserved-run.ts +1 -1
  282. package/scripts/hooks/step-zero-notice.ts +76 -0
  283. package/scripts/hooks/stop-guard.ts +47 -21
  284. package/scripts/init/claude-plugin-config.ts +4 -5
  285. package/scripts/init/hook-command-rewrite.ts +16 -8
  286. package/scripts/init/hook-launch.ts +41 -15
  287. package/scripts/init/init-basic.ts +2 -5
  288. package/scripts/init/init-logic.ts +7 -0
  289. package/scripts/init/init.ts +0 -3
  290. package/scripts/init/project-profile.ts +6 -11
  291. package/scripts/init/start-exec.ts +8 -2
  292. package/scripts/init/start-plan.ts +18 -5
  293. package/scripts/init/start-setup-pr.ts +52 -25
  294. package/scripts/init/start-steps.ts +42 -9
  295. package/scripts/init/start.ts +40 -10
  296. package/scripts/issue/behavior-change-lint.ts +0 -1
  297. package/scripts/issue/defect-rate-cli.ts +3 -3
  298. package/scripts/issue/defect-rate.ts +1 -2
  299. package/scripts/{git → issue}/git-next-issues.ts +37 -8
  300. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  301. package/scripts/issue/issue-cite-cli.ts +2 -6
  302. package/scripts/issue/issue-cite.ts +19 -3
  303. package/scripts/issue/issue-classification.ts +1 -9
  304. package/scripts/issue/issue-closing-pr.ts +4 -4
  305. package/scripts/issue/issue-comment-cli.ts +2 -2
  306. package/scripts/issue/issue-file-cli.ts +5 -5
  307. package/scripts/issue/issue-file.ts +2 -2
  308. package/scripts/issue/issue-fold-cli.ts +1 -1
  309. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  310. package/scripts/{git → issue}/issue-labels.ts +20 -0
  311. package/scripts/issue/issue-lint-cli.ts +1 -1
  312. package/scripts/issue/issue-merged.ts +2 -2
  313. package/scripts/issue/issue-rank.ts +89 -0
  314. package/scripts/issue/issue-read-cli.ts +8 -47
  315. package/scripts/issue/issue-read.ts +0 -2
  316. package/scripts/issue/issue-report-failures.ts +80 -0
  317. package/scripts/issue/issue-scout-cli.ts +1 -7
  318. package/scripts/issue/issue-scout-closed.ts +2 -2
  319. package/scripts/issue/issue-scout.ts +0 -2
  320. package/scripts/issue/issue-state-cli.ts +5 -46
  321. package/scripts/issue/issue-state.ts +1 -5
  322. package/scripts/issue/markdown-section.ts +1 -1
  323. package/scripts/issue/measure-rerun-cli.ts +1 -1
  324. package/scripts/issue/reproduction-measure.ts +1 -1
  325. package/scripts/josh/cli-body.ts +1 -1
  326. package/scripts/josh/file-map-stamp.ts +0 -3
  327. package/scripts/josh/josh-command-map.ts +2 -102
  328. package/scripts/josh/josh-commands-ai.ts +9 -102
  329. package/scripts/josh/josh-commands-backlog.ts +5 -1
  330. package/scripts/josh/josh-commands-development.ts +10 -3
  331. package/scripts/josh/josh-commands-issue.ts +2 -2
  332. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  333. package/scripts/josh/josh-commands-project.ts +7 -1
  334. package/scripts/josh/josh-commands-run.ts +114 -0
  335. package/scripts/josh/josh-commands-versioning.ts +8 -0
  336. package/scripts/josh/josh-commands-workflow.ts +2 -2
  337. package/scripts/josh/path-decision.ts +0 -3
  338. package/scripts/josh/process-owner.ts +16 -0
  339. package/scripts/josh/session-language-cli.ts +0 -1
  340. package/scripts/lane/lane-await.ts +3 -6
  341. package/scripts/lane/lane-capacity.ts +6 -3
  342. package/scripts/lane/lane-child-invocation.ts +20 -7
  343. package/scripts/lane/lane-child-marker.ts +16 -2
  344. package/scripts/lane/lane-cli.ts +33 -18
  345. package/scripts/lane/lane-close.ts +1 -3
  346. package/scripts/lane/lane-dispatch.ts +3 -4
  347. package/scripts/lane/lane-environment.ts +0 -9
  348. package/scripts/lane/lane-handoff.ts +38 -0
  349. package/scripts/lane/lane-launch-cli.ts +21 -11
  350. package/scripts/lane/lane-open.ts +0 -3
  351. package/scripts/lane/lane-output.ts +0 -1
  352. package/scripts/lane/lane-registry.ts +9 -0
  353. package/scripts/lane/lane-report.ts +10 -4
  354. package/scripts/lane/openai-lane-ship.ts +2 -0
  355. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  356. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  357. package/scripts/lane/openai-review-broker.ts +3 -0
  358. package/scripts/lib/bounded-pool.ts +1 -0
  359. package/scripts/lib/json-value.ts +5 -4
  360. package/scripts/lib/poll.ts +3 -1
  361. package/scripts/lib/timed-fetch.ts +15 -0
  362. package/scripts/lib/timeouts.ts +13 -0
  363. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  364. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  365. package/scripts/lines/lines-command.ts +0 -1
  366. package/scripts/lint/lint-related-scope.ts +0 -1
  367. package/scripts/lint/lint-related.ts +1 -1
  368. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  369. package/scripts/{git → notify}/telegram-test.ts +4 -4
  370. package/scripts/observations/observation-ledger-home.ts +0 -1
  371. package/scripts/observations/observation-ledger-line.ts +0 -1
  372. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  373. package/scripts/observations/observations-flush-landing.ts +3 -3
  374. package/scripts/observations/observations-flush.ts +2 -2
  375. package/scripts/overrides/lockfile-overrides.ts +1 -1
  376. package/scripts/overrides/overrides-logic.ts +1 -1
  377. package/scripts/package/package-scout-cli.ts +2 -7
  378. package/scripts/package/package-scout.ts +0 -2
  379. package/scripts/propagate/propagate-git-failure.ts +0 -1
  380. package/scripts/propagate/propagate-git.ts +0 -2
  381. package/scripts/propagate/propagate-plan.ts +185 -0
  382. package/scripts/propagate/propagate-publish.ts +2 -3
  383. package/scripts/propagate/propagate-run.ts +5 -3
  384. package/scripts/propagate/propagate-steps.ts +19 -6
  385. package/scripts/propagate/propagate-targets.ts +13 -6
  386. package/scripts/propagate/propagate.ts +60 -46
  387. package/scripts/refactor/import-graph.ts +0 -1
  388. package/scripts/refactor/refactor-lint.ts +0 -2
  389. package/scripts/refactor/refactor-scan.ts +0 -1
  390. package/scripts/refactor/refactor-targets.ts +0 -1
  391. package/scripts/registry-migration/migrate-logic.ts +1 -2
  392. package/scripts/registry-migration/migrate.ts +19 -9
  393. package/scripts/release/github-release-cli.ts +8 -6
  394. package/scripts/release/github-release-environment.ts +46 -0
  395. package/scripts/release/github-release.ts +151 -94
  396. package/scripts/release/release-history.ts +0 -1
  397. package/scripts/release/release-plan.ts +0 -1
  398. package/scripts/release/release-publish.ts +2 -3
  399. package/scripts/release/release-scope-cli.ts +1 -2
  400. package/scripts/release/release-tag.ts +2 -4
  401. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  402. package/scripts/repo/repo-setting.ts +1 -1
  403. package/scripts/repo/repository-labels.ts +3 -3
  404. package/scripts/repo/required-checks-logic.ts +206 -0
  405. package/scripts/repo/required-checks-report.ts +71 -0
  406. package/scripts/repo/ruleset-check-cli.ts +53 -0
  407. package/scripts/repo/ruleset-check.ts +147 -0
  408. package/scripts/report/report-lint-cli.ts +0 -4
  409. package/scripts/review/disposition-cli.ts +1 -1
  410. package/scripts/review/live-evidence.ts +1 -1
  411. package/scripts/review/review-attest-cli.ts +0 -6
  412. package/scripts/review/review-attest.ts +48 -16
  413. package/scripts/review/review-brief-cli.ts +72 -8
  414. package/scripts/review/review-brief.ts +67 -9
  415. package/scripts/review/review-diff-parts.ts +89 -0
  416. package/scripts/review/review-diff-write.ts +97 -0
  417. package/scripts/review/review-finding-ledger.ts +0 -1
  418. package/scripts/review/review-record-cli.ts +1 -1
  419. package/scripts/review/review-record.ts +0 -1
  420. package/scripts/review/review-round2-cli.ts +1 -1
  421. package/scripts/review/review-stamps.ts +6 -2
  422. package/scripts/review/review-tree.ts +14 -2
  423. package/scripts/rules/decision-oracle-stage.ts +18 -0
  424. package/scripts/rules/decision-oracle.ts +10 -7
  425. package/scripts/rules/delivered-rules.ts +9 -1
  426. package/scripts/rules/destructive-command.ts +119 -0
  427. package/scripts/rules/direct-filing.ts +1 -1
  428. package/scripts/rules/file-body.ts +0 -3
  429. package/scripts/rules/filing-cap.ts +0 -2
  430. package/scripts/rules/gh-api.ts +7 -2
  431. package/scripts/rules/git-argv.ts +18 -7
  432. package/scripts/rules/git-force.ts +0 -2
  433. package/scripts/rules/implementation-cut.ts +1 -2
  434. package/scripts/rules/index-guard.ts +71 -0
  435. package/scripts/rules/issue-citation.ts +50 -25
  436. package/scripts/rules/issue-fold.ts +1 -2
  437. package/scripts/rules/lane-background.ts +15 -7
  438. package/scripts/rules/lane-carry-conflict.ts +1 -2
  439. package/scripts/rules/lane-park.ts +14 -8
  440. package/scripts/rules/last-prompt.ts +1 -0
  441. package/scripts/rules/oracle-consulted.ts +1 -1
  442. package/scripts/rules/oracle-firing.ts +1 -0
  443. package/scripts/rules/oracle-list-cli.ts +0 -3
  444. package/scripts/rules/permission-guards.ts +14 -0
  445. package/scripts/rules/pre-gate-cut.ts +2 -2
  446. package/scripts/rules/protected-files.ts +74 -0
  447. package/scripts/rules/reply-language.ts +1 -1
  448. package/scripts/rules/rule-body-guard.ts +0 -3
  449. package/scripts/rules/rule-value-cli.ts +0 -1
  450. package/scripts/rules/shell-body-trigger.ts +0 -1
  451. package/scripts/rules/shell-segments.ts +0 -1
  452. package/scripts/rules/stop-rules.ts +13 -5
  453. package/scripts/rules/tail-commands.ts +1 -1
  454. package/scripts/rules/test-declared-commit.ts +1 -1
  455. package/scripts/rules/third-party-write.ts +0 -1
  456. package/scripts/rules/worktree-guard.ts +26 -9
  457. package/scripts/run/run-carry-cli.ts +0 -2
  458. package/scripts/run/run-carry-stash.ts +2 -2
  459. package/scripts/run/run-carry-streak.ts +1 -1
  460. package/scripts/run/run-cut-cli.ts +0 -7
  461. package/scripts/run/run-cut.ts +8 -54
  462. package/scripts/run/run-ending-cli.ts +1 -1
  463. package/scripts/run/run-ending.ts +1 -4
  464. package/scripts/run/run-entry-cli.ts +101 -24
  465. package/scripts/run/run-entry.ts +0 -1
  466. package/scripts/run/run-event-cli.ts +0 -2
  467. package/scripts/run/run-event-follow.ts +1 -0
  468. package/scripts/run/run-event-render.ts +1 -1
  469. package/scripts/run/run-event-scope.ts +53 -4
  470. package/scripts/run/run-event-stream.ts +0 -3
  471. package/scripts/run/run-event-watch.ts +1 -0
  472. package/scripts/run/run-halfrun-resume.ts +20 -7
  473. package/scripts/run/run-headless.ts +24 -8
  474. package/scripts/run/run-hold-cli.ts +33 -10
  475. package/scripts/run/run-hold.ts +25 -5
  476. package/scripts/run/run-issue-number.ts +1 -1
  477. package/scripts/run/run-liveness-cli.ts +1 -1
  478. package/scripts/run/run-liveness.ts +2 -3
  479. package/scripts/run/run-merge-cli.ts +5 -13
  480. package/scripts/run/run-merge-steps.ts +5 -5
  481. package/scripts/run/run-merge.ts +1 -1
  482. package/scripts/run/run-next-cli.ts +1 -1
  483. package/scripts/run/run-parent-cut-hook.ts +143 -0
  484. package/scripts/run/run-preflight.ts +2 -9
  485. package/scripts/run/run-prep-cli.ts +2 -2
  486. package/scripts/run/run-prep-locate.ts +1 -1
  487. package/scripts/run/run-progress-cli.ts +4 -7
  488. package/scripts/run/run-progress-clock.ts +6 -34
  489. package/scripts/run/run-progress-config.ts +0 -4
  490. package/scripts/run/run-progress-read.ts +3 -3
  491. package/scripts/run/run-progress.ts +22 -10
  492. package/scripts/run/run-prrun-resume.ts +117 -0
  493. package/scripts/run/run-report-cli.ts +1 -2
  494. package/scripts/run/run-report.ts +0 -1
  495. package/scripts/run/run-retrospective.ts +1 -1
  496. package/scripts/run/run-review-cli.ts +0 -3
  497. package/scripts/run/run-review-steps.ts +2 -0
  498. package/scripts/run/run-review.ts +0 -2
  499. package/scripts/run/run-ship-cli.ts +27 -77
  500. package/scripts/run/run-ship-detach.ts +1 -0
  501. package/scripts/run/run-ship-next.ts +106 -0
  502. package/scripts/run/run-ship-preflight.ts +87 -0
  503. package/scripts/run/run-ship-return.ts +8 -3
  504. package/scripts/run/run-ship-review-steps.ts +23 -30
  505. package/scripts/run/run-ship-review.ts +20 -0
  506. package/scripts/run/run-ship-scoped.ts +45 -0
  507. package/scripts/run/run-ship-stage.ts +5 -1
  508. package/scripts/run/run-ship-steps.ts +105 -0
  509. package/scripts/run/run-ship.ts +2 -1
  510. package/scripts/run/run-stage-read.ts +62 -0
  511. package/scripts/run/run-stage.ts +160 -0
  512. package/scripts/run/run-status-cli.ts +1 -1
  513. package/scripts/run/run-step-cli.ts +21 -14
  514. package/scripts/run/run-step.ts +1 -1
  515. package/scripts/run/run-stop-notify.ts +1 -3
  516. package/scripts/run/run-stranded-cli.ts +0 -4
  517. package/scripts/run/run-stranded-detect.ts +2 -2
  518. package/scripts/run/run-tail-cli.ts +17 -11
  519. package/scripts/run/run-tail.ts +2 -0
  520. package/scripts/run/run-tidy-lanes.ts +2 -1
  521. package/scripts/run/run-tidy-stashes.ts +12 -12
  522. package/scripts/run/run-wake-cli.ts +4 -5
  523. package/scripts/run/run-wake-describe.ts +19 -1
  524. package/scripts/run/run-wake-loop.ts +2 -2
  525. package/scripts/run/run-wake.ts +2 -4
  526. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  527. package/scripts/run/run-watcher-guard.ts +9 -7
  528. package/scripts/run/run-watcher-hook.ts +1 -1
  529. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  530. package/scripts/safe-chain/project-config.ts +1 -1
  531. package/scripts/security/security-audit-provision-logic.ts +0 -1
  532. package/scripts/security/security-audit-provision.ts +3 -2
  533. package/scripts/security/security-audit.ts +0 -1
  534. package/scripts/security/security-updates-logic.ts +0 -1
  535. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  536. package/scripts/sonar/sonar-hotspots.ts +0 -1
  537. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  538. package/scripts/sonar/sonar-new-code.ts +79 -0
  539. package/scripts/sonar/sonar-project.ts +97 -0
  540. package/scripts/split/split-assess-cli.ts +1 -1
  541. package/scripts/split/split-assess.ts +2 -5
  542. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  543. package/scripts/sync/skill-migration.ts +0 -1
  544. package/scripts/sync/sync-hook-safety.ts +2 -3
  545. package/scripts/sync/sync.ts +1 -8
  546. package/scripts/sync/template-source-logic.ts +0 -1
  547. package/scripts/sync/workflow-pin-logic.ts +16 -28
  548. package/scripts/test/test-declared-logic.ts +0 -1
  549. package/scripts/test/test-declared.ts +0 -2
  550. package/scripts/test/test-red-commit.ts +2 -2
  551. package/scripts/test/test-red.ts +14 -7
  552. package/scripts/test/test-type-logic.ts +1 -1
  553. package/scripts/test/unit-worker-share.ts +7 -16
  554. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  555. package/scripts/time-runtime/time-bundle-call.ts +2 -3
  556. package/scripts/time-runtime/time-bundles.ts +0 -4
  557. package/scripts/time-runtime/time-density-hook.ts +0 -2
  558. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  559. package/scripts/time-runtime/time-format.ts +0 -73
  560. package/scripts/time-runtime/time-round-trips.ts +0 -4
  561. package/scripts/time-runtime/time-single-check.ts +1 -1
  562. package/scripts/time-runtime/time-spans.ts +1 -1
  563. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  564. package/scripts/ui/ui-routes-cli.ts +0 -5
  565. package/scripts/ui/ui-routes.ts +0 -5
  566. package/scripts/version/effective-upstream.ts +2 -2
  567. package/scripts/version/latest-corepack.ts +7 -9
  568. package/scripts/version/latest-scope-cli.ts +0 -2
  569. package/scripts/version/latest-update.ts +0 -2
  570. package/scripts/version/npm-registry.ts +97 -0
  571. package/scripts/version/publishable-range-check.ts +1 -1
  572. package/scripts/version/release-hold.ts +0 -4
  573. package/scripts/version/running-binary.ts +2 -2
  574. package/scripts/version/version-check-logic.ts +0 -2
  575. package/scripts/version/version-commands.ts +5 -4
  576. package/scripts/version/version-remote.ts +28 -14
  577. package/scripts/version/version-targets.ts +4 -4
  578. package/templates/sonar-project.properties +28 -1
  579. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  580. package/templates/workflows/github-release.yml +81 -0
  581. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  582. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  583. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  584. package/scripts/init/plugin-install-hint.ts +0 -47
  585. package/scripts/version/parse-json.ts +0 -13
  586. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  587. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  588. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  589. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  590. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  591. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  592. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  593. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  594. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  595. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  596. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  597. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  598. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  599. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  600. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  601. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  602. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  603. /package/scripts/{git → lib}/git-animation.ts +0 -0
  604. /package/scripts/{git → notify}/git-notify.ts +0 -0
  605. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -3,8 +3,8 @@ import { homedir, tmpdir } from 'node:os'
3
3
  import path from 'node:path'
4
4
  import { setTimeout as sleep } from 'node:timers/promises'
5
5
  import { agent_event, type AgentEventState } from '#scripts/agent/agent-event'
6
- import { git_gh_issue_read } from '#scripts/git/git-gh-issue-read'
7
- import { ALREADY_DONE_LABEL, NEEDS_DECISION_LABEL } from '#scripts/git/issue-labels'
6
+ import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
7
+ import { ALREADY_DONE_LABEL, NEEDS_DECISION_LABEL } from '#scripts/issue/issue-labels'
8
8
  import { issue_state } from '#scripts/issue/issue-state'
9
9
  import { PLATFORM_TEMP_ROOT } from '#scripts/josh/platform-temporary'
10
10
  import { run_hold } from './run-hold'
@@ -401,7 +401,6 @@ const run_liveness = {
401
401
  decide,
402
402
  describe_agent_state,
403
403
  read_child_settled,
404
- read_agent_state,
405
404
  read_output_frozen,
406
405
  sample_output,
407
406
  to_safe_path,
@@ -5,6 +5,7 @@ import { api_outage } from '#scripts/agent/api-outage'
5
5
  import { CONTEXT_CUT_THRESHOLD } from '#scripts/cost-runtime/context-cut-threshold'
6
6
  import { issue_closing_pr } from '#scripts/issue/issue-closing-pr'
7
7
  import { issue_state_cli } from '#scripts/issue/issue-state-cli'
8
+ import { lane_handoff } from '#scripts/lane/lane-handoff'
8
9
  import { run_carry, type CarryOwner, type RunCarry } from './run-carry'
9
10
  import { run_ending } from './run-ending'
10
11
  import { run_event_stream } from './run-event-stream'
@@ -12,8 +13,6 @@ import { run_event_stream_emit } from './run-event-stream-emit'
12
13
  import { run_issue_number } from './run-issue-number'
13
14
  import { run_merge, type ChildOutcome, type EndingSignals } from './run-merge'
14
15
  import { run_merge_steps, type MergeContext } from './run-merge-steps'
15
- import { run_ship_detach } from './run-ship-detach'
16
- import { run_ship_probe } from './run-ship-probe'
17
16
 
18
17
  // `josh run:merge <N>` — one composite command for a `backlogrun` merge event (joshuafolkken/kit#2024).
19
18
  // The parent's context is the largest and its per-turn cost the highest, and the event was two turns:
@@ -316,7 +315,10 @@ async function on_cut(ctx: MergeContext): Promise<MergeVerdict> {
316
315
 
317
316
  // A child that parked itself: nothing is counted, but the park is written to the stream as a failed
318
317
  // child's is, so a reader restoring the run from its events sees the child settled (joshuafolkken/kit#2508).
318
+ // Its `in-progress` is dropped as a failed child's is: left on, it outlived the `needs-decision` a
319
+ // person later lifted, and a `run:solo` child then held the whole backlog (joshuafolkken/kit#3017).
319
320
  async function on_parked(ctx: MergeContext): Promise<MergeVerdict> {
321
+ await run_merge_steps.remove_in_progress(ctx.child)
320
322
  await run_event_stream_emit.emit(run_event_stream.EVENT_KIND.PARK, `#${ctx.child} parked`)
321
323
 
322
324
  return emit(await run_merge_steps.ask_next(ctx), SUCCESS_EXIT_CODE)
@@ -355,18 +357,10 @@ const HANDLERS: Readonly<Record<ChildOutcome, (ctx: MergeContext) => Promise<Mer
355
357
  shipping: on_shipping,
356
358
  }
357
359
 
358
- async function is_ship_running(child: string): Promise<boolean> {
359
- const repository = await run_ship_probe.repository_directory()
360
-
361
- return (
362
- repository !== undefined && run_ship_detach.read_result(repository, child)?.result === 'running'
363
- )
364
- }
365
-
366
360
  // The whole merge event for one returned child, in-process: read its state, classify it, and run the
367
361
  // handler. The CLI prints the token; `backlog:drive` branches on the outcome (joshuafolkken/kit#2508).
368
362
  async function merge_child(ctx: MergeContext): Promise<MergeResult> {
369
- if (await is_ship_running(ctx.child)) {
363
+ if (lane_handoff.is_ship_running(ctx.child, process.cwd())) {
370
364
  return { outcome: 'shipping', ...(await on_shipping()) }
371
365
  }
372
366
 
@@ -405,8 +399,6 @@ const run_merge_cli = {
405
399
  RESUMED_TOKEN,
406
400
  RETRY_TOKEN,
407
401
  STOP_TOKEN,
408
- USAGE,
409
- main,
410
402
  merge_child,
411
403
  parse,
412
404
  run,
@@ -1,9 +1,9 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import path from 'node:path'
3
- import { git_followup_issue_close } from '#scripts/git/git-followup-issue-close'
4
- import { git_gh_issue_write } from '#scripts/git/git-gh-issue-write'
5
- import { git_stash } from '#scripts/git/git-stash'
6
- import { IN_PROGRESS_LABEL, NEEDS_DECISION_LABEL } from '#scripts/git/issue-labels'
3
+ import { git_followup_issue_close } from '#scripts/followup/git-followup-issue-close'
4
+ import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
5
+ import { git_stash } from '#scripts/git/stash/git-stash'
6
+ import { IN_PROGRESS_LABEL, NEEDS_DECISION_LABEL } from '#scripts/issue/issue-labels'
7
7
  import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
8
8
  import { lane_close } from '#scripts/lane/lane-close'
9
9
  import { lane_reap } from '#scripts/lane/lane-reap'
@@ -347,7 +347,6 @@ async function ask_next(ctx: MergeContext): Promise<string> {
347
347
 
348
348
  const run_merge_steps = {
349
349
  CUT_RELAUNCH_CAUSE,
350
- apply_carry,
351
350
  ask_next,
352
351
  do_failed,
353
352
  do_merged,
@@ -355,6 +354,7 @@ const run_merge_steps = {
355
354
  has_resumable_cut,
356
355
  is_over_budget,
357
356
  refused_carry,
357
+ remove_in_progress,
358
358
  resume_cut,
359
359
  }
360
360
 
@@ -3,7 +3,7 @@ import {
3
3
  EPIC_LABEL,
4
4
  has_label_name,
5
5
  NEEDS_DECISION_LABEL,
6
- } from '#scripts/git/issue-labels'
6
+ } from '#scripts/issue/issue-labels'
7
7
  import type { IssueState } from '#scripts/issue/issue-state'
8
8
  import type { CarryChange, RunCarry } from './run-carry'
9
9
 
@@ -41,7 +41,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
41
41
  process.exitCode = await run(argv)
42
42
  }
43
43
 
44
- const run_next_cli = { USAGE, main, run }
44
+ const run_next_cli = { run }
45
45
 
46
46
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
47
47
 
@@ -0,0 +1,143 @@
1
+ import { CONTEXT_CUT_THRESHOLD } from '#scripts/cost-runtime/context-cut-threshold'
2
+ import { cost_cli, type CostVerdict } from '#scripts/cost-runtime/cost-cli'
3
+ import { cost_format } from '#scripts/cost-runtime/cost-format'
4
+ import { cost_verdict } from '#scripts/cost-runtime/cost-verdict'
5
+ import { hook_decision } from '#scripts/josh/hook-decision'
6
+ import { implementation_cut_verdict } from '#scripts/rules/implementation-cut-verdict'
7
+ import { run_carry, type RunCarry } from './run-carry'
8
+ import { run_headless } from './run-headless'
9
+ import { run_watcher_hook } from './run-watcher-hook'
10
+
11
+ // The `backlogrun` parent's hand-off, delivered at the call it binds on (joshuafolkken/kit#2947).
12
+ //
13
+ // **The parent's hand-off was asked only at a merge, and the context grew between merges.** The
14
+ // orchestrator never implements, yet on 2026-10-02 parent 259fb6d5 sent 111 of its 170 requests past
15
+ // the shared threshold, peaking at 207,081 tokens: `pnpm josh cost --cut` is read after each child's
16
+ // merge (`backlogrun-progress.md` → "The hand-off"), and a long wait or a lane-failure investigation
17
+ // between two merges is exactly where it went unread. This is the lesson `implementation-cut.ts` records
18
+ // for a lane child, one session up — a check carried as a step is taken late, a `PreToolUse` refusal is
19
+ // taken at the next call.
20
+ //
21
+ // **The same statistic and the same threshold, never a second measurement.** The verdict is
22
+ // `cost_cli.session_verdict` — what `pnpm josh cost --cut` prints — read through the implementation cut's
23
+ // short reuse window so a burst of calls is priced once.
24
+ //
25
+ // **It is async and composed after the synchronous guards, like the watcher guard.** Telling the parent
26
+ // apart reads the carry record through `run_headless.driving_carry`, which is asynchronous; reusing it is
27
+ // what keeps a second, synchronous spelling of the parent test from existing.
28
+
29
+ const SWITCH_ENV_KEY = 'JOSH_PARENT_CUT_GUARD'
30
+ const STAMP_PREFIX = 'josh-parent-cut-guard-'
31
+
32
+ // **One refusal, then a quiet window long enough to finish the hand-off in.** The hand-off is several
33
+ // calls — `lane:list`, `lane:output`, `run:carry --cut`, `run:wake`, the progress comment — and a guard
34
+ // refusing each of them would wedge the very procedure it asks for. A parent that could not cut (a lane
35
+ // nobody can poll) is asked again once the window has passed, which is the "next opportunity" the merge
36
+ // seam used to be.
37
+ const QUIET_WINDOW_MS = 600_000
38
+
39
+ // What the decision has to know about the world, passed in so it is testable without a carry record or
40
+ // a session transcript on disk.
41
+ interface ParentCutState {
42
+ carry: () => Promise<RunCarry | undefined>
43
+ verdict: () => CostVerdict
44
+ }
45
+
46
+ function current_state(): ParentCutState {
47
+ return {
48
+ carry: async (): Promise<RunCarry | undefined> => await run_headless.driving_carry(),
49
+ verdict: (): CostVerdict =>
50
+ implementation_cut_verdict.reused_verdict(() => cost_cli.session_verdict()),
51
+ }
52
+ }
53
+
54
+ const THRESHOLD_TEXT = `${cost_format.format_tokens(CONTEXT_CUT_THRESHOLD)}-token`
55
+
56
+ const PARENT_CUT_REASON =
57
+ '⛔ backlogrun parent hand-off: this session drives a `backlogrun` (it owns the live carry record) and ' +
58
+ `its recent-context cost has crossed the shared ${THRESHOLD_TEXT} threshold between merges, so every ` +
59
+ 'later request re-reads the accumulated context (joshuafolkken/kit#2947). Take the hand-off now rather ' +
60
+ 'than at the next merge: follow `.claude/skills/workflow-commands/backlogrun-progress.md` → "The ' +
61
+ 'hand-off" from its `over` branch — open no new lane and take no new child, read `pnpm josh lane:list`, ' +
62
+ 'make sure every lane in flight records an output path, then run `pnpm josh run:carry --cut --owner ' +
63
+ '"$PPID"` and, unless it answers `capped`, `pnpm josh run:wake`, post the progress comment and end the ' +
64
+ 'turn. A lane nobody can poll means the cut does not happen; carry on and this asks again later. ' +
65
+ 'Reissue this call when the hand-off is done or cannot be taken — the guard stays quiet for a while ' +
66
+ 'after it refuses, so the hand-off calls themselves are not refused.'
67
+
68
+ // Neither an uncapped parent's own record nor a measured `over` is optional: a capped record has no cut
69
+ // left to take (`run:carry --cut` answers `capped`), and an unmeasurable session is left alone here —
70
+ // refusing every call of a session that cannot be priced would wedge it, while the merge-seam check
71
+ // still takes `over`'s branch for it.
72
+ async function is_due(state: ParentCutState): Promise<boolean> {
73
+ const carry = await state.carry()
74
+
75
+ if (carry === undefined || run_carry.is_at_cut_cap(carry)) return false
76
+
77
+ return state.verdict() === cost_verdict.OVER_VERDICT
78
+ }
79
+
80
+ function is_quiet(target: string, now_ms: number): boolean {
81
+ const last_ms = hook_decision.create_refusal_stamp(STAMP_PREFIX).last_ms(target)
82
+
83
+ return last_ms !== hook_decision.NEVER_MS && now_ms - last_ms < QUIET_WINDOW_MS
84
+ }
85
+
86
+ // The quiet window is read before the carry record and the transcript price, so a refused parent's
87
+ // following calls cost one small file read each.
88
+ async function refusal_for(
89
+ transcript: string,
90
+ now_ms: number,
91
+ state: ParentCutState,
92
+ ): Promise<string | undefined> {
93
+ const stamp = hook_decision.create_refusal_stamp(STAMP_PREFIX)
94
+ const target = stamp.path(transcript)
95
+
96
+ if (is_quiet(target, now_ms) || !(await is_due(state))) return undefined
97
+
98
+ return stamp.record(target, now_ms) ? PARENT_CUT_REASON : undefined
99
+ }
100
+
101
+ // A delegated unit's call names the *parent's* transcript and runs under the parent's process, so the
102
+ // carry record reads as owned here; only `agent_id` tells it apart (`hook-decision.ts`). Refusing it
103
+ // would hand the unit a hand-off it cannot take and spend the parent's quiet window on it.
104
+ function is_unit_call(raw_payload: string): boolean {
105
+ try {
106
+ return (hook_decision.parse_hook_payload(raw_payload)?.agent_id ?? '') !== ''
107
+ } catch {
108
+ return false
109
+ }
110
+ }
111
+
112
+ function is_exempt(raw_payload: string): boolean {
113
+ return !hook_decision.is_switch_enabled(SWITCH_ENV_KEY) || is_unit_call(raw_payload)
114
+ }
115
+
116
+ /**
117
+ * The deny reason for a call a `backlogrun` parent makes past the shared threshold, or `undefined` when
118
+ * the call proceeds — a lane child, a delegated unit, a person's session, a handed-off or capped
119
+ * record, an `under` or unmeasurable verdict, or a call inside the quiet window after a refusal.
120
+ */
121
+ async function parent_cut_reason(
122
+ raw_payload: string,
123
+ now_ms: number = Date.now(),
124
+ state: ParentCutState = current_state(),
125
+ ): Promise<string | undefined> {
126
+ if (is_exempt(raw_payload)) return undefined
127
+
128
+ const transcript = run_watcher_hook.transcript_of(raw_payload)
129
+
130
+ if (transcript === undefined) return undefined
131
+
132
+ return await refusal_for(transcript, now_ms, state)
133
+ }
134
+
135
+ const run_parent_cut_hook = {
136
+ PARENT_CUT_REASON,
137
+ QUIET_WINDOW_MS,
138
+ SWITCH_ENV_KEY,
139
+ parent_cut_reason,
140
+ }
141
+
142
+ export type { ParentCutState }
143
+ export { run_parent_cut_hook }
@@ -1,5 +1,5 @@
1
+ import { git_gh_pr_read } from '#scripts/gh/git-gh-pr-read'
1
2
  import { git_command } from '#scripts/git/git-command'
2
- import { git_gh_pr_read } from '#scripts/git/git-gh-pr-read'
3
3
  import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
4
4
  import { z } from 'zod'
5
5
  import { run_hold } from './run-hold'
@@ -89,7 +89,7 @@ const STASH_LABEL_PREFIX = 'run:hold reclaimed before #'
89
89
  // so the shape it may take is pinned beside the interpolation rather than only in the CLI that
90
90
  // happens to be today's single caller. `run:liveness` interpolates it the same way, so the pattern
91
91
  // and the refusal live in one module both read (joshuafolkken/kit#1485).
92
- const { ISSUE_NUMBER_PATTERN, require_issue_number } = run_issue_number
92
+ const { require_issue_number } = run_issue_number
93
93
  const UNREADABLE_PR_MESSAGE = 'The pull request could not be read for branch '
94
94
 
95
95
  function needs_reclaim(tree: TreeState): boolean {
@@ -385,15 +385,8 @@ async function check(issue: string): Promise<PreflightDecision> {
385
385
  }
386
386
 
387
387
  const run_preflight = {
388
- CLEAN_ADVICE,
389
- CLEAN_REASON,
390
388
  CLEAN_VERDICT,
391
- ISSUE_NUMBER_PATTERN,
392
- PARK_ADVICE,
393
- PARK_VERDICT,
394
- RECLAIM_VERDICT,
395
389
  RESUME_ADVICE,
396
- RESUME_VERDICT,
397
390
  MERGED_PR,
398
391
  STASH_LABEL_PREFIX,
399
392
  check,
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
- import { git_stash } from '#scripts/git/git-stash'
3
+ import { git_stash } from '#scripts/git/stash/git-stash'
4
4
  import { issue_read_cli, type BlockRead } from '#scripts/issue/issue-read-cli'
5
5
  import { issue_state_cli, type StateRead } from '#scripts/issue/issue-state-cli'
6
6
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
@@ -150,7 +150,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
150
150
  // `gather` and `to_parts` are exported so `run:next` reads the same state from the same three reads
151
151
  // rather than growing a second copy of the gather (joshuafolkken/kit#2188) — `run:next` is the
152
152
  // consumer of `run:prep` the epic #2166 wanted.
153
- const run_prep_cli = { USAGE, gather, main, parse_number, run, to_parts }
153
+ const run_prep_cli = { gather, parse_number, run, to_parts }
154
154
 
155
155
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
156
156
 
@@ -159,7 +159,7 @@ async function locate(text: string): Promise<string> {
159
159
  return format_locations(located)
160
160
  }
161
161
 
162
- const run_prep_locate = { extract_targets, format_locations, locate, parse_hits }
162
+ const run_prep_locate = { extract_targets, locate, parse_hits }
163
163
 
164
164
  export type { Hit, Located }
165
165
  export { run_prep_locate }
@@ -28,7 +28,7 @@ import { run_progress_read, type ObservationRead } from './run-progress-read'
28
28
  // `backlogrun` parent — `ready #N · free lanes N` — which is itself something the parent acts on.
29
29
  //
30
30
  // **It cannot send a Telegram.** That is structural rather than a promise — nothing here imports
31
- // `scripts/git/telegram-notify`, which is the only egress there is. A heartbeat every twenty minutes on
31
+ // `scripts/notify/telegram-notify`, which is the only egress there is. A heartbeat every twenty minutes on
32
32
  // a phone is notification fatigue, and it would cheapen the `confirmation` and `completion` messages
33
33
  // that do need to interrupt someone.
34
34
 
@@ -347,10 +347,13 @@ async function run_ticks(
347
347
  let loop = seed_loop(target, started_ms)
348
348
 
349
349
  while (Date.now() - started_ms < options.max_ms && !run_progress_clock.is_life_ended(life)) {
350
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
350
351
  await sleep(options.tick_ms)
351
352
  run_progress_clock.ping_life(life)
353
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
352
354
  loop = await step(options, target, loop)
353
355
 
356
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
354
357
  const exit = await wait_exit(loop, wait)
355
358
 
356
359
  if (exit !== undefined) return exit
@@ -491,27 +494,21 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
491
494
  }
492
495
 
493
496
  const run_progress_cli = {
494
- DECLINE_RETRY_SECONDS,
495
497
  DEFAULT_MAX_HOURS,
496
498
  DISABLED_NOTICE,
497
499
  FAILED_TICK_PREFIX,
498
500
  FRESH_LOOP,
499
501
  IDLE_NOTICE,
500
502
  LANE_CHILD_NOTICE,
501
- MARKED_NOTICE,
502
503
  REPO_UNRESOLVED_NOTICE,
503
- TICK_SECONDS,
504
504
  UNREADABLE_NOTICE,
505
505
  USAGE,
506
506
  WAIT_EXPIRED_NOTICE,
507
- main,
508
507
  read_arguments: run_progress_args.read_arguments,
509
- report_decline,
510
508
  run,
511
509
  step,
512
510
  to_interval_ms: run_progress_args.to_interval_ms,
513
511
  to_max_ms: run_progress_args.to_max_ms,
514
- to_options,
515
512
  wait_once,
516
513
  }
517
514
 
@@ -1,6 +1,5 @@
1
- import { git_utilities } from '#scripts/git/constants'
1
+ import { git_common_directory } from '#scripts/git/git-common-directory'
2
2
  import { stamp_file } from '#scripts/josh/stamp-file'
3
- import { execaSync } from 'execa'
4
3
  import { z } from 'zod'
5
4
 
6
5
  // The report clock `josh run:progress` keeps, in the one form both of its readers can use
@@ -16,9 +15,10 @@ import { z } from 'zod'
16
15
  //
17
16
  // **The key is the work tree's own git directory**, the way `run_hold` keys its record: two lanes of
18
17
  // one repository are two runs, and one lane's report must not silence the other's clock. The
19
- // synchronous twin asks `git rev-parse --absolute-git-dir`, which is the first of the two lines
20
- // `git_command.git_directories` reads and the one the asynchronous path already takes — so the two
21
- // spellings cannot name different files.
18
+ // synchronous twin is `git_common_directory.own()`, which asks the same two lines
19
+ // `git_command.git_directories` reads and takes the first — so the two spellings cannot name different
20
+ // files. A git read that fails or times out answers `undefined`, which reads as "no clock here" and
21
+ // lets the call through.
22
22
 
23
23
  const PROGRESS_PREFIX = 'josh-run-progress-'
24
24
  // The watcher's own liveness record, kept apart from the report clock above: that one says *when* the
@@ -55,14 +55,6 @@ const MS_PER_MINUTE = 60_000
55
55
  const LOG_STALE_MINUTES = 90
56
56
  const LOG_STALE_MS = LOG_STALE_MINUTES * MS_PER_MINUTE
57
57
  const BLOCK_SEPARATOR = '\n\n'
58
- // The lookup only ever decides whether a rule speaks, so a git call that hangs must not hold the hook
59
- // that is holding the user's call. A timeout answers `undefined`, which reads as "no clock here" and
60
- // lets the call through — the direction every other failure in this path already takes.
61
- const GIT_TIMEOUT_MS = 5000
62
- // The first of the two lines `git_command.git_directories` reads, asked on its own because that is the
63
- // one the record is keyed on. Asking git rather than assuming a directory named `.git` is what makes a
64
- // linked work tree, a bare repository and a `--separate-git-dir` clone all answer correctly.
65
- const GIT_DIRECTORY_ARGUMENTS: ReadonlyArray<string> = ['rev-parse', '--absolute-git-dir']
66
58
 
67
59
  // `line` is the last heartbeat the watcher printed, kept verbatim beside the clock so a reader that
68
60
  // cannot see the watcher's transcript — a person checking a woken headless `backlogrun` through
@@ -259,25 +251,8 @@ function end_life(target: string): void {
259
251
  stamp_file.remove_stamp(target)
260
252
  }
261
253
 
262
- // execa runs the binary directly with an argument array and no `shell` option, so CLI args cannot
263
- // break out of a shell sandbox; the git command and args are internally controlled, never untrusted
264
- // input. tssecurity:S8705 is a false positive here.
265
- function git_directory_sync(): string | undefined {
266
- const git_binary = git_utilities.get_git_command_for_spawn()
267
- const result = execaSync(git_binary, GIT_DIRECTORY_ARGUMENTS, {
268
- reject: false,
269
- timeout: GIT_TIMEOUT_MS,
270
- }) // NOSONAR
271
-
272
- if (result.exitCode !== 0) return undefined
273
-
274
- const output = result.stdout.trim()
275
-
276
- return output === '' ? undefined : output
277
- }
278
-
279
254
  function stamp_target_sync(): string | undefined {
280
- const directory = git_directory_sync()
255
+ const directory = git_common_directory.own()
281
256
 
282
257
  return directory === undefined ? undefined : stamp_target_of(directory)
283
258
  }
@@ -299,8 +274,6 @@ const run_progress_clock = {
299
274
  LIFE_PREFIX,
300
275
  LOG_KEEP,
301
276
  LOG_STALE_MS,
302
- PROGRESS_PREFIX,
303
- append_line,
304
277
  begin_life,
305
278
  end_life,
306
279
  is_life_ended,
@@ -314,7 +287,6 @@ const run_progress_clock = {
314
287
  read_last_report,
315
288
  read_last_report_sync,
316
289
  stamp_target_of,
317
- stamp_target_sync,
318
290
  }
319
291
 
320
292
  export { run_progress_clock }
@@ -27,8 +27,6 @@ import { run_progress } from './run-progress'
27
27
  // watcher it guards kept the default, which is the one state this module exists to prevent.
28
28
 
29
29
  const PACKAGE_FILE = 'package.json'
30
- const CONFIG_FIELD = 'josh'
31
- const INTERVAL_FIELD = 'progress_interval_minutes'
32
30
 
33
31
  // Deep enough to cross a workspace package and its root, and bounded so a path that never reaches a
34
32
  // root — a broken mount, a mocked `dirname` — cannot spin.
@@ -108,8 +106,6 @@ function configured_interval_ms(directory: string = process.cwd()): number {
108
106
  }
109
107
 
110
108
  const run_progress_config = {
111
- CONFIG_FIELD,
112
- INTERVAL_FIELD,
113
109
  PACKAGE_FILE,
114
110
  configured_interval_ms,
115
111
  read_package_minutes,
@@ -28,7 +28,7 @@ import { run_progress_clock } from './run-progress-clock'
28
28
  // `run-progress-clock.ts`, because the trigger-delivered rule that refuses an early heartbeat reads
29
29
  // the same record from inside a `PreToolUse` hook and cannot await the git call this file makes
30
30
  // (joshuafolkken/kit#1570). What stays here is the asynchronous way of naming the work tree.
31
- const { PROGRESS_PREFIX, mark, parse_stamp, read_last_report } = run_progress_clock
31
+ const { mark, parse_stamp, read_last_report } = run_progress_clock
32
32
 
33
33
  const FIRST_LOAD_AVERAGE = 0
34
34
 
@@ -78,7 +78,7 @@ async function to_child(issue: OpenIssueData): Promise<ChildObservation> {
78
78
  const number = String(issue.number)
79
79
  const child = await run_preflight.read_child_state(number)
80
80
 
81
- return { issue: number, labels: to_labels(issue), pr_state: child.pr_state }
81
+ return { issue: number, title: issue.title, labels: to_labels(issue), pr_state: child.pr_state }
82
82
  }
83
83
 
84
84
  async function read_children(repo: string): Promise<ReadonlyArray<ChildObservation> | undefined> {
@@ -171,6 +171,7 @@ async function read_observations(request: ObservationRequest): Promise<Observati
171
171
  if (children.length === 0 && !(await has_run_started(lanes))) return IDLE_READ
172
172
 
173
173
  const observations: Observations = {
174
+ repo: request.repo,
174
175
  children,
175
176
  lanes,
176
177
  load_average: loadavg()[FIRST_LOAD_AVERAGE] ?? 0,
@@ -181,7 +182,6 @@ async function read_observations(request: ObservationRequest): Promise<Observati
181
182
  }
182
183
 
183
184
  const run_progress_read = {
184
- PROGRESS_PREFIX,
185
185
  has_run_started,
186
186
  live_target,
187
187
  log_target,
@@ -1,3 +1,5 @@
1
+ import { issue_cite, type IssueCiter } from '#scripts/issue/issue-cite'
2
+
1
3
  // `josh run:progress` — the one line an unattended run prints when it has gone quiet, and the clock
2
4
  // that decides when that is (joshuafolkken/kit#1520).
3
5
  //
@@ -56,6 +58,9 @@ const DEFAULT_INTERVAL_MS = DEFAULT_INTERVAL_MINUTES * MS_PER_MINUTE
56
58
  // a second spelling of it — `none` / `open` / `merged` / `closed`.
57
59
  interface ChildObservation {
58
60
  issue: string
61
+ // Kept from the `in-progress` listing the child was read from, so the line cites it in full
62
+ // (joshuafolkken/kit#2943) without a read per child.
63
+ title: string
59
64
  labels: ReadonlyArray<string>
60
65
  pr_state: string
61
66
  }
@@ -66,6 +71,8 @@ interface LaneObservation {
66
71
  }
67
72
 
68
73
  interface Observations {
74
+ // `owner/repo`, the repository the listing was read from — what every printed issue links into.
75
+ repo: string
69
76
  children: ReadonlyArray<ChildObservation>
70
77
  lanes: ReadonlyArray<LaneObservation>
71
78
  load_average: number
@@ -195,26 +202,32 @@ function next_state(
195
202
  return { key, unchanged_since_ms: now_ms }
196
203
  }
197
204
 
198
- function format_child(child: ChildObservation): string {
205
+ // The issue leads as a citation rather than a bare `#N` (joshuafolkken/kit#2943): the parent relays these
206
+ // lines verbatim, and a bare number copied into a reply is what the Stop guard sends back.
207
+ function format_child(child: ChildObservation, cite: IssueCiter): string {
199
208
  const labels = child.labels.length > 0 ? child.labels.join(',') : '(no labels)'
200
209
 
201
- return `#${child.issue} ${labels} PR:${child.pr_state}`
210
+ return `${cite(child.issue)} ${labels} PR:${child.pr_state}`
202
211
  }
203
212
 
204
213
  // An empty set is the pre-label stage, said as such rather than left as a blank slot between the
205
214
  // separators (joshuafolkken/kit#1900). After that change a `read_observations` result carries no
206
215
  // children exactly when a run has started and none has reached `in-progress` yet, so this is the one
207
216
  // place the two cases are told apart on the line.
208
- function format_children(children: ReadonlyArray<ChildObservation>): string {
217
+ function format_children(children: ReadonlyArray<ChildObservation>, repo: string): string {
209
218
  if (children.length === 0) return NO_CHILD_YET
219
+ const cite = issue_cite.citer(repo, new Map(children.map((child) => [child.issue, child.title])))
210
220
 
211
- return children.map((child) => format_child(child)).join(' · ')
221
+ return children.map((child) => format_child(child, cite)).join(' · ')
212
222
  }
213
223
 
214
- function format_lanes(lanes: ReadonlyArray<LaneObservation>): string {
224
+ // A lane is linked without its title: a lane in flight is a child the line above already cited in full,
225
+ // so repeating the title here would only lengthen the line.
226
+ function format_lanes(lanes: ReadonlyArray<LaneObservation>, repo: string): string {
215
227
  if (lanes.length === 0) return NO_LANES
228
+ const cite = issue_cite.citer(repo, new Map())
216
229
 
217
- return lanes.map((lane) => `${lane.issue}:${lane.state}`).join(' ')
230
+ return lanes.map((lane) => `${cite(lane.issue)}:${lane.state}`).join(' ')
218
231
  }
219
232
 
220
233
  // Absent is said, never filled in. A run started without a transcript path prints `unread` here, which
@@ -244,7 +257,7 @@ interface LineTiming {
244
257
  * this is that same move for one value.
245
258
  *
246
259
  * **It is a schedule rather than an observation, and the two conditions on it are said in prose**
247
- * (`docs/josh-commands.md` → `josh run:progress`): it holds only while the silence continues, and a
260
+ * (`docs/josh-commands-automation.md` → `josh run:progress`): it holds only while the silence continues, and a
248
261
  * real report arriving first restarts the clock through `--mark` and supersedes it. The line printing
249
262
  * it is itself a report, so the clock starts at this observation.
250
263
  */
@@ -303,8 +316,8 @@ function format_line(observations: Observations, timing: LineTiming): string {
303
316
  observed_at: format_observed_at(timing.now_ms),
304
317
  quiet: format_minutes(timing.now_ms - timing.quiet_since_ms),
305
318
  unchanged: format_minutes(timing.now_ms - timing.unchanged_since_ms),
306
- children: format_children(observations.children),
307
- lanes: format_lanes(observations.lanes),
319
+ children: format_children(observations.children, observations.repo),
320
+ lanes: format_lanes(observations.lanes, observations.repo),
308
321
  load: observations.load_average.toFixed(1),
309
322
  record: format_record(observations.record_age_ms),
310
323
  next: format_next_report(timing.now_ms, timing.interval_ms),
@@ -354,7 +367,6 @@ const run_progress = {
354
367
  format_line,
355
368
  format_next_line,
356
369
  format_next_report,
357
- format_record,
358
370
  format_report,
359
371
  is_due,
360
372
  minutes_from,