@joshuafolkken/kit 1.1514.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 (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -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
+ }
@@ -0,0 +1,73 @@
1
+ import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
2
+ import { shared_cache, type CacheSlot } from '#scripts/josh/shared-cache'
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 { z } from 'zod'
6
+ import { backlog_next } from './backlog-next'
7
+
8
+ // One `josh backlog:next` answer shared by every reader that asks it within a minute
9
+ // (joshuafolkken/kit#4550).
10
+ //
11
+ // **The drive's assignment and the arrival probe each ask every minute, and since a lane waiting on its
12
+ // merge frees its slot (joshuafolkken/kit#4483) a free slot is the usual state** — so both read the
13
+ // whole pool from GitHub every minute, for the same answer.
14
+ //
15
+ // **The key carries the newest event on the run's stream**, so a launch, a merge or a park — anything
16
+ // that can change what may start — is never answered from before it: the first ask after it reads
17
+ // again. Only an answer that read is kept; a failure or a `retry` is asked again by the next reader.
18
+
19
+ const SUCCESS_EXIT_CODE = 0
20
+
21
+ const NEXT_CACHE: CacheSlot = { prefix: 'josh-backlog-next-', ttl_ms: 60_000 }
22
+
23
+ const result_schema = z.object({
24
+ code: z.number(),
25
+ out: z.string(),
26
+ err: z.string().exactOptional(),
27
+ })
28
+
29
+ // The key a shared plan read is kept under: what was asked, and the newest event on the run's stream.
30
+ // `run:board`'s plan read keys by it too (joshuafolkken/kit#4558).
31
+ async function stream_key(scope: unknown): Promise<string> {
32
+ const target = await run_event_stream_emit.stream_target()
33
+ const last = target === undefined ? undefined : run_event_stream.read_last(target)
34
+
35
+ return JSON.stringify({ argv: scope, last })
36
+ }
37
+
38
+ function is_kept(result: JoshResult): boolean {
39
+ if (result.code !== SUCCESS_EXIT_CODE) return false
40
+
41
+ return !result.out.split('\n').includes(backlog_next.VERDICT_TOKENS.retry)
42
+ }
43
+
44
+ // A kept answer replays its explanation where the live one would have streamed it.
45
+ function replay(result: JoshResult, should_forward_stderr: boolean): JoshResult {
46
+ if (should_forward_stderr && result.err !== undefined && result.err !== '') {
47
+ console.error(result.err)
48
+ }
49
+
50
+ return result
51
+ }
52
+
53
+ async function read(
54
+ argv: ReadonlyArray<string>,
55
+ should_forward_stderr = false,
56
+ timeout_ms?: number,
57
+ ): Promise<JoshResult> {
58
+ const key = await stream_key(argv)
59
+ const now_ms = Date.now()
60
+ const kept = shared_cache.read(NEXT_CACHE, key, result_schema, now_ms)
61
+
62
+ if (kept !== undefined) return replay(kept, should_forward_stderr)
63
+
64
+ const result = await josh_command.josh_run(argv, should_forward_stderr, timeout_ms)
65
+
66
+ if (is_kept(result)) shared_cache.write(NEXT_CACHE, key, result, now_ms)
67
+
68
+ return result
69
+ }
70
+
71
+ const backlog_next_shared = { NEXT_CACHE, read, stream_key }
72
+
73
+ export { backlog_next_shared }
@@ -1,4 +1,3 @@
1
- import { fileURLToPath } from 'node:url'
2
1
  import { auto_ok_cli, type OptedInRead, type TrackingRead } from '#scripts/auto-ok/auto-ok-cli'
3
2
  import { repo_discovery } from '#scripts/discovery/repo-discovery'
4
3
  import { epic_bundle_gaps } from '#scripts/epic/epic-bundle-gaps'
@@ -13,11 +12,16 @@ import { epic_solo_stale } from '#scripts/epic/epic-solo-stale'
13
12
  import { epic_triage, type TriageVerdict } from '#scripts/epic/epic-triage'
14
13
  import { git_gh_command } from '#scripts/gh/git-gh-command'
15
14
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
15
+ import { issue_not_before } from '#scripts/issue/issue-not-before'
16
+ import { issue_not_before_label } from '#scripts/issue/issue-not-before-label'
17
+ import { session_cite } from '#scripts/issue/session-cite'
18
+ import { lane_state } from '#scripts/lane/lane-state'
16
19
  import { issue_citation } from '#scripts/rules/issue-citation'
