@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
@@ -0,0 +1,37 @@
1
+ // How often a waiting reservation re-reads the ledger: short enough that a freed place is taken up
2
+ // promptly, long enough that the wait itself burns no measurable CPU.
3
+ const POLL_INTERVAL_MS = 50
4
+ // The longest a reservation waits before it is admitted at minimum width regardless — a heavy step must
5
+ // make progress even if the budget never clears, so a leaked or wedged sibling cannot stall the machine
6
+ // for good. Two minutes is well past a unit suite's worst measured time under six-way load. A claim a
7
+ // swap stall holds is the exception (`core_admission.is_swap_held`).
8
+ const WAIT_CAP_MS = 120_000
9
+
10
+ // The clock and cadence a wait runs on, resolved apart from the ledger fields so `reserve` stays under
11
+ // the complexity limit — each default is a branch.
12
+ interface TimingConfig {
13
+ now: () => number
14
+ sleep: (ms: number) => Promise<void>
15
+ poll_interval_ms: number
16
+ wait_cap_ms: number
17
+ }
18
+
19
+ async function default_sleep(ms: number): Promise<void> {
20
+ await new Promise<void>((resolve) => {
21
+ setTimeout(resolve, ms)
22
+ })
23
+ }
24
+
25
+ function resolve_timing(options: Partial<TimingConfig>): TimingConfig {
26
+ return {
27
+ now: options.now ?? Date.now,
28
+ sleep: options.sleep ?? default_sleep,
29
+ poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
30
+ wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS,
31
+ }
32
+ }
33
+
34
+ const core_budget_timing = { resolve_timing }
35
+
36
+ export type { TimingConfig }
37
+ export { core_budget_timing }
@@ -9,8 +9,12 @@ import { stamp_file } from '#scripts/josh/stamp-file'
9
9
  import { json_value } from '#scripts/lib/json-value'
10
10
  import { unit_worker_share } from '#scripts/test/unit-worker-share'
11
11
  import { z } from 'zod'
12
+ import { busy_average, type BusySample } from './busy-average'
12
13
  import { core_admission, type Admission, type LedgerEntry, type Overflow } from './core-admission'
14
+ import { core_budget_timing, type TimingConfig } from './core-budget-timing'
13
15
  import { core_wait, type BudgetWait, type WaitReason } from './core-wait'
16
+ import { core_wait_record, type WaitSink } from './core-wait-record'
17
+ import { core_weights } from './core-weights'
14
18
  import { held_mark } from './held-mark'
15
19
  import { machine_capacity, type MachineBudget, type MachineReading } from './machine-capacity'
16
20
 
@@ -25,8 +29,9 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
25
29
  //
26
30
  // **A solo run is bit-for-bit unchanged, and that is arithmetic rather than a branch.** The gate's
27
31
  // weights are its `reserved_cores` (the static checks) and its `unit_worker_cap` (the unit suite), and
28
- // `reserved(2 + 1 + 1) + unit_cap(cores - 4)` is exactly `cores` — so a single gate's four claims sum
29
- // to the whole budget and every one is admitted the instant it is made, with no poll and no wait. Under
32
+ // `reserved(2 + 2 + 2) + unit_cap(cores - 6)` is exactly `cores` — so a single gate's four claims sum
33
+ // to the whole budget and, while the busy cores stay within what the ledger holds, every one is
34
+ // admitted the instant it is made, with no poll and no wait. Under
30
35
  // concurrency the same weights sum past the budget and the ledger is what holds the machine down.
31
36
  //
32
37
  // **Liveness is `process_identity`'s, reused rather than re-invented.** A run
@@ -41,66 +46,21 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
41
46
 
42
47
  const RESERVED_PREFIX = 'josh-core-reserved-'
43
48
  const RESERVED_SUFFIX = '.json'
44
- // How often a waiting reservation re-reads the ledger: short enough that a freed place is taken up
45
- // promptly, long enough that the wait itself burns no measurable CPU.
46
- const POLL_INTERVAL_MS = 50
47
- // The longest a reservation waits before it is admitted at minimum width regardless — a heavy step must
48
- // make progress even if the budget never clears, so a leaked or wedged sibling cannot stall the machine
49
- // for good. Two minutes is well past a unit suite's worst measured time under six-way load.
50
- const WAIT_CAP_MS = 120_000
51
- // The head of the ledger is always admitted, so the smallest budget worth planning against is one core.
49
+ // The head of an unsaturated ledger is always admitted, so the smallest declared budget is one core.
52
50
  const MIN_BUDGET = 1
