@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
@@ -0,0 +1,169 @@
1
+ import type { OpenIssueData } from '#scripts/git/git-schemas'
2
+ import { issue_cite } from '#scripts/issue/issue-cite'
3
+ import { has_any_label, NEEDS_DECISION_LABEL, RUN_STALLED_LABEL } from '#scripts/issue/issue-labels'
4
+ import { lane_registry } from '#scripts/lane/lane-registry'
5
+ import { lane_state, type LaneStateRecord } from '#scripts/lane/lane-state'
6
+ import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
7
+ import { telegram_notify } from '#scripts/notify/telegram-notify'
8
+ import { run_event_stream } from '#scripts/run/event/run-event-stream'
9
+ import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
10
+ import { DEFAULT_SILENT_MINUTES } from '#scripts/run/run-liveness'
11
+ import type { DrivePorts, OfferRead, PassResult } from './backlog-drive'
12
+ import { backlog_drive_idle } from './backlog-drive-idle'
13
+ import { backlog_overlap } from './backlog-overlap'
14
+
15
+ // A run held only by paused lanes (joshuafolkken/kit#4270): nothing of this run in flight, nothing
16
+ // dispatched, and a lane a person paused past the silent window `run:liveness` waits out declares a
17
+ // path an open candidate overlaps. A paused lane holds no lane place (`backlog-occupied.ts`), so that
18
+ // overlap is the one way it holds the run; the loop would otherwise watch for ever — a paused lane
19
+ // frees nothing until someone resumes it — so it asks the person once. A drained or parked backlog
20
+ // with a lane paused somewhere is not held by it, and stays quiet.
21
+ //
22
+ // **Once per pause episode**: the marker on the stream (`emit_once_since_with`, reset by the
23
+ // `lane-state` line every `lane:pause` / `lane:resume` writes) holds every repeat back.
24
+
25
+ const HOLDING_VERDICTS: ReadonlySet<string> = new Set(['watch', 'wait'])
26
+ const BLOCKED_ANSWER = 'blocked'
27
+ const PAUSED_TITLE = 'backlogrun held by paused lanes'
28
+ const PAUSED_HEAD =
29
+ 'No child of this run is running, and these paused lanes hold back work overlapping their paths:'
30
+ const PAUSED_RECOVERY =
31
+ 'Resume a lane with `pnpm josh lane:resume <N>`, or close it with `pnpm josh lane:close <N>`.'
32
+ const SILENT_WINDOW_MS = DEFAULT_SILENT_MINUTES * MS_PER_MINUTE
33
+ // A candidate a person set aside waits on that person, not on the paused lane it overlaps.
34
+ const SET_ASIDE_LABELS: ReadonlySet<string> = new Set([NEEDS_DECISION_LABEL, RUN_STALLED_LABEL])
35
+
36
+ interface PausedPorts {
37
+ read_records: () => Promise<ReadonlyArray<LaneStateRecord>>
38
+ // The `auto-ok` pool, or `undefined` when it could not be read.
39
+ read_issues: () => Promise<ReadonlyArray<OpenIssueData> | undefined>
40
+ emit: (compose: () => Promise<string>) => Promise<string | undefined>
41
+ send: (body: string) => Promise<boolean>
42
+ now_ms: () => number
43
+ }
44
+
45
+ // The port is asked on every holding offer with nothing in flight; `notify` decides whether a paused
46
+ // lane is what holds it.
47
+ function is_held(result: PassResult, read: OfferRead): boolean {
48
+ if (read.answer === BLOCKED_ANSWER) return false
49
+
50
+ return HOLDING_VERDICTS.has(read.verdict) && result.state.in_flight.length === 0
51
+ }
52
+
53
+ async function noticed(
54
+ result: PassResult,
55
+ read: OfferRead,
56
+ ports: Pick<DrivePorts, 'paused'>,
57
+ ): Promise<PassResult> {
58
+ if (is_held(result, read)) await ports.paused()
59
+
60
+ return result
61
+ }
62
+
63
+ /** The records paused for at least the silent window at `now_ms`. */
64
+ function long_paused(
65
+ records: ReadonlyArray<LaneStateRecord>,
66
+ now_ms: number,
67
+ ): Array<LaneStateRecord> {
68
+ return records.filter(
69
+ (record) =>
70
+ record.state === 'paused' && now_ms - Date.parse(record.changed_at) >= SILENT_WINDOW_MS,
71
+ )
72
+ }
73
+
74
+ // The open candidates no lane works on and no person set aside — the ones a paused lane can hold.
75
+ function waiting_of(
76
+ issues: ReadonlyArray<OpenIssueData>,
77
+ records: ReadonlyArray<LaneStateRecord>,
78
+ ): Array<number> {
79
+ const lanes = new Set(records.map((record) => record.issue))
80
+
81
+ return issues
82
+ .filter((issue) => !lanes.has(String(issue.number)))
83
+ .filter((issue) => !has_any_label(issue.labels, SET_ASIDE_LABELS))
84
+ .map((issue) => issue.number)
85
+ }
86
+
87
+ /** The `paused` records whose declared paths a waiting candidate overlaps. */
88
+ function holding(
89
+ paused: ReadonlyArray<LaneStateRecord>,
90
+ issues: ReadonlyArray<OpenIssueData>,
91
+ records: ReadonlyArray<LaneStateRecord>,
92
+ ): Array<LaneStateRecord> {
93
+ const declared = backlog_overlap.declared_of(issues)
94
+ const waiting = waiting_of(issues, records)
95
+
96
+ return paused.filter((record) =>
97
+ waiting.some((number) => backlog_overlap.holds(declared, Number(record.issue), number)),
98
+ )
99
+ }
100
+
101
+ async function held_by(ports: PausedPorts): Promise<Array<LaneStateRecord>> {
102
+ const records = await ports.read_records()
103
+ const paused = long_paused(records, ports.now_ms())
104
+
105
+ if (paused.length === 0) return []
106
+
107
+ const issues = await ports.read_issues()
108
+
109
+ return issues === undefined ? [] : holding(paused, issues, records)
110
+ }
111
+
112
+ function describe(records: ReadonlyArray<LaneStateRecord>): string {
113
+ const lines = records.map(
114
+ (record) => `- ${issue_cite.plain(record.issue)} — ${lane_state.paused_note(record) ?? ''}`,
115
+ )
116
+
117
+ return [PAUSED_HEAD, ...lines].join('\n')
118
+ }
119
+
120
+ async function read_lane_records(): Promise<ReadonlyArray<LaneStateRecord>> {
121
+ const lanes = await lane_registry.list_lanes()
122
+ const records = await lane_state.read_states(lanes.map((lane) => lane.issue))
123
+
124
+ return [...records.values()]
125
+ }
126
+
127
+ async function emit_paused(compose: () => Promise<string>): Promise<string | undefined> {
128
+ const { PAUSED_NOTICE, LANE_STATE } = run_event_stream.EVENT_KIND
129
+
130
+ return await run_event_stream_emit.emit_once_since_with(PAUSED_NOTICE, LANE_STATE, compose)
131
+ }
132
+
133
+ async function send_paused(body: string): Promise<boolean> {
134
+ return await telegram_notify.confirm({
135
+ issue_title: PAUSED_TITLE,
136
+ body,
137
+ recovery: PAUSED_RECOVERY,
138
+ recommended: 'Resume the paused lanes with `pnpm josh lane:resume <N>`',
139
+ alternatives: ['Close the paused lanes with `pnpm josh lane:close <N>`'],
140
+ })
141
+ }
142
+
143
+ const DEFAULT_PORTS: PausedPorts = {
144
+ read_records: read_lane_records,
145
+ read_issues: backlog_drive_idle.read_pool,
146
+ emit: emit_paused,
147
+ send: send_paused,
148
+ now_ms: () => Date.now(),
149
+ }
150
+
151
+ // The production `paused` port. Best-effort, as the idle port is: a failed read or send is dropped.
152
+ async function notify(ports: PausedPorts = DEFAULT_PORTS): Promise<void> {
153
+ try {
154
+ const paused = await held_by(ports)
155
+
156
+ if (paused.length === 0) return
157
+
158
+ const body = await ports.emit(async () => describe(paused))
159
+
160
+ if (body !== undefined) await ports.send(body)
161
+ } catch {
162
+ // Reporting is best-effort: a paused notice we could not read or send is dropped.
163
+ }
164
+ }
165
+
166
+ const backlog_drive_paused = { noticed, notify }
167
+
168
+ export { backlog_drive_paused }
169
+ export type { PausedPorts }
@@ -1,16 +1,20 @@
1
+ import { run_event_scope } from '#scripts/run/event/run-event-scope'
1
2
  import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
