@joshuafolkken/kit 1.1471.0 → 1.1784.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 (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -7,11 +7,12 @@ import { backlog_arrival_added } from './backlog-arrival-added'
7
7
  import { backlog_next } from './backlog-next'
8
8
  import { backlog_ready, type ReadyPorts, type ReadyReading } from './backlog-ready'
9
9
  import { backlog_stalled } from './backlog-stalled'
10
+ import { backlog_stalled_detect } from './backlog-stalled-detect'
10
11
 
11
12
  // The arrival probe a `backlogrun` parent's `--wait` watcher runs while children are in flight.
12
13
  // Without it, an issue opted in with `auto-ok` mid-run is picked up only when the parent
13
14
  // next wakes — a child's merge, or the progress interval — so in practice the ten-minute stall detector
14
- // becomes the pick-up, and the person gets a ⏳ notification for the wait.
15
+ // becomes the pick-up, ten minutes late.
15
16
  //
16
17
  // **The watcher's exit is the only thing that wakes a live parent**, so the probe rides it: once a
17
18
  // minute it reads the backlog the pick-up line reads (`backlog_ready.read_ready`, cheap first — a full
@@ -66,15 +67,18 @@ async function bounded_ready_issues(): Promise<ReadonlyArray<string>> {
66
67
  return answered_issues(await backlog_ready.read_backlog_next(COMMAND_TIMEOUT_MS))
67
68
  }
68
69
 
69
- // The backlog reads, plus whether `run:add` handed the run an issue since a given instant.
70
+ // The backlog reads, whether `run:add` handed the run an issue since a given instant, and the stall
71
+ // detector's record of whether work and a free lane coexist (joshuafolkken/kit#4349).
70
72
  interface ArrivalPorts extends ReadyPorts {
71
73
  is_added_since: (since_ms: number) => Promise<boolean>
74
+ observe_offerable: (is_offerable: boolean) => Promise<void>
72
75
  }
73
76
 
74
77
  const ARRIVAL_PORTS: ArrivalPorts = {
75
78
  free_lane_count: backlog_ready.free_lane_count,
76
79
  ready_issues: bounded_ready_issues,
77
80
  is_added_since: backlog_arrival_added.is_added_since,
81
+ observe_offerable: backlog_stalled_detect.observe_offerable,
78
82
  }
79
83
 
80
84
  interface ArrivalProbe {
@@ -94,6 +98,11 @@ function arrivals(
94
98
  return is_raised ? reading.issues : reading.issues.filter((issue) => !baseline.has(issue))
95
99
  }
96
100
 
101
+ // The stall detector's condition, off the reading the probe already made.
102
+ function is_offerable(reading: ReadyReading): boolean {
103
+ return reading.issues.length > NONE && reading.free_lanes > NO_FREE
104
+ }
105
+
97
106
  // The baseline is the whole runnable pool, free lane or not: an issue that was waiting for a lane is not
98
107
  // new when one frees, and the child's merge that freed it already wakes the parent.
99
108
  //
@@ -149,7 +158,7 @@ async function retry_baseline(
149
158
  function pool_probe_of(
150
159
  initial: ReadonlySet<string> | undefined,
151
160
  first_ms: number,
152
- ports: ReadyPorts,
161
+ ports: ArrivalPorts,
153
162
  is_raised: () => boolean,
154
163
  ): ArrivalProbe {
155
164
  let next_ms = first_ms
@@ -168,6 +177,8 @@ function pool_probe_of(
168
177
 
169
178
  const reading = await read_reading(ports)
170
179
 
180
+ if (reading !== undefined) await ports.observe_offerable(is_offerable(reading))
181
+
171
182
  return reading !== undefined && arrivals(baseline, reading, is_raised()).length > NONE
172
183
  }
173
184
 
@@ -1,7 +1,6 @@
1
- #!/usr/bin/env tsx
2
- import { fileURLToPath } from 'node:url'
3
1
  import { path_decision } from '#scripts/josh/path-decision'
4
2
  import { cli_flags } from '#scripts/lib/cli-flags'
3
+ import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
5
4
  import {
6
5
  backlog_budget,
7
6
  type BacklogAnswer,
@@ -13,7 +12,6 @@ import {
13
12
  // command line, hand it to the pure decision, print the verdict on stdout and the reason on stderr
14
13
  // through the printer every mechanically-decided command in this repository already shares.
15
14
 
16
- const ARGV_OFFSET = 2
17
15
  const SUCCESS_EXIT_CODE = 0
18
16
  const FAILURE_EXIT_CODE = 1
19
17
  const JSON_KEY = 'budget'
@@ -54,19 +52,6 @@ function to_time_ms(raw: string | undefined): number | undefined {
54
52
  return Number.isNaN(parsed) ? undefined : parsed
55
53
  }
56
54
 
57
- // Digits and nothing else. `Number('')`, `Number(' ')` and `Number('0x10')` are all safe integers, so
58
- // a check that only asked `Number.isSafeInteger` would read an unset shell variable — `--max
59
- // "$max_issues"` — as a maximum of zero and finish the run having done nothing.
60
- const COUNT_PATTERN = /^\d+$/u
61
-
62
- function to_count(raw: string | undefined): number | undefined {
63
- if (raw === undefined || !COUNT_PATTERN.test(raw)) return undefined
64
-
65
- const parsed = Number(raw)
66
-
67
- return Number.isSafeInteger(parsed) ? parsed : undefined
68
- }
69
-
70
55
  // A flag that was given but could not be read makes the whole invocation unreadable. Falling back to
71
56
  // the default instead would answer a question nobody asked — a mistyped `--idle 0` would read as the
72
57
  // default watch and hold a run open that was asked to finish at its first empty backlog.
@@ -80,10 +65,10 @@ type Counts = Record<(typeof COUNT_NAMES)[number], number | undefined>
80
65
 
81
66
  function counts_of(values: ParsedValues): Counts {
82
67
  return {
83
- idle: to_count(cli_flags.string_of(values.idle)),
84
- max: to_count(cli_flags.string_of(values.max)),
85
- merged: to_count(cli_flags.string_of(values.merged)),
86
- running: to_count(cli_flags.string_of(values.running)),
68
+ idle: cli_flags.to_count(cli_flags.string_of(values.idle)),
69
+ max: cli_flags.to_count(cli_flags.string_of(values.max)),
70
+ merged: cli_flags.to_count(cli_flags.string_of(values.merged)),
71
+ running: cli_flags.to_count(cli_flags.string_of(values.running)),
87
72
  }
88
73
  }
89
74
 
@@ -102,7 +87,7 @@ function to_idle_ms(idle_minutes: number | undefined): number | undefined {
102
87
  if (idle_minutes === undefined) return backlog_budget.DEFAULT_IDLE_MS
103
88
  if (idle_minutes === NO_IDLE_MINUTES) return undefined
104
89
 
105
- return idle_minutes * backlog_budget.MS_PER_MINUTE
90
+ return idle_minutes * MS_PER_MINUTE
106
91
  }
107
92
 
108
93
  // An idle watch measured from the run's start is not the watch that was asked for. A run already
@@ -117,7 +102,7 @@ function to_idle_ms(idle_minutes: number | undefined): number | undefined {
117
102
  // lands on the very first ask, before the run has started anything, and the fix is one flag the loop
118
103
  // already holds: it always knows when it last had work.
119
104
  function is_watch_readable(values: ParsedValues): boolean {
120
- if (to_idle_ms(to_count(cli_flags.string_of(values.idle))) === undefined) return true
105
+ if (to_idle_ms(cli_flags.to_count(cli_flags.string_of(values.idle))) === undefined) return true
121
106
 
122
107
  return cli_flags.string_of(values.active) !== undefined
123
108
  }
@@ -197,28 +182,17 @@ function run(argv: ReadonlyArray<string>, now_ms: number = Date.now()): number {
197
182
  return SUCCESS_EXIT_CODE
198
183
  }
199
184
 
200
- // `process.exitCode` rather than `process.exit()`, for the reason `backlog:next` records: the whole
201
- // contract is `answer=$(pnpm josh backlog:budget …)`, and exiting outright can cut the pipe before it
202
- // has drained.
203
- function main(argv: ReadonlyArray<string>): void {
204
- process.exitCode = run(argv)
205
- }
206
-
207
185
  const backlog_budget_cli = {
208
186
  JSON_KEY,
209
187
  OPTIONS,
210
188
  SUCCESS_EXIT_CODE,
211
189
  USAGE,
212
190
  build_input,
213
- main,
214
191
  read_arguments,
215
192
  run,
216
193
  to_answer,
217
- to_count,
218
194
  to_time_ms,
219
195
  }
220
196
 
221
- if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
222
-
223
197
  export { backlog_budget_cli }
224
198
  export type { ParsedValues }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { backlog_budget_cli } from './backlog-budget-cli'
4
+
5
+ // The `josh backlog:budget` entry, kept apart from `backlog-budget-cli.ts` because other modules
6
+ // import that one: a bundle is one file, so a main guard there would fire for every command that
7
+ // carries it (joshuafolkken/kit#4186).
8
+ //
9
+ // `process.exitCode` rather than `process.exit()`, for the reason `backlog:next` records: the whole
10
+ // contract is `answer=$(pnpm josh backlog:budget …)`, and exiting outright can cut the pipe before it
11
+ // has drained.
12
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
13
+ const ARGV_OFFSET = 2
14
+
15
+ process.exitCode = backlog_budget_cli.run(process.argv.slice(ARGV_OFFSET))
16
+ }
@@ -1,3 +1,5 @@
1
+ import { MS_PER_MINUTE, MS_PER_SECOND } from '#scripts/lib/timeouts'
2
+
1
3
  // `josh backlog:budget` — whether a `backlogrun` may start more work, keep watching, or finish.
2
4
  //
3
5
  // `backlog:next` says what may start; it says nothing about when the run itself should end. Without
@@ -17,7 +19,6 @@
17
19
  // and `josh review:level` are commands: a count and an elapsed time kept in an agent's head are a
18
20
  // one-shot judgement — a threshold asked once and then never again while the run walks past it.
19
21
 
20
- const MS_PER_MINUTE = 60_000
21
22
  const MINUTES_PER_HOUR = 60
22
23
 
23
24
  // **How long a run with nothing to do waits, and the only time bound a run has.** It is counted from
@@ -34,7 +35,6 @@ const DEFAULT_IDLE_MS = DEFAULT_IDLE_MINUTES * MS_PER_MINUTE
34
35
  // once, without waiting it out. `backlogrun-progress.md` → "Waiting, and never waiting forever" holds
35
36
  // the row; the figure is here because `idle_watch_reason` below has to say it.
36
37
  const OFFER_INTERVAL_SECONDS = 60
37
- const MS_PER_SECOND = 1000
38
38
  const OFFER_INTERVAL_MS = OFFER_INTERVAL_SECONDS * MS_PER_SECOND
39
39
 
40
40
  const RUN_VERDICT = 'run'
@@ -42,7 +42,7 @@ const WATCH_VERDICT = 'watch'
42
42
  const STOP_VERDICT = 'stop'
43
43
  const TRIAGE_VERDICT = 'triage'
44
44
 
45
- // `run` — start what `backlog:next` offered. `watch` — sleep the polling interval and ask again,
45
+ // `run` — start what `backlog:next` offered. `watch` — sleep the re-ask floor and ask again,
46
46
  // except while something of the run's own is in flight, where the wake is the progress watcher's exit
47
47
  // and the interval is only a floor (`docs/maintainers/backlogrun-driver.md` → "Waiting while
48
48
  // something is in flight").
@@ -87,7 +87,7 @@ interface BudgetDecision {
87
87
  }
88
88
 
89
89
  const BLOCKED_REASON =
90
- 'Everything opted in is blocked or already running, so waiting can still change the answer. Poll again at the polling interval.'
90
+ 'Everything opted in is blocked or already running, so waiting can still change the answer. Ask again at the re-ask floor (60 s).'
91
91
 
92
92
  const TRIAGE_REASON =
93
93
  'An opted-in candidate carries neither `run:solo` nor `run:lane`, so nothing starts until it is judged. Read each issue named above, record its order and one of the two labels with a comment, then ask again.'
@@ -121,7 +121,7 @@ function max_reached_reason(merged: number, max_issues: number): string {
121
121
  }
122
122
 
123
123
  function draining_reason(running: number, reason: string): string {
124
- return `Start nothing more and poll until the running children merge (running: ${String(running)}). Then report and finish — ${reason}`
124
+ return `Start nothing more and wait on \`pnpm josh lane:await\` until the running children merge (running: ${String(running)}). Then report and finish — ${reason}`
125
125
  }
126
126
 
127
127
  function idle_expired_reason(answer: BacklogAnswer, idle_budget_ms: number): string {
@@ -140,7 +140,7 @@ function idle_watch_reason(answer: BacklogAnswer, left_ms: number): string {
140
140
  // **The watch runs down while they drain, and restarts at each one collected.** A collected child is
141
141
  // work, so it moves `active_at`; an ask that offered nothing never does.
142
142
  function running_watch_reason(answer: BacklogAnswer, running: number, left_ms: number): string {
143
- return `${waiting_on(answer)} and the idle watch has about ${to_minutes(left_ms)} minutes left, with ${String(running)} still running. Keep the working tree until they merge and poll at the polling interval — the watch is running down meanwhile.`
143
+ return `${waiting_on(answer)} and the idle watch has about ${to_minutes(left_ms)} minutes left, with ${String(running)} still running. Keep the working tree and wait on \`pnpm josh lane:await\` until they merge — the watch is running down meanwhile.`
144
144
  }
145
145
 
146
146
  function watching_reason(input: BudgetInput, left_ms: number): string {
@@ -231,7 +231,6 @@ const backlog_budget = {
231
231
  DEFAULT_IDLE_MINUTES,
232
232
  DEFAULT_IDLE_MS,
233
233
  IDLE_WAIT_HOURS,
234
- MS_PER_MINUTE,
235
234
  OFFER_INTERVAL_MS,
236
235
  RUN_VERDICT,
237
236
  STOP_VERDICT,
@@ -18,10 +18,11 @@ function above_message(measured: DefectRate): string {
18
18
  return `The defect rate ${defect_rate.rate_text(measured)} is above its baseline ${String(defect_rate.BASELINE_RATE)}, so defects are offered first and new mechanisms last.`
19
19
  }
20
20
 
21
- // An unreadable body reads as empty: the labels still classify `route:interrupt`, and anything else
22
- // keeps its usual place rather than being deferred on a read that failed.
21
+ // The body the listing already carried, else one read for it (joshuafolkken/kit#4550). An unreadable
22
+ // body reads as empty: the labels still classify `route:interrupt`, and anything else keeps its usual
23
+ // place rather than being deferred on a read that failed.
23
24
  async function kind_of_child(child: EpicChild): Promise<IssueKind> {
24
- const body = await git_gh_command.issue_get_body(String(child.number), child.repo)
25
+ const body = child.body ?? (await git_gh_command.issue_get_body(String(child.number), child.repo))
25
26
 
26
27
  return defect_rate.kind_of({ body: body ?? '', labels: child.labels })
27
28
  }
@@ -0,0 +1,67 @@
1
+ import { issue_cite } from '#scripts/issue/issue-cite'
2
+ import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
3
+ import { run_event_stream } from '#scripts/run/event/run-event-stream'
4
+ import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
5
+ import type { DrivePorts, DriveState } from './backlog-drive'
6
+ import { backlog_drive_restore } from './backlog-drive-restore'
7
+
8
+ // **A lane the drive did not launch is still the run's to collect** (joshuafolkken/kit#4373). The loop
9
+ // held only the lanes it was seeded with and the ones it launched, so a child the parent dispatched
10
+ // itself with `lane:launch` — an interrupt in a named run — finished, merged and was never handed to
11
+ // `run:merge`: no `merge` event and no collected lane until `run:carry --end`, 91 minutes later. The
12
+ // stop was `run_pass` collecting only `state.in_flight` (`backlog-drive.ts`), seeded once at start
13
+ // (`backlog-drive-cli.ts` `seeded_lanes`). Adopted, a child that ends with its pull request unmerged
14
+ // is classified `failed` by `run:merge` (`run-merge.ts` `unfinished_outcome`), which puts it on the
15
+ // stream as a park with its cause (`run-merge-cli.ts` `on_parked_failure`) — the reason a lane left
16
+ // unmerged is recorded.
17
+
18
+ // The open lanes on a child this run launched and never settled — what the drive adopts while it runs
19
+ // and `run:carry --end` collects once it has stopped.
20
+ async function active_lanes(): Promise<ReadonlyArray<LaneInfo>> {
21
+ const active = backlog_drive_restore.active_issues(await run_event_stream_emit.current_events())
22
+ const lanes = await lane_registry.list_lanes()
23
+
24
+ return lanes.filter((lane) => !lane.is_stranded && active.has(lane.issue))
25
+ }
26
+
27
+ function adopted_note(issue: string): string {
28
+ return `${issue_cite.plain(issue)} adopted by backlog:drive: its lane was launched outside the loop`
29
+ }
30
+
31
+ async function note_adopted(issue: string): Promise<void> {
32
+ await run_event_stream_emit.emit(run_event_stream.EVENT_KIND.NOTE, adopted_note(issue))
33
+ }
34
+
35
+ // The active lanes the loop does not hold, each put on the stream with why it is adopted.
36
+ async function adoptable(in_flight: ReadonlyArray<string>): Promise<ReadonlyArray<string>> {
37
+ const lanes = await active_lanes()
38
+ const issues = lanes.map((lane) => lane.issue).filter((issue) => !in_flight.includes(issue))
39
+
40
+ await Promise.all(
41
+ issues.map(async (issue) => {
42
+ await note_adopted(issue)
43
+ }),
44
+ )
45
+
46
+ return issues
47
+ }
48
+
49
+ // The state with every adoptable lane in flight, so its child is collected as soon as it ends. Asked on
50
+ // an offered pass only, not every poll: the read walks the run's whole event stream. A stopping run
51
+ // adopts nothing: the child whose unparked failure stopped it left the stream unsettled, so adopting
52
+ // would collect — and count — it again.
53
+ async function held(
54
+ state: DriveState,
55
+ should_offer: boolean,
56
+ ports: Pick<DrivePorts, 'adoptable'>,
57
+ ): Promise<DriveState> {
58
+ if (!should_offer || state.is_stopping) return state
59
+
60
+ const adopting = await ports.adoptable(state.in_flight)
61
+
62
+ return adopting.length === 0 ? state : { ...state, in_flight: [...state.in_flight, ...adopting] }
63
+ }
64
+
65
+ const backlog_drive_adopt = { active_lanes, adoptable, held }
66
+
67
+ export { backlog_drive_adopt }
@@ -1,5 +1,6 @@
1
1
  import { issue_number_shape } from '#scripts/issue/issue-number-shape'
2
2
  import { cli_flags } from '#scripts/lib/cli-flags'
3
+ import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
3
4
  import type { DriveState } from './backlog-drive'
4
5
 
5
6
  // The `josh backlog:drive` flags — read into a `DriveContext`, and written back as the `resume:` line —
@@ -7,9 +8,7 @@ import type { DriveState } from './backlog-drive'
7
8
  // `backlog_drive_cli` re-exports `parse` and `resume_line` under the names they always had, so the move
8
9
  // changed no call site and no suite that reads them through `backlog_drive_cli`.
9
10
 
10
- const MS_PER_MINUTE = 60_000
11
11
  const LIST_SEPARATOR = ','
12
- const COUNT_PATTERN = /^\d+$/u
13
12
  const USAGE =
14
13
  'Usage: josh backlog:drive --owner <pid> [--active <ISO-8601>] [--max <n>] [--idle <minutes>] [--only] [--exclude <n>[,<n>...]] [--await <n>[,<n>...]] [--window <minutes>] [--stopped <n>]'
15
14
 
@@ -57,7 +56,7 @@ function to_issues(raw: string | undefined): ReadonlyArray<string> | undefined {
57
56
  function forwarded_of(values: Values): ReadonlyArray<string> | undefined {
58
57
  const pairs = (['max', 'idle'] as const).filter((name) => values[name] !== undefined)
59
58
 
60
- if (pairs.some((name) => !COUNT_PATTERN.test(values[name] ?? ''))) return undefined
59
+ if (pairs.some((name) => cli_flags.to_count(values[name]) === undefined)) return undefined
61
60
 
62
61
  return pairs.flatMap((name) => [`--${name}`, values[name] ?? ''])
63
62
  }
@@ -68,7 +67,7 @@ function window_of(raw: string | undefined): number | undefined {
68
67
  }
69
68
 
70
69
  function is_valid_window(raw: string | undefined): boolean {
71
- return raw === undefined || COUNT_PATTERN.test(raw)
70
+ return raw === undefined || cli_flags.to_count(raw) !== undefined
72
71
  }
73
72
 
74
73
  function is_valid_single(values: Values): boolean {
@@ -81,7 +80,7 @@ function is_valid_single(values: Values): boolean {
81
80
  function owner_of(values: Values | undefined): string | undefined {
82
81
  const owner = values?.owner
83
82
 
84
- return owner !== undefined && COUNT_PATTERN.test(owner) ? owner : undefined
83
+ return cli_flags.to_count(owner) === undefined ? undefined : owner
85
84
  }
86
85
 
87
86
  function to_context(values: Values, owner: string): DriveContext | undefined {
@@ -12,7 +12,8 @@ import { error_text } from '#scripts/lib/error-message'
12
12
  import { json_value } from '#scripts/lib/json-value'
13
13
  import { run_carry, type RunCarry } from '#scripts/run/carry/run-carry'
14
14
  import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
15
- import { run_merge_cli, type MergeResult } from '#scripts/run/merge/run-merge-cli'
15
+ import type { MergeResult } from '#scripts/run/merge/run-merge-cli'
16
+ import { run_merge_driver } from '#scripts/run/merge/run-merge-driver'
16
17
  import { z } from 'zod'
17
18
  import { backlog_budget } from './backlog-budget'
18
19
  import {
@@ -23,14 +24,19 @@ import {
23
24
  type LoopPorts,
24
25
  type OfferRead,
25
26
  } from './backlog-drive'
27
+ import { backlog_drive_adopt } from './backlog-drive-adopt'
26
28
  import { backlog_drive_args, type DriveContext } from './backlog-drive-args'
27
29
  import { backlog_drive_carried } from './backlog-drive-carried'
28
30
  import { backlog_drive_finish } from './backlog-drive-finish'
31
+ import { backlog_drive_hold, type HoldRecorder } from './backlog-drive-hold'
32
+ import { backlog_drive_idle } from './backlog-drive-idle'
29
33
  import { backlog_drive_launch } from './backlog-drive-launch'
34
+ import { backlog_drive_memory } from './backlog-drive-memory'
30
35
  import { backlog_drive_named } from './backlog-drive-named'
31
36
  import { backlog_drive_named_offer } from './backlog-drive-named-offer'
32
37
  import { backlog_drive_offer_argv } from './backlog-drive-offer-argv'
33
38
  import { backlog_drive_owner } from './backlog-drive-owner'
39
+ import { backlog_drive_paused } from './backlog-drive-paused'
34
40
  import { backlog_drive_restore } from './backlog-drive-restore'
35
41
  import { backlog_drive_retrospective } from './backlog-drive-retrospective'
36
42
  import { backlog_drive_seats } from './backlog-drive-seats'
@@ -59,6 +65,8 @@ const offer_read_schema = z.object({
59
65
  issues: z.array(z.string()),
60
66
  retries: z.number(),
61
67
  answer: z.string().optional(),
68
+ cause: z.string().optional(),
69
+ waiting: z.array(z.number()).optional(),
62
70
  reason: z.string().optional(),
63
71
  is_finish: z.boolean().optional(),
64
72
  })
@@ -106,20 +114,21 @@ function merge_token(out: string, code: number): string {
106
114
  return ''
107
115
  }
108
116
 
117
+ // A `run:merge` that printed no result — a crash before its verdict — answers no token, which the loop
118
+ // never reads as a collection.
119
+ function unprinted(code: number): MergeResult {
120
+ return { token: '', code, is_offer: true, outcome: 'unresolved' }
121
+ }
122
+
109
123
  // The child's transcript, where its lane recorded one, so `run:merge` can tell an API outage from a
110
- // failure exactly as it does for the parent that passes `--output` by hand. No hand-off threshold: the
111
- // supervisor runs this loop, and a process has no context to cut.
124
+ // failure exactly as it does for the parent that passes `--output` by hand. Run as its own process
125
+ // (`run-merge-driver.ts`), so a fix merged since this loop started is the code that decides the child.
112
126
  async function merge(issue: string, owner: string): Promise<MergeResult> {
113
127
  await backlog_drive_owner.assert_current(owner)
114
128
  const lane = await lane_registry.find_open_lane(issue)
115
- const result = await run_merge_cli.merge_child({
116
- child: issue,
117
- epic: undefined,
118
- repo: undefined,
119
- over: undefined,
120
- owner: run_carry.owner_of(Number(owner)),
121
- output: lane?.output,
122
- })
129
+ const argv = run_merge_driver.argv_of({ child: issue, owner, output: lane?.output })
130
+ const ran = await josh_command.josh_run(argv, should_forward_stderr)
131
+ const result = run_merge_driver.read(ran.out) ?? unprinted(ran.code)
123
132
 
124
133
  await backlog_drive_named.mark_done(issue, result, owner)
125
134
 
@@ -130,17 +139,18 @@ async function merge(issue: string, owner: string): Promise<MergeResult> {
130
139
  // a restart after it ended — is read as having appeared, so it is collected after the re-confirm window
131
140
  // rather than waited on until the never-appeared timeout. One that never appeared is collected too:
132
141
  // `run:merge` reads its state rather than this loop guessing.
133
- function finished_checker(seeded: ReadonlyArray<string>): (issue: string) => boolean {
142
+ function finished_checker(seeded: ReadonlySet<string>): (issue: string) => boolean {
134
143
  const states = new Map<string, AwaitState>()
135
144
  const config = {
136
145
  is_running: lane_await.is_process_running_default,
146
+ is_shipped: lane_await.is_shipped_default,
137
147
  reconfirm_ms: lane_await.RECONFIRM_MS,
138
148
  never_appeared_timeout_ms: lane_await.NEVER_APPEARED_TIMEOUT_MS,
139
149
  }
140
150
 
141
151
  return (issue: string): boolean => {
142
152
  const state = states.get(issue) ?? {
143
- appeared: seeded.includes(issue),
153
+ appeared: seeded.has(issue),
144
154
  disappeared_at: undefined,
145
155
  first_polled_at: undefined,
146
156
  }
@@ -181,19 +191,61 @@ function judgement_reader(): () => Promise<number> {
181
191
  }
182
192
  }
183
193
 
194
+ // The reports an offered pass leaves: why it started nothing, the idle notice and the paused notice.
195
+ function reporters(holds: HoldRecorder): Pick<LoopPorts, 'hold' | 'idle' | 'paused'> {
196
+ return {
197
+ hold: holds.hold,
198
+ idle: backlog_drive_idle.notify,
199
+ paused: async () => {
200
+ await backlog_drive_paused.notify()
201
+ },
202
+ }
203
+ }
204
+
205
+ // What a launch is weighed against: the free lanes, a kept lane, and the memory for one more.
206
+ function room_ports(): Pick<LoopPorts, 'free_lanes' | 'has_lane' | 'limit_room' | 'memory_held'> {
207
+ return {
208
+ free_lanes: backlog_ready.drive_free_lane_count,
209
+ limit_room: backlog_ready.drive_limit_room,
210
+ has_lane: backlog_drive_seats.has_kept_lane,
211
+ memory_held: backlog_drive_memory.gauge(),
212
+ }
213
+ }
214
+
215
+ // The children's ports. An adopted lane was dispatched like a seeded one, so a child already gone is
216
+ // collected rather than waited on until the never-appeared timeout.
217
+ function child_ports(
218
+ seeded: ReadonlyArray<string>,
219
+ owner: string,
220
+ ): Pick<LoopPorts, 'adoptable' | 'is_finished' | 'merge'> {
221
+ const known = new Set(seeded)
222
+
223
+ return {
224
+ is_finished: finished_checker(known),
225
+ merge: async (issue) => await merge(issue, owner),
226
+ adoptable: async (in_flight) => {
227
+ const adopting = await backlog_drive_adopt.adoptable(in_flight)
228
+
229
+ for (const issue of adopting) known.add(issue)
230
+
231
+ return adopting
232
+ },
233
+ }
234
+ }
235
+
184
236
  function ports_of(
185
237
  context: DriveContext,
186
238
  seeded: ReadonlyArray<string>,
187
239
  last: { state: DriveState },
240
+ holds: HoldRecorder,
188
241
  ): LoopPorts {
189
242
  return {
190
- is_finished: finished_checker(seeded),
191
- merge: async (issue) => await merge(issue, context.owner),
243
+ ...child_ports(seeded, context.owner),
192
244
  offer: async (state) => await read_offer(state, context),
193
245
  launch: async (issue) => await backlog_drive_launch.launch(issue, context.owner),
194
- free_lanes: backlog_ready.drive_free_lane_count,
195
- has_lane: backlog_drive_seats.has_kept_lane,
246
+ ...room_ports(),
196
247
  judgement_owed: judgement_reader(),
248
+ ...reporters(holds),
197
249
  now: () => new Date(),
198
250
  sleep: async (milliseconds) => {
199
251
  await sleep(milliseconds)
@@ -205,7 +257,15 @@ function ports_of(
205
257
  }
206
258
  }
207
259
 
208
- async function seeded_lanes(context: DriveContext): Promise<ReadonlyArray<string> | undefined> {
260
+ // The lanes still in flight, and the children this run withdrew: a withdrawal while the drive was
261
+ // handed back is never collected by this invocation, so its exclusion is read from the stream
262
+ // (joshuafolkken/kit#4365).
263
+ interface Seeded {
264
+ lanes: ReadonlyArray<string>
265
+ withdrawn: ReadonlyArray<string>
266
+ }
267
+
268
+ async function seeded_lanes(context: DriveContext): Promise<Seeded | undefined> {
209
269
  const carry = await read_record()
210
270
 
211
271
  if (carry === undefined) return undefined
@@ -216,9 +276,13 @@ async function seeded_lanes(context: DriveContext): Promise<ReadonlyArray<string
216
276
 
217
277
  const open = await open_lanes()
218
278
  const lanes = [...new Set([...open.map((lane) => lane.issue), ...context.awaited])]
219
- const dispatched = await backlog_drive_carried.carried(open)
279
+ const carried = await backlog_drive_carried.carried(open)
280
+ const dispatched = backlog_drive_named.own_carried(carry, carried, context.is_only)
220
281
 
221
- return backlog_drive_restore.restore(lanes, events, carry.merged_issues ?? [], dispatched)
282
+ return {
283
+ lanes: backlog_drive_restore.restore(lanes, events, carry.merged_issues ?? [], dispatched),
284
+ withdrawn: backlog_drive_restore.withdrawn_issues(events),
285
+ }
222
286
  }
223
287
 
224
288
  // The interval between two asks is `backlog:budget`'s own, so the driver keeps the one its reason prints.
@@ -226,19 +290,39 @@ function loop_config(window_ms: number | undefined): LoopConfig {
226
290
  return { poll_ms: POLL_MS, offer_ms: backlog_budget.OFFER_INTERVAL_MS, window_ms }
227
291
  }
228
292
 
293
+ // The hand-back, the ledger's hold included — the lanes now wait on a session — and the resume line.
294
+ async function report_end(
295
+ end: DriveEnd,
296
+ state: DriveState,
297
+ context: DriveContext,
298
+ holds: HoldRecorder,
299
+ ): Promise<void> {
300
+ await holds.end(end)
301
+ console.info(end_line(end))
302
+ console.info(backlog_drive_args.resume_line(state, context))
303
+ }
304
+
305
+ function seeded_state(seeded: Seeded, context: DriveContext): DriveState {
306
+ const fresh = backlog_drive.initial_state(
307
+ seeded.lanes,
308
+ context.active ?? new Date().toISOString(),
309
+ )
310
+ const initial =
311
+ context.stopped === undefined ? fresh : backlog_drive.merge_stopped(context.stopped, fresh)
312
+
313
+ return { ...initial, exclude: [...new Set([...context.exclude, ...seeded.withdrawn])] }
314
+ }
315
+
229
316
  async function drive(context: DriveContext): Promise<number> {
230
317
  const seeded = await seeded_lanes(context)
231
318
 
232
319
  if (seeded === undefined) return FAILURE_EXIT_CODE
233
- const fresh = backlog_drive.initial_state(seeded, context.active ?? new Date().toISOString())
234
- const initial =
235
- context.stopped === undefined ? fresh : backlog_drive.merge_stopped(context.stopped, fresh)
236
- const last = { state: { ...initial, exclude: [...context.exclude] } }
237
- const config = loop_config(context.window_ms)
238
- const end = await backlog_drive.run_loop(last.state, config, ports_of(context, seeded, last))
320
+ const last = { state: seeded_state(seeded, context) }
321
+ const holds = backlog_drive_hold.recorder()
322
+ const ports = ports_of(context, seeded.lanes, last, holds)
323
+ const end = await backlog_drive.run_loop(last.state, loop_config(context.window_ms), ports)
239
324
 
240
- console.info(end_line(end))
241
- console.info(backlog_drive_args.resume_line(last.state, context))
325
+ await report_end(end, last.state, context, holds)
242
326
 
243
327
  return SUCCESS_EXIT_CODE
244
328
  }
@@ -288,6 +372,7 @@ const backlog_drive_cli = {
288
372
  read_offer,
289
373
  resume_line: backlog_drive_args.resume_line,
290
374
  run,
375
+ seeded_state,
291
376
  to_offer,
292
377
  }
293
378