53
51
 
54
- // **The cores each heavy tool occupies, declared once for both places that reserve them**
55
- // `gate-plan.ts`'s checks and the `josh` commands that run the same tools
56
- // directly read these, so a direct `josh lint` claims what the gate's lint claims. The lint, type check
57
- // and spell check numbers are `gate-plan.ts`'s measured table, floored. The whole-tree eslint scan
58
- // behind `josh lines` and `josh refactor:scan` runs in one process: measured cold on the 11-core
59
- // machine on 2026-10-06, 113s of CPU over 98s of wall, so it gets one core.
60
- //
61
- // The rest ran outside the ledger until joshuafolkken/kit#3944, measured with `/usr/bin/time -l` on the
62
- // same machine on 2026-10-17 under a load average of 16. Every one stays under one core, so each takes
63
- // one: `prettier --check` over 40 staged files 2.1s of CPU over 1.7s of wall (`format`), `josh
64
- // retrospective` 16.5s over 19.8s, and a fresh lane's `pnpm install --frozen-lockfile` 1.9s over 6.1s.
65
- // `e2e` is the Playwright worker count `josh test:e2e` passes locally — the two-worker run CI already
66
- // sizes for its four-core runner — since kit has no e2e suite of its own to time.
67
- const CORE_WEIGHTS = {
68
- lint: 2,
69
- type_check: 1,
70
- spell_check: 1,
71
- eslint_scan: 1,
72
- format: 1,
73
- retrospective: 1,
74
- install: 1,
75
- e2e: 2,
76
- } as const
77
-
78
- // **The memory each heavy tool holds, declared beside its cores**: peak
79
- // resident size in MB, rounded up. Measured with `/usr/bin/time -l` on the 11-core / 18 GB machine on
80
- // 2026-10-07: the type check 1,244 MB, the spell check 330 MB, and one unit worker 319 MB over 54 test
81
- // files. Typed eslint was 1,207 MB over one directory and was observed at 1.6–2.4 GB per whole-tree
82
- // `eslint .` with three lanes running the same day, so lint and the whole-tree scan take that peak.
83
- // On 2026-10-17: prettier 260 MB, the retrospective 862 MB and a lane install 65 MB.
84
- const MEMORY_MB = {
85
- lint: 2400,
86
- type_check: 1300,
87
- spell_check: 350,
88
- eslint_scan: 2400,
89
- unit_worker: 350,
90
- format: 300,
91
- retrospective: 900,
92
- install: 100,
93
- } as const
94
-
95
52
  // `memory_mb` and `admitted_at` are optional so a marker an older `josh` wrote still reads: it holds no
96
53
  // declared memory, and it counts as load from outside the ledger until it is gone.
97
54
  // `command`, `checkout`, `lane`, `lanes_root` and `wait_reason` name a waiting claim on `run:board`