3
+ import { backlog_offer_exclude } from './backlog-offer-exclude'
2
4
 
3
5
  const ISSUE_IN_EVENT = /#([1-9]\d*)\b/u
4
6
  const SETTLED_KINDS: ReadonlySet<string> = new Set([
5
7
  run_event_stream.EVENT_KIND.MERGE,
6
8
  run_event_stream.EVENT_KIND.PARK,
7
9
  run_event_stream.EVENT_KIND.SPLIT,
10
+ run_event_stream.EVENT_KIND.WITHDRAW,
8
11
  run_event_stream.EVENT_KIND.OUTAGE,
9
12
  ])
10
13
  const DONE_KINDS: ReadonlySet<string> = new Set([
11
14
  run_event_stream.EVENT_KIND.MERGE,
12
15
  run_event_stream.EVENT_KIND.PARK,
13
16
  run_event_stream.EVENT_KIND.SPLIT,
17
+ run_event_stream.EVENT_KIND.WITHDRAW,
14
18
  ])
15
19
 
16
20
  function issue_of(event: RunEvent): string | undefined {
@@ -44,14 +48,33 @@ function settled_issues(events: ReadonlyArray<RunEvent>): ReadonlySet<number> {
44
48
  )
45
49
  }
46
50
 
51
+ function issues_of_kind(events: ReadonlyArray<RunEvent>, kind: string): ReadonlyArray<string> {
52
+ return events
53
+ .filter((event) => event.kind === kind)
54
+ .map((event) => issue_of(event))
55
+ .filter((issue) => issue !== undefined)
56
+ }
57
+
58
+ // The issues a person withdrew from this run and nobody launched again: the withdrawal leaves the issue
59
+ // open for the next run, so this one keeps it out of the offer (joshuafolkken/kit#4365).
60
+ function withdrawn_issues(events: ReadonlyArray<RunEvent>): ReadonlyArray<string> {
61
+ const named = issues_of_kind(events, run_event_stream.EVENT_KIND.WITHDRAW)
62
+
63
+ return named.filter((issue) => run_event_scope.is_withdrawn(events, issue))
64
+ }
65
+
66
+ // The offer's exclusion as the stream records it: the merged and withdrawn children and the ones still
67
+ // in flight — the list the drive keeps in memory, read by a reader that has only the stream
68
+ // (joshuafolkken/kit#4349).
69
+ function offer_exclude(events: ReadonlyArray<RunEvent>): ReadonlyArray<string> {
70
+ const merged = issues_of_kind(events, run_event_stream.EVENT_KIND.MERGE)
71
+ const settled = [...merged, ...withdrawn_issues(events)]
72
+
73
+ return backlog_offer_exclude.exclude_of(settled, active_issues(events))
74
+ }
75
+
47
76
  function parked_issues(events: ReadonlyArray<RunEvent>): ReadonlySet<number> {
48
- return new Set(
49
- events
50
- .filter((event) => event.kind === run_event_stream.EVENT_KIND.PARK)
51
- .map((event) => issue_of(event))
52
- .filter((issue) => issue !== undefined)
53
- .map(Number),
54
- )
77
+ return new Set(issues_of_kind(events, run_event_stream.EVENT_KIND.PARK).map(Number))
55
78
  }