17
20
  import { backlog_defect_priority } from './backlog-defect-priority'
18
21
  import { backlog_overlap } from './backlog-overlap'
19
22
  import { backlog_pool } from './backlog-pool'
20
23
  import { backlog_rank, type GateScope } from './backlog-rank'
24
+ import { backlog_wait_cause } from './backlog-wait-cause'
21
25
 
22
26
  // `josh backlog:next` — what the whole opted-in backlog may run next.
23
27
  //
@@ -30,7 +34,6 @@ import { backlog_rank, type GateScope } from './backlog-rank'
30
34
  // `auto-ok:next`'s own listing and runnability rules, and the verdict comes from
31
35
  // `epic_report.decide_verdict` so it cannot drift from what `epic:next` means by the same word.
32
36
 
33
- const ARGV_OFFSET = 2
34
37
  const SUCCESS_EXIT_CODE = 0
35
38
  const FAILURE_EXIT_CODE = 1
36
39
 
@@ -130,6 +133,31 @@ function warn_gaps(context: PoolContext, has_answer: boolean): void {
130
133
  warn_epic_gap(context)
131
134
  }
132
135
 
136
+ // Why a row on the time side is not offered yet, when the reason is a declared start time or sample
137
+ // condition — the waits a reader cannot see from the labels or the blockers. A sample condition names
138
+ // its pull request as `#N`, linkified like the explanation.
139
+ function warn_not_before(context: PoolContext): void {
140
+ for (const issue of context.opted_in.issues) {
141
+ const reason = issue_not_before.waiting_reason(issue.body)
142
+
143
+ if (reason === undefined) continue
144
+
145
+ const cited = session_cite.issue(issue.number, undefined, context.repo)
146
+
147
+ console.error(`${cited} ${issue_citation.linkify(reason, context.repo)}`)
148
+ }
149
+ }
150
+
151
+ // Which waiting issues hold the backlog on a dependency chain or a start condition, read back by
152
+ // `backlog:offer` so a lane held by them is told apart in `lane:stats` (joshuafolkken/kit#4513).
153
+ function warn_wait_causes(result: EpicNextResult, context: PoolContext): void {
154
+ const causes = backlog_wait_cause.classify(result.waiting, context.repo)
155
+
156
+ for (const line of backlog_wait_cause.lines_of(causes)) {
157
+ console.error(issue_citation.linkify(line, context.repo))
158
+ }
159
+ }
160
+
133
161
  function report(result: EpicNextResult, context: PoolContext): number {
134
162
  warn_gaps(context, result.verdict === 'run')
135
163
  // The explanation names epics and children as `#N` (`tracked by epic #N`); linkified so the text a
@@ -139,8 +167,12 @@ function report(result: EpicNextResult, context: PoolContext): number {
139
167
  const explanation = epic_report.format_result(result, context.repo)
140
168
 
141
169
  console.error(issue_citation.linkify(explanation, context.repo))
170
+ warn_not_before(context)
142
171
 
143
- for (const token of tokens_of(result, context.repo)) console.info(token)
172
+ const tokens = tokens_of(result, context.repo)
173
+
174
+ if (tokens[0] === VERDICT_TOKENS.wait) warn_wait_causes(result, context)
175
+ for (const token of tokens) console.info(token)
144
176
 
145
177
  return SUCCESS_EXIT_CODE
146
178
  }
@@ -297,11 +329,15 @@ function standalone_keys(context: PoolContext): ReadonlySet<string> {
297
329
 
298
330
  // The running lanes still carry the pickup label, so the opted-in listing holds their bodies too —
299
331
  // which is what lets a candidate be held back from a path a running lane already declares.
300
- // `backlog:plan --waves` reads the same scope, so its first wave is this offer.
301
- function gate_scope(context: PoolContext): GateScope {
332
+ // `backlog:plan --waves` reads the same scope, so its first wave is this offer. Their lane state
333
+ // records name a paused holder in the wait it causes (joshuafolkken/kit#4270); they are local files.
334
+ async function gate_scope(context: PoolContext): Promise<GateScope> {
335
+ const { issues } = context.opted_in
336
+
302
337
  return {
303
338
  standalone: standalone_keys(context),
304
- declared: backlog_overlap.declared_of(context.opted_in.issues),
339
+ declared: backlog_overlap.declared_of(issues),
340
+ lanes: await lane_state.read_states(issues.map((issue) => String(issue.number))),
305
341
  }
306
342
  }
307
343
 
@@ -320,7 +356,7 @@ async function gate_solo(result: EpicNextResult, context: PoolContext): Promise<
320
356
 
321
357
  if (notice !== undefined) console.error(notice)
322
358
 
323
- const gated = backlog_rank.gate(result, read, repo, gate_scope(context))
359
+ const gated = backlog_rank.gate(result, read, repo, await gate_scope(context))
324
360
 
325
361
  if (gated.notice !== undefined) console.error(gated.notice)
326
362
 
@@ -393,6 +429,11 @@ async function context_of(
393
429
  }
394
430
 
395
431
  async function answer(opted_in: OptedIn, exclude: ReadonlyArray<number>): Promise<number> {
432
+ // The scan has every opted-in body and its labels already, so it keeps `not-before` in line with them
433
+ // and with every other issue the label is on — before any answer, so a drained backlog or a failed
434
+ // read still takes a passed label off.
435
+ await issue_not_before_label.sweep(opted_in.issues)
436
+
396
437
  if (opted_in.issues.length === 0) return report_none()
397
438
 
398
439
  const context = await context_of(opted_in, exclude)
@@ -422,13 +463,6 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
422
463
  return await answer(opted_in, options.exclude ?? [])
423
464
  }
424
465
 
425
- // `process.exitCode` rather than `process.exit()`, for the reason `auto-ok:next` records: the whole
426
- // contract is `answers=$(pnpm josh backlog:next)`, and exiting outright can cut the pipe before it
427
- // has drained.
428
- async function main(argv: ReadonlyArray<string>): Promise<void> {
429
- process.exitCode = await run(argv)
430
- }
431
-
432
466
  const backlog_next = {
433
467
  USAGE,
434
468
  REPO_UNREADABLE_MESSAGE,
@@ -441,7 +475,5 @@ const backlog_next = {
441
475
  run,
442
476
  }
443
477
 
444
- if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
445
-
446
478
  export { backlog_next }
447
479
  export type { BacklogVerdict, OptedIn, PoolContext }
@@ -1,56 +1,69 @@
1
1
  import type { LaneInfo } from '#scripts/lane/lane-registry'
2
- import type { RunEvent } from '#scripts/run/event/run-event-stream'
3
- import { run_invocation } from '#scripts/run/run-invocation'
4
- import { backlog_drive_restore } from './backlog-drive-restore'
2
+ import type { LaneRecords } from '#scripts/lane/lane-state'
5
3
 
6
4
  // The open lanes that hold a place under the lane limit — the one count `lane:limit`, the drive and
7
5
  // `run:board` all subtract from it.
8
6
  //
9
- // **A lane nobody will come back to holds no place.** A `--only` run works its named list and never
10
- // touches another lane, so a lane an earlier run left with no child in it would fill the limit for the
11
- // whole run, and the run's own issues would wait on it for good (joshuafolkken/kit#3967). Under a `--only`
12
- // run such a lane is not counted; its tree and branch stay, for the next run that names its issue.
7
+ // **A lane with no child working in it holds no place, whatever it waits on** (joshuafolkken/kit#4107).
8
+ // The limit caps the load on the machine, and a lane whose child is gone puts none on it — parked,
9
+ // blocked by another issue, waiting on a decision, or left by an earlier run (joshuafolkken/kit#3967,
10
+ // #4028). Its tree, branch and port seat stay; when its issue is picked up again the drive seats it
11
+ // ahead of a fresh launch, inside the free lanes (`backlog-drive-seats.ts`).
13
12
  //
14
- // **Everything else keeps its place, so the count errs toward fewer free lanes.** A run that drains
15
- // the pool may offer any open lane's issue again, a lane whose child still works is busy whoever owns
16
- // it, and with no run there is nobody to judge ownership for. The read stays local — no issue label is
17
- // read — because the count gates the network read behind it (`backlog-ready.ts`).
18
-
19
- interface OccupiedRead {
20
- // The live run's invocation, `undefined` when no run is live here.
21
- invocation: string | undefined
22
- // The live run's own events, for the issues it launched or settled; `undefined` where its scope
23
- // could not be told, which leaves every open lane counted.
24
- events: ReadonlyArray<RunEvent> | undefined
25
- // The issues whose lane has no child working in it; read only for a `--only` run.
26
- idle: (lanes: ReadonlyArray<LaneInfo>) => ReadonlyArray<string>
27
- }
28
-
29
- // The issues a `--only` run owns — those it names and those it launched or settled — or `undefined`
30
- // where there is no such run, or its events could not be scoped to it.
31
- function owned_issues(read: OccupiedRead): ReadonlySet<string> | undefined {
32
- const { invocation, events } = read
33
- const is_only = invocation !== undefined && run_invocation.has_only(invocation)
34
-
35
- if (!is_only || events === undefined) return undefined
13
+ // **A paused lane holds no place either** (joshuafolkken/kit#4201): a child `lane:pause` suspended
14
+ // puts no load on the machine until it is resumed. **Paused is the lane state record's answer alone**
15
+ // (joshuafolkken/kit#4270) — the `ps` state is not read — so a lane only `lane:pause` paused is
16
+ // uncounted. Its memory stays held, which the free-memory check reads as measured
17
+ // (`backlog-drive-memory.ts`); `lane:prune` still keeps it, since a child is there (`lane-spent.ts`).
18
+ //
19
+ // **A lane with no record is unknown, and keeps its place**, so the count errs toward fewer free
20
+ // lanes. **Whether a child is there at all is not the record's**:
21
+ // a child that parks or dies writes nothing, so only pgrep's own "no match" (`PROCESS_NONE`,
22
+ // `lane_spent.idle_lanes`) clears a lane, and a probe that did not answer keeps it. A stranded lane has
23
+ // no tree to work in and holds no place either. The reads stay local — no issue label is read —
24
+ // because the count gates the network read behind it (`backlog-ready.ts`).
25
+ //
26
+ // **A lane whose detached ship waits on its merge holds no place either** (joshuafolkken/kit#4466). The
27
+ // child ended at the hand-off, and while `josh followup` runs the supervisor only polls CI, CodeRabbit
28
+ // and the merge, so the slot is free for the next launch while every merge check still runs. The wait is
29
+ // unmarked while the followup stage merges and gates again (`run-ship-sync.ts`); a stop there counts
30
+ // the lane again, and past the limit the supervisor waits for a place before it relaunches the child
31
+ // (`run-ship-return.ts`). A named epic's offer discounts the same lanes (`epic-lane-offer.ts`).
36
32
 
37
- const named = (run_invocation.issue_numbers(invocation) ?? []).map(String)
33
+ // The issues whose lane has no child working in it (`lane_spent.idle_lanes`).
34
+ type IdleRead = (lanes: ReadonlyArray<LaneInfo>) => ReadonlyArray<string>
35
+ // Whether the lane of an issue has a detached ship waiting on its merge (`lane_handoff.merge_wait_reader`).
36
+ type MergeWaitRead = (issue: string) => boolean
38
37
 
39
- return new Set([...named, ...backlog_drive_restore.mentioned_issues(events)])
38
+ function is_never_merge_waiting(): boolean {
39
+ return false
40
40
  }
41
41
 
42
- function occupied_lanes(lanes: ReadonlyArray<LaneInfo>, read: OccupiedRead): Array<LaneInfo> {
42
+ function occupied_lanes(
43
+ lanes: ReadonlyArray<LaneInfo>,
44
+ idle: IdleRead,
45
+ records: LaneRecords,
46
+ is_merge_waiting: MergeWaitRead = is_never_merge_waiting,
47
+ ): Array<LaneInfo> {
43
48
  const live = lanes.filter((lane) => !lane.is_stranded)
44
- const owned = owned_issues(read)
45
-
46
- if (owned === undefined) return live
49
+ const idle_issues = new Set(idle(live))
47
50
 
48
- const idle = new Set(read.idle(live))
51
+ return live.filter(
52
+ (lane) =>
53
+ !idle_issues.has(lane.issue) &&
54
+ records.get(lane.issue)?.state !== 'paused' &&
55
+ !is_merge_waiting(lane.issue),
56
+ )
57
+ }
49
58
 
50
- return live.filter((lane) => owned.has(lane.issue) || !idle.has(lane.issue))
59
+ /** The issues of the live lanes in `lanes` that have no state record. */
60
+ function unknown_lanes(lanes: ReadonlyArray<LaneInfo>, records: LaneRecords): Array<string> {
61
+ return lanes
62
+ .filter((lane) => !lane.is_stranded && !records.has(lane.issue))
63
+ .map((lane) => lane.issue)
51
64
  }
52
65
 
53
- const backlog_occupied = { occupied_lanes }
66
+ const backlog_occupied = { occupied_lanes, unknown_lanes }
54
67
 
55
68
  export { backlog_occupied }
56
- export type { OccupiedRead }
69
+ export type { IdleRead, MergeWaitRead }