98
- // (`core-wait.ts`).
55
+ // (`core-wait.ts`). `is_unit` marks a unit suite's claim, which may be admitted narrowed to `granted`
56
+ // past the wait cap (`core_admission.narrowed_weight`).
99
57
  const reservation_schema = process_owner_schema.extend({
100
58
  weight: z.number(),
101
59
  claimed_at: z.number(),
102
60
  memory_mb: z.number().optional(),
103
61
  admitted_at: z.number().optional(),
62
+ is_unit: z.boolean().optional(),
63
+ granted: z.number().optional(),
104
64
  command: z.string().optional(),
105
65
  checkout: z.string().optional(),
106
66
  lane: z.string().optional(),
@@ -121,6 +81,8 @@ interface ReserveOptions {
121
81
  memory_mb?: number | undefined
122
82
  // What the claim is for, named on the waiting line and on `run:board`.
123
83
  command?: string | undefined
84
+ // A unit suite's claim, whose weight is its worker count.
85
+ is_unit?: boolean | undefined
124
86
  report?: (line: string) => void
125
87
  read_machine?: () => Promise<MachineReading>
126
88
  wait_cap_ms?: number
@@ -128,6 +90,8 @@ interface ReserveOptions {
128
90
  directory?: string
129
91
  now?: () => number
130
92
  sleep?: (ms: number) => Promise<void>
93
+ // Where a claim that waited records how long, once admitted (`core-wait-record.ts`).
94
+ record_wait?: WaitSink
131
95
  }
132
96
 
133
97
  interface Handle {
@@ -139,7 +103,7 @@ function marker_name(key: string): string {
139
103
  return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`
140
104
  }
141
105
 
142
- // **"Cannot tell" counts as live**, the same direction `unit-worker-share.ts` takes: being wrong that
106
+ // **"Cannot tell" counts as live**, the same direction `unit-run-marker.ts` takes: being wrong that
143
107
  // way costs a reservation a slower admission, while the other way admits past a run that is still there.
144
108
  function is_running(reservation: Reservation): boolean {
145
109
  return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false
@@ -155,7 +119,7 @@ function read_reservation(source: string): Reservation | undefined {
155
119
 
156
120
  // **A dead marker is removed, not merely skipped** — otherwise a reissued pid turns a leaked place into
157
121
  // a phantom that fills the budget for good. The unlink never throws: a marker this account may not
158
- // remove is left alone, exactly as `unit-worker-share.ts` leaves it.
122
+ // remove is left alone, exactly as `unit-run-marker.ts` leaves it.
159
123
  function sweep_marker(source: string): void {
160
124
  try {
161
125
  stamp_file.remove_stamp(source)
@@ -202,12 +166,6 @@ function normalize_budget(budget: number): number {
202
166
  return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET
203
167
  }
204
168
 
205
- async function default_sleep(ms: number): Promise<void> {
206
- await new Promise<void>((resolve) => {
207
- setTimeout(resolve, ms)
208
- })
209
- }
210
-
211
169
  // **Replaced atomically, never unlinked and recreated**: the admitted rewrite lands on a marker other
212
170
  // lanes are polling, and a reader that hit the gap between an unlink and its create would see the ledger
213
171
  // without this place and admit past it.
@@ -219,57 +177,52 @@ function report_wait(line: string): void {
219
177
  process.stderr.write(`${line}\n`)
220
178
  }
221
179
 
222
- // The clock and cadence a wait runs on, resolved apart from the ledger fields so `reserve` stays under
223
- // the complexity limit — each default is a branch.
224
- interface TimingConfig {
225
- now: () => number
226
- sleep: (ms: number) => Promise<void>
227
- poll_interval_ms: number
228
- wait_cap_ms: number
229
- }
230
-
231
180
  interface WaitContext extends TimingConfig {
232
181
  read_machine: () => Promise<MachineReading>
233
182
  report: (line: string) => void
183
+ record_wait: WaitSink | undefined
234
184
  key: string
235
185
  target: string
236
186
  directory: string
237
187
  budget: number
238
188
  deadline: number
239
189
  fields: ReservationFields
190
+ busy_samples: Array<BusySample>
240
191
  }
241
192
 
242
- function resolve_timing(options: ReserveOptions): TimingConfig {
243
- return {
244
- now: options.now ?? Date.now,
245
- sleep: options.sleep ?? default_sleep,
246
- poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
247
- wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS,
248
- }
249
- }
250
-
251
- // **A claim alone in the ledger reads nothing from the machine**: the head is admitted whatever the
252
- // budget says, so a solo run pays no sampling window and starts exactly as it did before.
193
+ // **A claim alone in the ledger reads the machine too** (joshuafolkken/kit#4238): load outside the
194
+ // ledger saturates the CPU whether or not another claim is in it. The busy cores are the mean of this
195
+ // wait's recent readings of load outside the ledger (`busy-average.ts`). That load holds every claim but
196
+ // the first waiter, which it narrows instead (`core_admission.is_admitted`, joshuafolkken/kit#4313) unless
197
+ // the run queue reads the machine overloaded (`machine_capacity.machine_budget`, joshuafolkken/kit#4361).
253
198
  async function current_budget(
254
199
  context: WaitContext,
255
200
  reservations: ReadonlyArray<LiveReservation>,
256
201
  ): Promise<MachineBudget> {
257
- if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity }
258
-
259
202
  const reading = await context.read_machine()
260
203
  const ledger = core_admission.ledger_load(reservations, context.now())
261
- const budget = machine_capacity.machine_budget(context.budget, reading, ledger)
262
204
 
263
- return { ...budget, cores: normalize_budget(budget.cores) }
205
+ context.busy_samples = busy_average.with_reading(
206
+ context.busy_samples,
207
+ reading,
208
+ ledger.cores,
209
+ context.now(),
210
+ )
211
+
212
+ const mean = busy_average.averaged(reading, context.busy_samples, ledger.cores)
213
+
214
+ return machine_capacity.machine_budget(context.budget, mean, ledger)
264
215
  }
265
216
 
266
217
  // The claim is admitted: its marker records when, which moves its load from "load outside the ledger"
267
218
  // to "load the ledger holds" for every later reader — its cores at once, its memory once its tool has
268
219
  // had time to ramp up.
269
- function admit(context: WaitContext, overflow?: Overflow): Admission {
270
- write_reservation(context.target, { ...context.fields, admitted_at: context.now() })
220
+ function admit(context: WaitContext, overflow?: Overflow, granted?: number): Admission {
221
+ const admitted_at = context.now()
271
222
 
272
- return { overflow }
223
+ write_reservation(context.target, { ...context.fields, admitted_at, granted })
224
+
225
+ return { overflow, granted, waited_ms: admitted_at - context.fields.claimed_at }
273
226
  }
274
227
 
275
228
  function overflow_of(
@@ -300,14 +253,24 @@ function mark_waiting(context: WaitContext, reason: WaitReason): void {
300
253
  async function poll_admission(context: WaitContext): Promise<Admission | undefined> {
301
254
  const reservations = live_reservations(context.directory)
302
255
  const budget = await current_budget(context, reservations)
256
+ // A unit claim is admitted at the room the budget leaves rather than at full width — the first
257
+ // waiter, which load outside the ledger does not hold, as well as one past the wait cap.
258
+ const granted = core_admission.narrowed_weight(context.key, reservations, budget.cores)
259
+ const reason = core_wait.hold_reason(context.key, reservations, budget, granted)
260
+
261
+ if (reason === undefined) return admit(context, undefined, granted)
303
262
 
304
- if (core_admission.is_admitted(context.key, reservations, budget)) return admit(context)
263
+ // Past the cap a held claim runs regardless, except one a swap stall holds.
264
+ if (
265
+ context.now() >= context.deadline &&
266
+ !core_admission.is_swap_held(context.key, reservations, budget)
267
+ ) {
268
+ const held = core_admission.with_grant(context.key, reservations, granted)
305
269
 
306
- if (context.now() >= context.deadline) {
307
- return admit(context, overflow_of(context, reservations, budget))
270
+ return admit(context, overflow_of(context, held, budget), granted)
308
271
  }
309
272
 
310
- mark_waiting(context, core_wait.wait_reason(context.key, reservations, budget))
273
+ mark_waiting(context, reason)
311
274
 
312
275
  return undefined
313
276
  }
@@ -325,14 +288,19 @@ async function await_admission(context: WaitContext): Promise<Admission> {
325
288
  admission = await poll_admission(context)
326
289
  }
327
290
 
291
+ await core_wait_record.record_admitted(context.fields, context.now(), context.record_wait)
292
+
328
293
  return admission
329
294
  }
330
295
 
331
- // What a wait reads the machine through and reports its start to.
332
- function resolve_ports(options: ReserveOptions): Pick<WaitContext, 'read_machine' | 'report'> {
296
+ // What a wait reads the machine through, reports its start to and records its length in.
297
+ function resolve_ports(
298
+ options: ReserveOptions,
299
+ ): Pick<WaitContext, 'read_machine' | 'report' | 'record_wait'> {
333
300
  return {
334
301
  read_machine: options.read_machine ?? machine_capacity.read_machine,
335
302
  report: options.report ?? report_wait,
303
+ record_wait: options.record_wait,
336
304
  }
337
305
  }
338
306
 
@@ -343,13 +311,13 @@ function claim_fields(
343
311
  claimed_at: number,
344
312
  options: ReserveOptions,
345
313
  ): ReservationFields {
346
- const { memory_mb, command } = options
314
+ const { memory_mb, command, is_unit } = options
347
315
 
348
- return { weight, claimed_at, memory_mb, command, ...core_wait.where_of(process.cwd()) }
316
+ return { weight, claimed_at, memory_mb, command, is_unit, ...core_wait.where_of(process.cwd()) }
349
317
  }
350
318
 
351
319
  async function reserve(weight: number, options: ReserveOptions = {}): Promise<Handle> {
352
- const timing = resolve_timing(options)
320
+ const timing = core_budget_timing.resolve_timing(options)
353
321
  const directory = options.directory ?? PLATFORM_TEMP_ROOT
354
322
  const claimed_at = timing.now()
355
323
  const name = marker_name(randomUUID())
@@ -365,6 +333,7 @@ async function reserve(weight: number, options: ReserveOptions = {}): Promise<Ha
365
333
  budget: normalize_budget(options.budget ?? availableParallelism()),
366
334
  deadline: claimed_at + timing.wait_cap_ms,
367
335
  fields,
336
+ busy_samples: [],
368
337
  ...resolve_ports(options),
369
338
  })
370
339
 
@@ -421,16 +390,29 @@ async function with_command_reservation<T>(
421
390
  )
422
391
  }
423
392
 
393
+ // The unit claim the parent command holds for this process (`with_command_reservation`), or
394
+ // `undefined` where none does. A held claim that is not a unit suite's says nothing about workers.
395
+ function held_unit_claim(directory: string = PLATFORM_TEMP_ROOT): Reservation | undefined {
396
+ const key = held_mark.held_reservation()
397
+
398
+ if (key === undefined) return undefined
399
+
400
+ const held = live_reservations(directory).find((entry) => entry.key === key)
401
+
402
+ return held?.reservation.is_unit === true ? held.reservation : undefined
403
+ }
404
+
424
405
  const core_budget = {
425
- CORE_WEIGHTS,
406
+ CORE_WEIGHTS: core_weights.CORE_WEIGHTS,
426
407
  HELD_KEY: held_mark.HELD_KEY,
427
408
  HELD_VALUE: held_mark.HELD_VALUE,
428
- MEMORY_MB,
409
+ MEMORY_MB: core_weights.MEMORY_MB,
429
410
  RESERVED_PREFIX,
430
411
  admitted_keys: core_admission.admitted_keys,
431
412
  admitted_load: core_admission.admitted_load,
432
413
  budget_waits,
433
414
  describe_overflow: core_admission.describe_overflow,
415
+ held_unit_claim,
434
416
  is_held: held_mark.is_held,
435
417
  live_reservations,
436
418
  release,
@@ -0,0 +1,48 @@
1
+ import { lane_ledger, type CoreWaitRecord } from '#scripts/lane/lane-ledger'
2
+
3
+ // How long a claim waited for the core budget, written to the lane ledger once it is admitted, so
4
+ // `josh lane:stats` can split a lane's time into work and waiting (joshuafolkken/kit#4382). The
5
+ // waiting line on stderr says a wait started; this says what it cost.
6
+ //
7
+ // **Only a claim that waited is recorded** — one admitted on its first read cost nothing, and a line per
8
+ // command would bury the waits a lane's time is split by. The lane is the claim's own checkout's, the
9
+ // one `run:board` names the waiting claim by.
10
+
11
+ const UNNAMED_COMMAND = 'a step'
12
+
13
+ // What `core-budget.ts` knows of the claim when it is admitted.
14
+ interface AdmittedClaim {
15
+ command?: string | undefined
16
+ lane?: string | undefined
17
+ wait_reason?: string | undefined
18
+ claimed_at: number
19
+ }
20
+
21
+ type WaitSink = (wait: CoreWaitRecord) => Promise<void>
22
+
23
+ async function to_ledger(wait: CoreWaitRecord): Promise<void> {
24
+ await lane_ledger.record_core_wait(wait)
25
+ }
26
+
27
+ function wait_of(claim: AdmittedClaim, now: number): CoreWaitRecord | undefined {
28
+ if (claim.wait_reason === undefined) return undefined
29
+
30
+ const wait = { command: claim.command ?? UNNAMED_COMMAND, waited_ms: now - claim.claimed_at }
31
+
32
+ return claim.lane === undefined ? wait : { ...wait, issue: Number(claim.lane) }
33
+ }
34
+
35
+ async function record_admitted(
36
+ claim: AdmittedClaim,
37
+ now: number,
38
+ sink: WaitSink = to_ledger,
39
+ ): Promise<void> {
40
+ const wait = wait_of(claim, now)
41
+
42
+ if (wait !== undefined) await sink(wait)
43
+ }
44
+
45
+ const core_wait_record = { record_admitted, wait_of }
46
+
47
+ export type { WaitSink }
48
+ export { core_wait_record }
@@ -9,13 +9,15 @@ import type { MachineBudget } from './machine-capacity'
9
9
  // says it once on its own output; `run:board` draws every marker still waiting. Everything here is a
10
10
  // pure function of the ledger and the budget it is handed.
11
11
 
12
- const WAIT_REASONS = ['cores', 'memory', 'pressure'] as const
12
+ const WAIT_REASONS = ['cores', 'cpu', 'memory', 'pressure'] as const
13
13
 
14
14
  type WaitReason = (typeof WAIT_REASONS)[number]
15
15
 
16
- // The one wording of each reason, shared by the waiting command's line and the board's.
16
+ // The one wording of each reason, on the waiting command's own line; the board draws the reason as the
17
+ // header's icon instead (joshuafolkken/kit#4052).
17
18
  const REASON_TEXT: Record<WaitReason, string> = {
18
19
  cores: 'not enough free cores',
20
+ cpu: 'CPU saturated',
19
21
  memory: 'not enough free memory',
20
22
  pressure: 'memory under pressure',
21
23
  }
@@ -49,6 +51,18 @@ interface BudgetWait extends BudgetPlace {
49
51
  reason: WaitReason
50
52
  }
51
53
 
54
+ // A claim short of cores waits on the CPU when it would fit on what the ledger declares — the cores it
55
+ // lacks are taken by busy load beyond the ledger (joshuafolkken/kit#4238) — and on the ledger otherwise.
56
+ function core_reason(
57
+ key: string,
58
+ reservations: ReadonlyArray<LedgerEntry>,
59
+ budget: MachineBudget,
60
+ ): WaitReason {
61
+ const declared = { cores: budget.cores + (budget.busy_excess ?? 0), memory_mb: Infinity }
62
+
63
+ return core_admission.is_admitted(key, reservations, declared) ? 'cpu' : 'cores'
64
+ }
65
+
52
66
  // **The cores decide first**: a claim that would not fit even with unlimited memory waits for cores;
53
67
  // one that fits on cores waits for memory, named as pressure when the reading saw compression or swap.
54
68
  function wait_reason(
@@ -56,13 +70,31 @@ function wait_reason(
56
70
  reservations: ReadonlyArray<LedgerEntry>,
57
71
  budget: MachineBudget,
58
72
  ): WaitReason {
59
- const cores_only = { cores: budget.cores, memory_mb: Infinity }
73
+ const cores_only = { ...budget, memory_mb: Infinity }
60
74
 
61
- if (!core_admission.is_admitted(key, reservations, cores_only)) return 'cores'
75
+ if (!core_admission.is_admitted(key, reservations, cores_only)) {
76
+ return core_reason(key, reservations, budget)
77
+ }
62
78
 
63
79
  return budget.memory_pressured === true ? 'pressure' : 'memory'
64
80
  }
65
81
 
82
+ // Why a claim is not admitted yet, or `undefined` once it is: a unit claim the budget admits only too
83
+ // narrow (`core_admission.is_too_narrow`) still waits, on the CPU — admitted, it fits what the ledger
84
+ // declares, so only busy load beyond the ledger narrowed it (`core_reason`).
85
+ function hold_reason(
86
+ key: string,
87
+ reservations: ReadonlyArray<LedgerEntry>,
88
+ budget: MachineBudget,
89
+ granted: number | undefined,
90
+ ): WaitReason | undefined {
91
+ if (!core_admission.is_admitted(key, reservations, budget)) {
92
+ return wait_reason(key, reservations, budget)
93
+ }
94
+
95
+ return core_admission.is_too_narrow(key, reservations, granted) ? 'cpu' : undefined
96
+ }
97
+
66
98
  // The line a waiting command prints once, when its wait starts.
67
99
  function wait_line(command: string | undefined, reason: WaitReason): string {
68
100
  return `⏳ ${command ?? 'a step'} waits for the core budget — ${REASON_TEXT[reason]}`
@@ -118,8 +150,8 @@ function waits_of(
118
150
  }
119
151
 
120
152
  const core_wait = {
121
- REASON_TEXT,
122
153
  WAIT_REASONS,
154
+ hold_reason,
123
155
  wait_line,
124
156
  wait_reason,
125
157
  waits_of,
@@ -0,0 +1,86 @@
1
+ // The weights heavy tools declare to the core budget (`core-budget.ts`), in their own module so the
2
+ // ledger's file stays under its line ceiling.
3
+
4
+ // One tool's measured run: its CPU seconds over its wall seconds, the cores it kept busy on average.
5
+ interface Measurement {
6
+ cpu_s: number
7
+ wall_s: number
8
+ }
9
+
10
+ // **What each heavy tool was measured at, on the 11-core machine.** The whole-tree eslint scan behind
11
+ // `josh lines` and `josh refactor:scan`, cold on 2026-10-06. eslint over 40 staged files
12
+ // (`pre-commit-lint.ts`), which the gate's lint also runs beside its sibling linters, so it is the
13
+ // lint's floor; whole runs were observed at 124–147% CPU. The type check and the spell check with
14
+ // `/usr/bin/time -l` on 2026-10-21 under a load average of 14. `prettier --check` over 40 staged
15
+ // files, `josh retrospective` and a fresh lane's `pnpm install --frozen-lockfile` with
16
+ // `/usr/bin/time -l` on 2026-10-17 under a load average of 16. The gate ledger records each check's
17
+ // CPU beside its duration (`check-cpu.ts`), so these can be re-measured from it.
18
+ const MEASURED = {
19
+ lint: { cpu_s: 16.9, wall_s: 14 },
20
+ type_check: { cpu_s: 31.2, wall_s: 27.3 },
21
+ spell_check: { cpu_s: 6, wall_s: 5.6 },
22
+ eslint_scan: { cpu_s: 113, wall_s: 98 },
23
+ format: { cpu_s: 2.1, wall_s: 1.7 },
24
+ retrospective: { cpu_s: 16.5, wall_s: 19.8 },
25
+ install: { cpu_s: 1.9, wall_s: 6.1 },
26
+ } as const satisfies Readonly<Record<string, Measurement>>
27
+
28
+ // **Rounded up, never down** (joshuafolkken/kit#4362): a weight is a whole number of cores, and the
29
+ // floored table of joshuafolkken/kit#3354 let a 1.15-core eslint scan claim one, so the budget admitted
30
+ // more than the machine had.
31
+ function rounded_up(measurement: Measurement): number {
32
+ return Math.ceil(measurement.cpu_s / measurement.wall_s)
33
+ }
34
+
35
+ // **The cores each heavy tool occupies, declared once for both places that reserve them**
36
+ // `gate-plan.ts`'s checks and the `josh` commands that run the same tools
37
+ // directly read these, so a direct `josh lint` claims what the gate's lint claims. Each is its
38
+ // measurement rounded up. `e2e` is the Playwright worker count `josh test:e2e` passes locally — the
39
+ // two-worker run CI already sizes for its four-core runner — since kit has no e2e suite of its own to
40
+ // time.
41
+ const CORE_WEIGHTS = {
42
+ lint: rounded_up(MEASURED.lint),
43
+ type_check: rounded_up(MEASURED.type_check),
44
+ spell_check: rounded_up(MEASURED.spell_check),
45
+ eslint_scan: rounded_up(MEASURED.eslint_scan),
46
+ format: rounded_up(MEASURED.format),
47
+ retrospective: rounded_up(MEASURED.retrospective),
48
+ install: rounded_up(MEASURED.install),
49
+ e2e: 2,
50
+ } as const
51
+
52
+ // **The memory each heavy tool holds, declared beside its cores**: peak
53
+ // resident size in MB, rounded up. Measured with `/usr/bin/time -l` on the 11-core / 18 GB machine on
54
+ // 2026-10-07: the type check 1,244 MB, the spell check 330 MB, and one unit worker 319 MB over 54 test
55
+ // files. Typed eslint was 1,207 MB over one directory and was observed at 1.6–2.4 GB per whole-tree
56
+ // `eslint .` with three lanes running the same day, so lint and the whole-tree scan take that peak.
57
+ // On 2026-10-17: prettier 260 MB, the retrospective 862 MB and a lane install 65 MB. On 2026-10-22
58
+ // (joshuafolkken/kit#4528) the whole suite, 1,830 files at `--maxWorkers=3` beside four lanes, sampled
59
+ // each worker's resident size once a second: the largest peaked at 381 MB, so the 54-file
60
+ // measurement had read a worker short of the files it lives through.
61
+ const MEMORY_MB = {
62
+ lint: 2400,
63
+ type_check: 1300,
64
+ spell_check: 350,
65
+ eslint_scan: 2400,
66
+ unit_worker: 400,
67
+ format: 300,
68
+ retrospective: 900,
69
+ install: 100,
70
+ } as const
71
+
72
+ // **The program a command launches, mapped to the `MEMORY_MB` row it holds** — the one table
73
+ // `command-memory.ts` reads a wrapped command's memory off. `install` is `pnpm install` read past its
74
+ // `pnpm` wrapper (`git_argv.program_of`).
75
+ const TOOL_MEMORY: Readonly<Partial<Record<string, keyof typeof MEMORY_MB>>> = {
76
+ eslint: 'lint',
77
+ tsc: 'type_check',
78
+ cspell: 'spell_check',
79
+ vitest: 'unit_worker',
80
+ prettier: 'format',
81
+ install: 'install',
82
+ }
83
+
84
+ const core_weights = { CORE_WEIGHTS, MEASURED, MEMORY_MB, TOOL_MEMORY }
85
+
86
+ export { core_weights }
@@ -1,12 +1,14 @@
1
1
  import { availableParallelism } from 'node:os'
2
+ import type { FreeCapacity } from '#scripts/test/unit-worker-share'
2
3
  import { core_admission } from './core-admission'
3
4
  import { core_budget, type LiveReservation } from './core-budget'
5
+ import { core_weights } from './core-weights'
4
6
  import { held_mark } from './held-mark'
5
7
  import { machine_capacity, type MachineReading } from './machine-capacity'
6
8
 
7
9
  // The cores a unit suite may open workers on: the core count less the load from outside the core
8
10
  // budget's ledger, the figure the ledger admits against (`machine_capacity.machine_budget`). The run
9
- // count in `unit-worker-share.ts` divides the machine between unit runs; this is what bounds that
11
+ // count in `unit-run-marker.ts` divides the machine between unit runs; this is what bounds that
10
12
  // division when something else holds the cores.
11
13
  //
12
14
  // Its own module because the reading needs the ledger, and `core-budget.ts` already imports
@@ -29,9 +31,7 @@ function running_claims(directory: string | undefined): Array<LiveReservation> {
29
31
 
30
32
  // `undefined` where the machine could not be read — a CI runner, a CPU quota narrower than the host —
31
33
  // which `unit_worker_share.cap_to_free` reads as the share as it was.
32
- async function read(options: FreeCoresOptions = {}): Promise<number | undefined> {
33
- const reading = await (options.read_machine ?? machine_capacity.read_machine)()
34
-
34
+ function free_of(reading: MachineReading, options: FreeCoresOptions): number | undefined {
35
35
  if (reading.busy_cores === undefined) return undefined
36
36
 
37
37
  const ledger = core_admission.ledger_load(running_claims(options.directory), Date.now())
@@ -43,6 +43,29 @@ async function read(options: FreeCoresOptions = {}): Promise<number | undefined>
43
43
  ).cores
44
44
  }
45
45
 
46
+ // **The workers the free memory holds** (joshuafolkken/kit#4528): the free memory over one worker's
47
+ // peak (`core_weights.MEMORY_MB.unit_worker`, where its measurement is recorded). Divided here, not in
48
+ // `unit-run-marker.ts`, which the vitest config imports — `core-weights.ts` there would widen every
49
+ // related run on it to the whole suite. The memory is the reading's own available figure, not the
50
+ // budget's: the ledger's held memory is added back there for admission's walk, and it is not free for
51
+ // this run's workers. `undefined` — a platform `machine-capacity.ts` reads no memory on — leaves the
52
+ // share as it was; a Linux CI runner reads `/proc/meminfo`, whose memory holds more workers than cores.
53
+ function workers_in_memory(available_mb: number | undefined): number | undefined {
54
+ if (available_mb === undefined) return undefined
55
+
56
+ return available_mb / core_weights.MEMORY_MB.unit_worker
57
+ }
58
+
59
+ // One reading answers both halves: the sample window is waited out once.
60
+ async function read(options: FreeCoresOptions = {}): Promise<FreeCapacity> {
61
+ const reading = await (options.read_machine ?? machine_capacity.read_machine)()
62
+
63
+ return {
64
+ cores: free_of(reading, options),
65
+ memory_workers: workers_in_memory(reading.available_mb),
66
+ }
67
+ }
68
+
46
69
  const free_cores = { read }
47
70
 
48
71
  export type { FreeCoresOptions }