56
79
 
57
80
  // The issues this invocation launched or settled — any other dispatched lane was carried in from an
@@ -82,4 +105,12 @@ function restore(
82
105
  )
83
106
  }
84
107
 
85
- export const backlog_drive_restore = { active_issues, restore, settled_issues, parked_issues }
108
+ export const backlog_drive_restore = {
109
+ active_issues,
110
+ mentioned_issues,
111
+ offer_exclude,
112
+ restore,
113
+ withdrawn_issues,
114
+ settled_issues,
115
+ parked_issues,
116
+ }
@@ -1,25 +1,35 @@
1
1
  import { lane_registry } from '#scripts/lane/lane-registry'
2
+ import { lane_vacant } from '#scripts/lane/lane-vacant'
2
3
  import type { DrivePorts } from './backlog-drive'
3
4
 
4
- type SeatPorts = Pick<DrivePorts, 'free_lanes' | 'has_lane'>
5
+ type SeatPorts = Pick<DrivePorts, 'free_lanes' | 'has_lane' | 'limit_room'>
5
6
 
6
- // The issues a pass launches: every one that already holds a kept lane, which it reuses, then as many
7
- // of the rest as there are free lanes.
7
+ // The issues a pass launches: those that already hold a kept lane first, then the rest. A lane with no
8
+ // child in it holds no place under the limit (`backlog-occupied.ts`), so resuming its issue takes one
9
+ // (joshuafolkken/kit#4107) — but it keeps its port seat, so the resumes are cut by the limit room alone:
10
+ // idle kept lanes filling every seat must not shut out their own resumes. Fresh launches take what is
11
+ // left of both.
8
12
  async function seated(issues: ReadonlyArray<string>, ports: SeatPorts): Promise<Array<string>> {
9
13
  const kept = await Promise.all(issues.map(async (issue) => await ports.has_lane(issue)))
10
- const fresh = issues.filter((_issue, index) => kept[index] !== true)
14
+ const room = await ports.limit_room()
15
+ const resumed = issues.filter((_issue, index) => kept[index] === true).slice(0, room)
16
+ const fresh_room = Math.min(await ports.free_lanes(), room - resumed.length)
11
17
 
12
18
  return [
13
- ...issues.filter((_issue, index) => kept[index] === true),
14
- ...fresh.slice(0, await ports.free_lanes()),
19
+ ...resumed,
20
+ ...issues.filter((_issue, index) => kept[index] !== true).slice(0, fresh_room),
15
21
  ]
16
22
  }
17
23
 
18
- // A kept lane is one a child was dispatched into — `lane:launch` reuses it rather than opening one.
24
+ // A kept lane is one a child was dispatched into that holds work — `lane:launch` reuses it rather
25
+ // than opening one. A vacant one holds nothing to resume, so its issue waits in line like any fresh
26
+ // launch (joshuafolkken/kit#4028).
19
27
  async function has_kept_lane(issue: string): Promise<boolean> {
20
28
  const lane = await lane_registry.find_open_lane(issue)
21
29
 
22
- return lane?.output !== undefined
30
+ if (lane?.output === undefined) return false
31
+
32
+ return !(await lane_vacant.is_vacant(lane))
23
33
  }
24
34
 
25
35
  const backlog_drive_seats = { has_kept_lane, seated }
@@ -0,0 +1,38 @@
1
+ import { run_merge_token, type MergeToken } from '#scripts/run/merge/run-merge-token'
2
+
3
+ const { MERGE_TOKEN } = run_merge_token
4
+
5
+ // How the loop reads each `run:merge` token — keyed by the producer's own type, so a token added there
6
+ // is a type error here until it is classified. `hand-back` ends the loop at once: a hand-off, a person's
7
+ // stop, the environment down, a foreign owner, an unreadable state. `stop` — the failure guard, or a
8
+ // failed child left unparked — collects the child, starts nothing more, and collects the children still
9
+ // in flight before the loop ends. `await` is a cut resumed in place: the same lane is awaited again.
10
+ //
11
+ // **The offer `run:merge` passes through is never read here** (joshuafolkken/kit#3781): its `stop` —
12
+ // only person-waiting issues left — is spelled like the control one, and acting on it ended the run
13
+ // without the idle watch. The loop asks `backlog:offer` on the next pass instead, so whether a parked
14
+ // backlog waits or ends is `backlog:budget`'s alone, after a merge as after any other pass.
15
+ type TokenHandling = 'hand-back' | 'stop' | 'await'
16
+ const TOKEN_HANDLING: Readonly<Record<MergeToken, TokenHandling>> = {
17
+ [MERGE_TOKEN.OVER]: 'hand-back',
18
+ [MERGE_TOKEN.HUMAN_REVIEW]: 'hand-back',
19
+ [MERGE_TOKEN.ENVIRONMENT]: 'hand-back',
20
+ [MERGE_TOKEN.BUSY]: 'hand-back',
21
+ [MERGE_TOKEN.RETRY]: 'hand-back',
22
+ [MERGE_TOKEN.STOP]: 'stop',
23
+ [MERGE_TOKEN.RESUMED]: 'await',
24
+ }
25
+
26
+ function tokens_handled(...handlings: ReadonlyArray<TokenHandling>): ReadonlySet<string> {
27
+ const entries = Object.entries(TOKEN_HANDLING)
28
+
29
+ return new Set(entries.filter(([, handling]) => handlings.includes(handling)).map(([key]) => key))
30
+ }
31
+
32
+ const IMMEDIATE_TOKENS = tokens_handled('hand-back')
33
+ // Every token `run:merge` prints first even on a non-zero exit.
34
+ const HANDOFF_TOKENS = tokens_handled('hand-back', 'stop')
35
+
36
+ const backlog_drive_token_handling = { HANDOFF_TOKENS, IMMEDIATE_TOKENS, TOKEN_HANDLING }
37
+
38
+ export { backlog_drive_token_handling }
@@ -19,43 +19,22 @@
19
19
  import { issue_cite } from '#scripts/issue/issue-cite'
20
20
  import type { LaunchOutcome } from '#scripts/lane/lane-launch-cli'
21
21
  import type { MergeResult } from '#scripts/run/merge/run-merge-cli'
22
- import { run_merge_token, type MergeToken } from '#scripts/run/merge/run-merge-token'
22
+ import { run_merge_token } from '#scripts/run/merge/run-merge-token'
23
+ import { backlog_drive_adopt } from './backlog-drive-adopt'
24
+ import { backlog_drive_hold, type HeldWaiting } from './backlog-drive-hold'
25
+ import { backlog_drive_idle } from './backlog-drive-idle'
26
+ import { backlog_drive_judge } from './backlog-drive-judge'
27
+ import { backlog_drive_memory } from './backlog-drive-memory'
28
+ import { backlog_drive_paused } from './backlog-drive-paused'
23
29
  import { backlog_drive_seats } from './backlog-drive-seats'
30
+ import { backlog_drive_token_handling } from './backlog-drive-token-handling'
24
31
 
25
32
  const { MERGE_TOKEN } = run_merge_token
33
+ const { HANDOFF_TOKENS, IMMEDIATE_TOKENS, TOKEN_HANDLING } = backlog_drive_token_handling
26
34
  const RUN_VERDICT = 'run'
27
35
  const STOP_VERDICT = 'stop'
28
- // How the loop reads each `run:merge` token — keyed by the producer's own type, so a token added there
29
- // is a type error here until it is classified. `hand-back` ends the loop at once: a hand-off, a person's
30
- // stop, the environment down, a foreign owner, an unreadable state. `stop` — the failure guard, or a
31
- // failed child left unparked — collects the child, starts nothing more, and collects the children still
32
- // in flight before the loop ends. `await` is a cut resumed in place: the same lane is awaited again.
33
- //
34
- // **The offer `run:merge` passes through is never read here** (joshuafolkken/kit#3781): its `stop` —
35
- // only person-waiting issues left — is spelled like the control one, and acting on it ended the run
36
- // without the idle watch. The loop asks `backlog:offer` on the next pass instead, so whether a parked
37
- // backlog waits or ends is `backlog:budget`'s alone, after a merge as after any other pass.
38
- type TokenHandling = 'hand-back' | 'stop' | 'await'
39
- const TOKEN_HANDLING: Readonly<Record<MergeToken, TokenHandling>> = {
40
- [MERGE_TOKEN.OVER]: 'hand-back',
41
- [MERGE_TOKEN.HUMAN_REVIEW]: 'hand-back',
42
- [MERGE_TOKEN.ENVIRONMENT]: 'hand-back',
43
- [MERGE_TOKEN.BUSY]: 'hand-back',
44
- [MERGE_TOKEN.RETRY]: 'hand-back',
45
- [MERGE_TOKEN.STOP]: 'stop',
46
- [MERGE_TOKEN.RESUMED]: 'await',
47
- }
48
-
49
- function tokens_handled(...handlings: ReadonlyArray<TokenHandling>): ReadonlySet<string> {
50
- const entries = Object.entries(TOKEN_HANDLING)
51
-
52
- return new Set(entries.filter(([, handling]) => handlings.includes(handling)).map(([key]) => key))
53
- }
54
-
55
- const IMMEDIATE_TOKENS = tokens_handled('hand-back')
56
- // Every token `run:merge` prints first even on a non-zero exit.
57
- const HANDOFF_TOKENS = tokens_handled('hand-back', 'stop')
58
- const MERGED_OUTCOME = 'merged'
36
+ // The outcomes that keep a child out of the rest of this run's offers.
37
+ const EXCLUDED_OUTCOMES: ReadonlySet<string> = new Set(['merged', 'withdrawn'])
59
38
  const WATCH_VERDICT = 'watch'
60
39
  // The verdicts the loop acts on without the parent. Any other is handed back as it was printed.
61
40
  const KNOWN_VERDICTS: ReadonlySet<string> = new Set([
@@ -71,11 +50,13 @@ const JUDGE_REASON = 'judge'
71
50
  const LAUNCHED = 'launched'
72
51
  const UNOPENED = 'unopened'
73
52
 
74
- interface OfferRead {
53
+ interface OfferRead extends HeldWaiting {
75
54
  verdict: string
76
55
  issues: ReadonlyArray<string>
77
56
  retries: number
78
57
  answer?: string | undefined
58
+ // Why a `blocked` answer started nothing — `solo`, or `backlog-wait-cause.ts`'s with its `waiting`.
59
+ cause?: string | undefined
79
60
  reason?: string | undefined
80
61
  // Whether a drain here owes the retrospective: the opt-in switch is on and it has not run yet. Absent
81
62
  // reads as not owed, so a drain with the switch off keeps the idle watch.
@@ -98,6 +79,8 @@ interface DriveState {
98
79
  stop_is_finish?: boolean | undefined
99
80
  // The child whose merge answered `stop`, carried on the resume line: no offer re-derives that stop.
100
81
  stopped_by?: string | undefined
82
+ // The last offer answered `run` on a machine with no memory to spare (`backlog-drive-memory.ts`).
83
+ is_memory_held?: boolean | undefined
101
84
  }
102
85
 
103
86
  interface DriveEnd {
@@ -118,6 +101,9 @@ interface DrivePorts {
118
101
  is_finished: (issue: string) => boolean
119
102
  // `run:merge <N>`'s first stdout token and the outcome it handled the child as.
120
103
  merge: (issue: string) => Promise<Collected>
104
+ // The lanes on a child this run launched and never settled that the loop does not hold — one the
105
+ // parent dispatched itself with `lane:launch` (`backlog_drive_adopt.adoptable` in production).
106
+ adoptable: (in_flight: ReadonlyArray<string>) => Promise<ReadonlyArray<string>>
121
107
  // `backlog:offer`'s answer for the state, or `undefined` when it exited non-zero.
122
108
  offer: (state: DriveState) => Promise<OfferRead | undefined>
123
109
  // Where `lane:launch`'s chain ended — `launched`, `unopened` (no lane taken) or `failed` (one taken).
@@ -125,12 +111,26 @@ interface DrivePorts {
125
111
  // The lanes free right now — `backlog_ready.drive_free_lane_count` in production, the limit less the
126
112
  // open lanes.
127
113
  free_lanes: () => Promise<number>
128
- // Whether the issue already holds a kept lane (one a child was dispatched into) — it is reused, so it
129
- // takes no free seat.
114
+ // The places left under the limit, port seats aside — `backlog_ready.drive_limit_room` in production.
115
+ limit_room: () => Promise<number>
116
+ // Whether the issue already holds a kept lane (one a child was dispatched into) — it is reused, and
117
+ // seated ahead of a fresh launch inside the limit room (`backlog-drive-seats.ts`).
130
118
  has_lane: (issue: string) => Promise<boolean>
131
119
  // How many open issues lacking `auto-ok` still owe a judgement — `auto_ok_judge_read.owed` in
132
120
  // production, `0` when the read failed.
133
121
  judgement_owed: () => Promise<number>
122
+ // Whether the machine has no memory for one more lane — `backlog_drive_memory.gauge()` in production,
123
+ // which carries its hysteresis between calls.
124
+ memory_held: () => Promise<boolean>
125
+ // Why an offered pass started nothing (`backlog-drive-hold.ts`). Production records it in the lane
126
+ // ledger only while a lane is free. `undefined` is the run's stop, which owes no lane a child.
127
+ hold: (reason: string | undefined, waiting?: ReadonlyArray<number>) => Promise<void>
128
+ // A watch with nothing in flight — the one idle notification (`backlog-drive-idle.ts`), deduplicated
129
+ // per episode by the port itself.
130
+ idle: (state: DriveState) => Promise<void>
131
+ // A holding offer with nothing in flight — the paused-lane notice (`backlog-drive-paused.ts`), which
132
+ // reads the lane records itself and is deduplicated per pause episode by the port.
133
+ paused: () => Promise<void>
134
134
  now: () => Date
135
135
  }
136
136
 
@@ -154,20 +154,12 @@ function ended(reason: string, state: DriveState, token?: string, issue?: string
154
154
  }
155
155
  }
156
156
 
157
- // Only an empty backlog drains: `backlog:offer` marks the drain on `exhausted` alone, so a watch over a
158
- // parked or unreadable backlog has no retrospective for `run:step` to fire and stays the driver's.
159
- function is_drain(read: OfferRead, state: DriveState): boolean {
157
+ // A drain owing the retrospective, read under a `watch` or a `stop` verdict. Only an empty backlog
158
+ // drains: `backlog:offer` marks the drain on `exhausted` alone, so a watch over a parked or unreadable
159
+ // backlog has no retrospective for `run:step` to fire and stays the driver's.
160
+ function is_drain_owed(read: OfferRead, state: DriveState, verdict: string): boolean {
160
161
  return (
161
- read.verdict === WATCH_VERDICT &&
162
- read.answer === EXHAUSTED_ANSWER &&
163
- state.in_flight.length === 0 &&
164
- read.is_retrospective_owed === true
165
- )
166
- }
167
-
168
- function needs_retrospective(read: OfferRead, state: DriveState): boolean {
169
- return (
170
- read.verdict === STOP_VERDICT &&
162
+ read.verdict === verdict &&
171
163
  read.answer === EXHAUSTED_ANSWER &&
172
164
  state.in_flight.length === 0 &&
173
165
  read.is_retrospective_owed === true
@@ -196,10 +188,12 @@ function merge_stopped(issue: string, state: DriveState): DriveState {
196
188
  }
197
189
  }
198
190
 
199
- // Only a merged child is excluded: `backlog:next` may still read it OPEN. Any other is classified by
200
- // its labels, so excluding it would hide a child a person released for the rest of the process.
191
+ // A merged child is excluded because `backlog:next` may still read it OPEN, and a withdrawn one because
192
+ // `lane:withdraw` leaves it OPEN for the next run, not this one (joshuafolkken/kit#4365). Any other is
193
+ // classified by its labels, so excluding it would hide a child a person released for the rest of the
194
+ // process.
201
195
  function excluded(issue: string, outcome: Collected['outcome'], state: DriveState): Array<string> {
202
- if (outcome !== MERGED_OUTCOME || state.exclude.includes(issue)) return state.exclude
196
+ if (!EXCLUDED_OUTCOMES.has(outcome) || state.exclude.includes(issue)) return state.exclude
203
197
 
204
198
  return [...state.exclude, issue]
205
199
  }
@@ -251,6 +245,8 @@ async function collect_finished(state: DriveState, ports: DrivePorts): Promise<P
251
245
  current = result.state
252
246
  }
253
247
 
248
+ await backlog_drive_hold.stopped(state, current, ports)
249
+
254
250
  return { kind: 'continue', state: current }
255
251
  }
256
252
 
@@ -271,8 +267,8 @@ async function refused(
271
267
 
272
268
  // **No more new lanes than free lanes**. `backlog:offer` lists every ready issue without reading the
273
269
  // lanes, so launching all of them overran `JOSH_LANE_LIMIT` until `lane:open` ran out of seats. An issue
274
- // that already holds a kept lane reuses it and takes no seat (`backlog-drive-seats.ts`); the rest launch
275
- // up to the free count, read once before the first launch.
270
+ // that already holds a kept lane reuses its port seat but takes a place under the limit, ahead of a
271
+ // fresh launch; the rest launch up to the free count (`backlog-drive-seats.ts`), read before the first.
276
272
  //
277
273
  // **Only a launch is activity**: a pass that started nothing — every lane taken
278
274
  // — keeps `active` where it was, or the once-a-minute offer would restart the idle budget for good.
@@ -310,7 +306,10 @@ async function launch_all(
310
306
  // parent's. With children still running the watch is only waiting on them.
311
307
  function on_verdict(read: OfferRead, state: DriveState): PassResult {
312
308
  if (!KNOWN_VERDICTS.has(read.verdict)) return ended(read.verdict, state, read.verdict)
313
- if (needs_retrospective(read, state)) return ended('retrospective', state, 'retrospective')
309
+
310
+ if (is_drain_owed(read, state, STOP_VERDICT)) {
311
+ return ended('retrospective', state, 'retrospective')
312
+ }
314
313
 
315
314
  if (read.verdict === STOP_VERDICT) {
316
315
  return {
@@ -324,43 +323,44 @@ function on_verdict(read: OfferRead, state: DriveState): PassResult {
324
323
  }
325
324
  }
326
325
 
327
- if (is_drain(read, state)) return ended(WATCH_VERDICT, state, WATCH_VERDICT)
326
+ if (is_drain_owed(read, state, WATCH_VERDICT)) return ended(WATCH_VERDICT, state, WATCH_VERDICT)
328
327
 
329
328
  return { kind: 'continue', state }
330
329
  }
331
330
 
332
- // **A free lane with nothing opted in is the open backlog's turn to be judged**
333
- // (joshuafolkken/kit#3854): a watch over an exhausted pool hands back `judge` while an open issue
334
- // lacking `auto-ok` still owes a judgement, ahead of the drain it would otherwise be. Once every one
335
- // carries its judgement comment the count is zero and the watch is the driver's again.
336
- async function is_judgement_owed(read: OfferRead, ports: DrivePorts): Promise<boolean> {
337
- const is_exhausted = read.verdict === WATCH_VERDICT && read.answer === EXHAUSTED_ANSWER
338
-
339
- if (!is_exhausted || (await ports.free_lanes()) <= NO_FREE_LANES) return false
331
+ // An offer answered `run`: launched while the machine has memory to spare, held until it does otherwise.
332
+ async function run_offered(
333
+ issues: ReadonlyArray<string>,
334
+ state: DriveState,
335
+ ports: DrivePorts,
336
+ ): Promise<PassResult> {
337
+ if (await ports.memory_held()) return await backlog_drive_memory.held(state, ports)
340
338
 
341
- return (await ports.judgement_owed()) > 0
339
+ return await launch_all(issues, state, ports)
342
340
  }
343
341
 
342
+ // Every offer answers the memory hold afresh: one that is not `run` leaves nothing held for memory.
344
343
  async function ask_offer(state: DriveState, ports: DrivePorts): Promise<PassResult> {
345
344
  const read = await ports.offer(state)
346
345
 
347
346
  if (read === undefined) return ended('offer', state)
348
347
 
349
- const next = { ...state, retries: read.retries }
348
+ const next = { ...state, retries: read.retries, is_memory_held: false }
350
349
 
351
- if (read.verdict === RUN_VERDICT) return await launch_all(read.issues, next, ports)
352
- if (await is_judgement_owed(read, ports)) return ended(JUDGE_REASON, next, JUDGE_REASON)
350
+ if (read.verdict === RUN_VERDICT) return await run_offered(read.issues, next, ports)
351
+ if (await backlog_drive_judge.is_owed(read, ports)) return ended(JUDGE_REASON, next, JUDGE_REASON)
353
352
 
354
- return on_verdict(read, next)
353
+ const idle = await backlog_drive_idle.noticed(on_verdict(read, next), read, ports)
354
+ const result = await backlog_drive_paused.noticed(idle, read, ports)
355
+
356
+ return await backlog_drive_hold.held(result, read, ports)
355
357
  }
356
358
 
357
359
  // One pass: collect every child that ended, then — unless a `stop` has been read — ask what to start.
358
360
  // `should_offer` is the caller's throttle on the one network read; a collection always asks, because a
359
361
  // lane just freed.
360
362
  function is_offering(before: DriveState, after: DriveState, should_offer: boolean): boolean {
361
- if (after.is_stopping) return false
362
-
363
- return should_offer || after.in_flight.length !== before.in_flight.length
363
+ return !after.is_stopping && (should_offer || after.in_flight.length !== before.in_flight.length)
364
364
  }
365
365
 
366
366
  // A stopping run with nothing left in flight has ended.
@@ -377,10 +377,11 @@ async function run_pass(
377
377
  should_offer: boolean,
378
378
  ports: DrivePorts,
379
379
  ): Promise<PassResult> {
380
- const collected = await collect_finished(state, ports)
380
+ const held = await backlog_drive_adopt.held(state, should_offer, ports)
381
+ const collected = await collect_finished(held, ports)
381
382
 
382
383
  if (collected.kind === 'end') return collected
383
- if (!is_offering(state, collected.state, should_offer)) return settle(collected)
384
+ if (!is_offering(held, collected.state, should_offer)) return settle(collected)
384
385
 
385
386
  return settle(await ask_offer(collected.state, ports))
386
387
  }
@@ -419,10 +420,13 @@ function is_window_spent(run: LoopRun, config: LoopConfig, now_ms: number): bool
419
420
  type LoopStep = { kind: 'end'; end: DriveEnd } | { kind: 'next'; run: LoopRun }
420
421
 
421
422
  // One pass of the loop: the offer is due on the first pass and then no oftener than `offer_ms`, bar the
422
- // passes that collected a child. A `next` carries the run to sleep on and pass again.
423
+ // passes that collected a child and the one that finds a memory hold cleared. A `next` carries the run
424
+ // to sleep on and pass again.
423
425
  async function loop_step(run: LoopRun, config: LoopConfig, ports: LoopPorts): Promise<LoopStep> {
424
426
  const now_ms = ports.now().getTime()
425
- const is_due = now_ms - run.offered_ms >= config.offer_ms
427
+ const is_due =
428
+ now_ms - run.offered_ms >= config.offer_ms ||
429
+ (await backlog_drive_memory.is_cleared(run.state, ports))
426
430
  const result = await run_pass(run.state, is_due, ports)
427
431
 
428
432
  ports.on_state(result.state)
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { backlog_next } from './backlog-next'
4
+
5
+ // The `josh backlog:next` entry, kept apart from `backlog-next.ts` because other modules import that
6
+ // one: a bundle is one file, so a main guard there would fire for every command that carries it
7
+ // (joshuafolkken/kit#4186).
8
+ //
9
+ // `process.exitCode` rather than `process.exit()`, for the reason `auto-ok:next` records: the whole
10
+ // contract is `answers=$(pnpm josh backlog:next)`, 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 = await backlog_next.run(process.argv.slice(ARGV_OFFSET))
16
+ }