@joshuafolkken/kit 1.1471.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -9,7 +9,13 @@ 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'
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'
18
+ import { held_mark } from './held-mark'
13
19
  import { machine_capacity, type MachineBudget, type MachineReading } from './machine-capacity'
14
20
 
15
21
  // A machine-wide weighted core budget with admission control.
@@ -23,8 +29,9 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
23
29
  //
24
30
  // **A solo run is bit-for-bit unchanged, and that is arithmetic rather than a branch.** The gate's
25
31
  // weights are its `reserved_cores` (the static checks) and its `unit_worker_cap` (the unit suite), and
26
- // `reserved(2 + 1 + 1) + unit_cap(cores - 4)` is exactly `cores` — so a single gate's four claims sum
27
- // 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
28
35
  // concurrency the same weights sum past the budget and the ledger is what holds the machine down.
29
36
  //
30
37
  // **Liveness is `process_identity`'s, reused rather than re-invented.** A run
@@ -39,61 +46,31 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
39
46
 
40
47
  const RESERVED_PREFIX = 'josh-core-reserved-'
41
48
  const RESERVED_SUFFIX = '.json'
42
- // How often a waiting reservation re-reads the ledger: short enough that a freed place is taken up
43
- // promptly, long enough that the wait itself burns no measurable CPU.
44
- const POLL_INTERVAL_MS = 50
45
- // The longest a reservation waits before it is admitted at minimum width regardless — a heavy step must
46
- // make progress even if the budget never clears, so a leaked or wedged sibling cannot stall the machine
47
- // for good. Two minutes is well past a unit suite's worst measured time under six-way load.
48
- const WAIT_CAP_MS = 120_000
49
- // 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.
50
50
  const MIN_BUDGET = 1
51
51
 
52
- // **The cores each heavy tool occupies, declared once for both places that reserve them**
53
- // `gate-plan.ts`'s checks and the `josh` commands that run the same tools
54
- // directly read these, so a direct `josh lint` claims what the gate's lint claims. The lint, type check
55
- // and spell check numbers are `gate-plan.ts`'s measured table, floored. The whole-tree eslint scan
56
- // behind `josh lines` and `josh refactor:scan` runs in one process: measured cold on the 11-core
57
- // machine on 2026-10-06, 113s of CPU over 98s of wall, so it gets one core.
58
- const CORE_WEIGHTS = {
59
- lint: 2,
60
- type_check: 1,
61
- spell_check: 1,
62
- eslint_scan: 1,
63
- } as const
64
-
65
- // **The memory each heavy tool holds, declared beside its cores**: peak
66
- // resident size in MB, rounded up. Measured with `/usr/bin/time -l` on the 11-core / 18 GB machine on
67
- // 2026-10-07: the type check 1,244 MB, the spell check 330 MB, and one unit worker 319 MB over 54 test
68
- // files. Typed eslint was 1,207 MB over one directory and was observed at 1.6–2.4 GB per whole-tree
69
- // `eslint .` with three lanes running the same day, so lint and the whole-tree scan take that peak.
70
- const MEMORY_MB = {
71
- lint: 2400,
72
- type_check: 1300,
73
- spell_check: 350,
74
- eslint_scan: 2400,
75
- unit_worker: 350,
76
- } as const
77
-
78
- // **The environment mark that says a parent already holds this process's cores**
79
- // `josh gate` reserves per check and then spawns `pnpm josh lint`. Without
80
- // the mark, that child's own dispatch would claim a second place for the cores its parent already
81
- // holds. Every holder sets it, and every child inherits it through the environment and claims nothing.
82
- const HELD_KEY = 'JOSH_CORE_RESERVED'
83
- const HELD_VALUE = '1'
84
-
85
52
  // `memory_mb` and `admitted_at` are optional so a marker an older `josh` wrote still reads: it holds no
86
53
  // declared memory, and it counts as load from outside the ledger until it is gone.
54
+ // `command`, `checkout`, `lane`, `lanes_root` and `wait_reason` name a waiting claim on `run:board`
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`).
87
57
  const reservation_schema = process_owner_schema.extend({
88
58
  weight: z.number(),
89
59
  claimed_at: z.number(),
90
60
  memory_mb: z.number().optional(),
91
61
  admitted_at: z.number().optional(),
62
+ is_unit: z.boolean().optional(),
63
+ granted: z.number().optional(),
64
+ command: z.string().optional(),
65
+ checkout: z.string().optional(),
66
+ lane: z.string().optional(),
67
+ lanes_root: z.string().optional(),
68
+ wait_reason: z.enum(core_wait.WAIT_REASONS).optional(),
92
69
  })
93
70
 
94
71
  type Reservation = z.infer<typeof reservation_schema>
95
72
 
96
- type ReservationFields = Pick<Reservation, 'weight' | 'claimed_at' | 'memory_mb' | 'admitted_at'>
73
+ type ReservationFields = Omit<Reservation, 'pid' | 'process_start'>
97
74
 
98
75
  interface LiveReservation extends LedgerEntry {
99
76
  reservation: Reservation
@@ -102,12 +79,19 @@ interface LiveReservation extends LedgerEntry {
102
79
  interface ReserveOptions {
103
80
  budget?: number
104
81
  memory_mb?: number | undefined
82
+ // What the claim is for, named on the waiting line and on `run:board`.
83
+ command?: string | undefined
84
+ // A unit suite's claim, whose weight is its worker count.
85
+ is_unit?: boolean | undefined
86
+ report?: (line: string) => void
105
87
  read_machine?: () => Promise<MachineReading>
106
88
  wait_cap_ms?: number
107
89
  poll_interval_ms?: number
108
90
  directory?: string
109
91
  now?: () => number
110
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
111
95
  }
112
96
 
113
97
  interface Handle {
@@ -119,7 +103,7 @@ function marker_name(key: string): string {
119
103
  return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`
120
104
  }
121
105
 
122
- // **"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
123
107
  // way costs a reservation a slower admission, while the other way admits past a run that is still there.
124
108
  function is_running(reservation: Reservation): boolean {
125
109
  return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false
@@ -135,7 +119,7 @@ function read_reservation(source: string): Reservation | undefined {
135
119
 
136
120
  // **A dead marker is removed, not merely skipped** — otherwise a reissued pid turns a leaked place into
137
121
  // a phantom that fills the budget for good. The unlink never throws: a marker this account may not
138
- // 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.
139
123
  function sweep_marker(source: string): void {
140
124
  try {
141
125
  stamp_file.remove_stamp(source)
@@ -182,12 +166,6 @@ function normalize_budget(budget: number): number {
182
166
  return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET
183
167
  }
184
168
 
185
- async function default_sleep(ms: number): Promise<void> {
186
- await new Promise<void>((resolve) => {
187
- setTimeout(resolve, ms)
188
- })
189
- }
190
-
191
169
  // **Replaced atomically, never unlinked and recreated**: the admitted rewrite lands on a marker other
192
170
  // lanes are polling, and a reader that hit the gap between an unlink and its create would see the ledger
193
171
  // without this place and admit past it.
@@ -195,56 +173,56 @@ function write_reservation(target: string, fields: ReservationFields): void {
195
173
  stamp_file.replace_stamp(target, { ...process_identity.own_fields(), ...fields })
196
174
  }
197
175
 
198
- // The clock and cadence a wait runs on, resolved apart from the ledger fields so `reserve` stays under
199
- // the complexity limit — each default is a branch.
200
- interface TimingConfig {
201
- now: () => number
202
- sleep: (ms: number) => Promise<void>
203
- poll_interval_ms: number
204
- wait_cap_ms: number
176
+ function report_wait(line: string): void {
177
+ process.stderr.write(`${line}\n`)
205
178
  }
206
179
 
207
180
  interface WaitContext extends TimingConfig {
208
181
  read_machine: () => Promise<MachineReading>
182
+ report: (line: string) => void
183
+ record_wait: WaitSink | undefined
209
184
  key: string
210
185
  target: string
211
186
  directory: string
212
187
  budget: number
213
188
  deadline: number
214
189
  fields: ReservationFields
190
+ busy_samples: Array<BusySample>
215
191
  }
216
192
 
217
- function resolve_timing(options: ReserveOptions): TimingConfig {
218
- return {
219
- now: options.now ?? Date.now,
220
- sleep: options.sleep ?? default_sleep,
221
- poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
222
- wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS,
223
- }
224
- }
225
-
226
- // **A claim alone in the ledger reads nothing from the machine**: the head is admitted whatever the
227
- // 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).
228
198
  async function current_budget(
229
199
  context: WaitContext,
230
200
  reservations: ReadonlyArray<LiveReservation>,
231
201
  ): Promise<MachineBudget> {
232
- if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity }
233
-
234
202
  const reading = await context.read_machine()
235
203
  const ledger = core_admission.ledger_load(reservations, context.now())
236
- const budget = machine_capacity.machine_budget(context.budget, reading, ledger)
237
204
 
238
- 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)
239
215
  }
240
216
 
241
217
  // The claim is admitted: its marker records when, which moves its load from "load outside the ledger"
242
218
  // to "load the ledger holds" for every later reader — its cores at once, its memory once its tool has
243
219
  // had time to ramp up.
244
- function admit(context: WaitContext, overflow?: Overflow): Admission {
245
- 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()
222
+
223
+ write_reservation(context.target, { ...context.fields, admitted_at, granted })
246
224
 
247
- return { overflow }
225
+ return { overflow, granted, waited_ms: admitted_at - context.fields.claimed_at }
248
226
  }
249
227
 
250
228
  function overflow_of(
@@ -259,16 +237,41 @@ function overflow_of(
259
237
  }
260
238
  }
261
239
 
240
+ // The marker records why the claim waits, rewritten only when the reason changes, and the command says
241
+ // so once, when its wait starts.
242
+ function mark_waiting(context: WaitContext, reason: WaitReason): void {
243
+ const previous = context.fields.wait_reason
244
+
245
+ if (previous === reason) return
246
+
247
+ context.fields = { ...context.fields, wait_reason: reason }
248
+ write_reservation(context.target, context.fields)
249
+
250
+ if (previous === undefined) context.report(core_wait.wait_line(context.fields.command, reason))
251
+ }
252
+
262
253
  async function poll_admission(context: WaitContext): Promise<Admission | undefined> {
263
254
  const reservations = live_reservations(context.directory)
264
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)
265
262
 
266
- 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)
267
269
 
268
- if (context.now() >= context.deadline) {
269
- return admit(context, overflow_of(context, reservations, budget))
270
+ return admit(context, overflow_of(context, held, budget), granted)
270
271
  }
271
272
 
273
+ mark_waiting(context, reason)
274
+
272
275
  return undefined
273
276
  }
274
277
 
@@ -285,16 +288,41 @@ async function await_admission(context: WaitContext): Promise<Admission> {
285
288
  admission = await poll_admission(context)
286
289
  }
287
290
 
291
+ await core_wait_record.record_admitted(context.fields, context.now(), context.record_wait)
292
+
288
293
  return admission
289
294
  }
290
295
 
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'> {
300
+ return {
301
+ read_machine: options.read_machine ?? machine_capacity.read_machine,
302
+ report: options.report ?? report_wait,
303
+ record_wait: options.record_wait,
304
+ }
305
+ }
306
+
307
+ // The checkout the claim runs in, so `run:board` can say whose claim waits. The ledger is the
308
+ // machine's, so the checkout may be another repository's (`core-wait.ts` → `where_of`).
309
+ function claim_fields(
310
+ weight: number,
311
+ claimed_at: number,
312
+ options: ReserveOptions,
313
+ ): ReservationFields {
314
+ const { memory_mb, command, is_unit } = options
315
+
316
+ return { weight, claimed_at, memory_mb, command, is_unit, ...core_wait.where_of(process.cwd()) }
317
+ }
318
+
291
319
  async function reserve(weight: number, options: ReserveOptions = {}): Promise<Handle> {
292
- const timing = resolve_timing(options)
320
+ const timing = core_budget_timing.resolve_timing(options)
293
321
  const directory = options.directory ?? PLATFORM_TEMP_ROOT
294
322
  const claimed_at = timing.now()
295
323
  const name = marker_name(randomUUID())
296
324
  const target = path.join(directory, name)
297
- const fields = { weight, claimed_at, memory_mb: options.memory_mb }
325
+ const fields = claim_fields(weight, claimed_at, options)
298
326
 
299
327
  write_reservation(target, fields)
300
328
  const admission = await await_admission({
@@ -305,58 +333,43 @@ async function reserve(weight: number, options: ReserveOptions = {}): Promise<Ha
305
333
  budget: normalize_budget(options.budget ?? availableParallelism()),
306
334
  deadline: claimed_at + timing.wait_cap_ms,
307
335
  fields,
308
- read_machine: options.read_machine ?? machine_capacity.read_machine,
336
+ busy_samples: [],
337
+ ...resolve_ports(options),
309
338
  })
310
339
 
311
340
  return { target, admission }
312
341
  }
313
342
 
343
+ // The claims waiting in the ledger now, for a `run:board` running in `home`.
344
+ function budget_waits(
345
+ directory: string = PLATFORM_TEMP_ROOT,
346
+ now: number = Date.now(),
347
+ home: string = process.cwd(),
348
+ ): Array<BudgetWait> {
349
+ return core_wait.waits_of(live_reservations(directory), now, home)
350
+ }
351
+
314
352
  function release(handle: Handle): void {
315
353
  sweep_marker(handle.target)
316
354
  }
317
355
 
318
356
  // The whole reservation lifetime around a step: claim a place, wait for admission, run, and free the
319
357
  // place on any exit. `finally`, so a step that threw still releases its cores. The step is told how it was
320
- // admitted, so the gate can report one that started past the budget.
358
+ // admitted, so the gate can report one that started past the budget, and the claim's ledger key.
321
359
  async function with_core_reservation<T>(
322
360
  weight: number,
323
- run: (admission: Admission) => Promise<T>,
361
+ run: (admission: Admission, key: string) => Promise<T>,
324
362
  options: ReserveOptions = {},
325
363
  ): Promise<T> {
326
364
  const handle = await reserve(weight, options)
327
365
 
328
366
  try {
329
- return await run(handle.admission)
367
+ return await run(handle.admission, path.basename(handle.target))
330
368
  } finally {
331
369
  release(handle)
332
370
  }
333
371
  }
334
372
 
335
- function is_held(): boolean {
336
- return process.env[HELD_KEY] === HELD_VALUE
337
- }
338
-
339
- // A function of its own so the restoring write does not sit after an `await`, where
340
- // `require-atomic-updates` reads any write to `process` as a possible race — the reason `josh.ts`
341
- // gives `record_exit_code`.
342
- function set_held_mark(value: string): void {
343
- process.env[HELD_KEY] = value
344
- }
345
-
346
- // Marks this process, and every child it spawns, as running inside a held reservation. The previous
347
- // value comes back afterwards, so a nested holder never clears the mark its outer holder set.
348
- async function with_held_mark<T>(run: () => Promise<T>): Promise<T> {
349
- const previous = process.env[HELD_KEY] ?? ''
350
-
351
- set_held_mark(HELD_VALUE)
352
-
353
- try {
354
- return await run()
355
- } finally {
356
- set_held_mark(previous)
357
- }
358
- }
359
-
360
373
  // **A command's reservation: the gate's claim, unless a parent already holds the cores**
361
374
  // `josh-logic.ts` calls this around every command that declares a weight.
362
375
  // Each command then only declares its weight, and no command carries a copy of the claim, run and
@@ -368,27 +381,45 @@ async function with_command_reservation<T>(
368
381
  run: () => Promise<T>,
369
382
  options: ReserveOptions = {},
370
383
  ): Promise<T> {
371
- if (is_held() || unit_worker_share.is_nested_run()) return await run()
384
+ if (held_mark.is_held() || unit_worker_share.is_nested_run()) return await run()
385
+
386
+ return await with_core_reservation(
387
+ weight,
388
+ async (_admission, key) => await held_mark.with_held_mark(run, key),
389
+ options,
390
+ )
391
+ }
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)
372
401
 
373
- return await with_core_reservation(weight, async () => await with_held_mark(run), options)
402
+ return held?.reservation.is_unit === true ? held.reservation : undefined
374
403
  }
375
404
 
376
405
  const core_budget = {
377
- CORE_WEIGHTS,
378
- HELD_KEY,
379
- HELD_VALUE,
380
- MEMORY_MB,
406
+ CORE_WEIGHTS: core_weights.CORE_WEIGHTS,
407
+ HELD_KEY: held_mark.HELD_KEY,
408
+ HELD_VALUE: held_mark.HELD_VALUE,
409
+ MEMORY_MB: core_weights.MEMORY_MB,
381
410
  RESERVED_PREFIX,
382
411
  admitted_keys: core_admission.admitted_keys,
383
412
  admitted_load: core_admission.admitted_load,
413
+ budget_waits,
384
414
  describe_overflow: core_admission.describe_overflow,
385
- is_held,
415
+ held_unit_claim,
416
+ is_held: held_mark.is_held,
386
417
  live_reservations,
387
418
  release,
388
419
  reserve,
389
420
  with_command_reservation,
390
421
  with_core_reservation,
391
- with_held_mark,
422
+ with_held_mark: held_mark.with_held_mark,
392
423
  }
393
424
 
394
425
  export type { LiveReservation, Reservation, ReserveOptions }
@@ -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 }
@@ -0,0 +1,162 @@
1
+ import path from 'node:path'
2
+ import { lane_paths } from '#scripts/lane/lane-paths'
3
+ import { core_admission, type LedgerEntry } from './core-admission'
4
+ import type { MachineBudget } from './machine-capacity'
5
+
6
+ // **Why a claim waits, and who is waiting** (joshuafolkken/kit#3943). A claim held back by the budget
7
+ // used to wait in silence: the command printed nothing and no board showed it, so a lane stalled on
8
+ // memory pressure read the same as one stuck. The waiting claim records its reason on its marker and
9
+ // says it once on its own output; `run:board` draws every marker still waiting. Everything here is a
10
+ // pure function of the ledger and the budget it is handed.
11
+
12
+ const WAIT_REASONS = ['cores', 'cpu', 'memory', 'pressure'] as const
13
+
14
+ type WaitReason = (typeof WAIT_REASONS)[number]
15
+
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).
18
+ const REASON_TEXT: Record<WaitReason, string> = {
19
+ cores: 'not enough free cores',
20
+ cpu: 'CPU saturated',
21
+ memory: 'not enough free memory',
22
+ pressure: 'memory under pressure',
23
+ }
24
+
25
+ // What the board reads off a marker. Every field but the claim time is optional, so a marker an older
26
+ // `josh` wrote still reads, and one that never waited is not drawn.
27
+ interface WhereFields {
28
+ checkout?: string | undefined
29
+ lane?: string | undefined
30
+ lanes_root?: string | undefined
31
+ }
32
+
33
+ interface WaitMarker extends WhereFields {
34
+ claimed_at: number
35
+ admitted_at?: number | undefined
36
+ command?: string | undefined
37
+ wait_reason?: WaitReason | undefined
38
+ }
39
+
40
+ // Where a waiting claim runs: `lane` is the board's own repository's lane number, which the board
41
+ // links; `elsewhere` names another repository's checkout, which it cannot link. Neither is the board's
42
+ // own main checkout.
43
+ interface BudgetPlace {
44
+ lane: string | undefined
45
+ elsewhere: string | undefined
46
+ }
47
+
48
+ interface BudgetWait extends BudgetPlace {
49
+ command: string | undefined
50
+ waited_ms: number
51
+ reason: WaitReason
52
+ }
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
+
66
+ // **The cores decide first**: a claim that would not fit even with unlimited memory waits for cores;
67
+ // one that fits on cores waits for memory, named as pressure when the reading saw compression or swap.
68
+ function wait_reason(
69
+ key: string,
70
+ reservations: ReadonlyArray<LedgerEntry>,
71
+ budget: MachineBudget,
72
+ ): WaitReason {
73
+ const cores_only = { ...budget, memory_mb: Infinity }
74
+
75
+ if (!core_admission.is_admitted(key, reservations, cores_only)) {
76
+ return core_reason(key, reservations, budget)
77
+ }
78
+
79
+ return budget.memory_pressured === true ? 'pressure' : 'memory'
80
+ }
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
+
98
+ // The line a waiting command prints once, when its wait starts.
99
+ function wait_line(command: string | undefined, reason: WaitReason): string {
100
+ return `⏳ ${command ?? 'a step'} waits for the core budget — ${REASON_TEXT[reason]}`
101
+ }
102
+
103
+ // The lanes root a checkout belongs to: a lane's parent, or the root beside a main checkout. Two
104
+ // checkouts of one repository share it; the ledger is machine-wide, so another repository's do not.
105
+ function lanes_root_of(checkout: string): string {
106
+ if (lane_paths.lane_issue_of(checkout) === undefined) return lane_paths.lane_root(checkout)
107
+
108
+ return path.dirname(path.resolve(checkout))
109
+ }
110
+
111
+ // Where a claim runs, read by the claimer under its own environment: `JOSH_LANE_ROOT` is a
112
+ // per-project setting, so a board cannot derive another repository's lanes root from its own.
113
+ function where_of(checkout: string): Required<WhereFields> {
114
+ return { checkout, lane: lane_paths.lane_issue_of(checkout), lanes_root: lanes_root_of(checkout) }
115
+ }
116
+
117
+ // Another repository's checkout is named by its lanes root and lane, or its directory, so its lane
118
+ // number is never linked to the board's repository's issue of that number.
119
+ function place_of(marker: WhereFields, home_root: string): BudgetPlace {
120
+ const { checkout, lane, lanes_root } = marker
121
+
122
+ if (checkout === undefined || lanes_root === undefined || lanes_root === home_root) {
123
+ return { lane, elsewhere: undefined }
124
+ }
125
+
126
+ const name = lane === undefined ? path.basename(checkout) : `${path.basename(lanes_root)}/${lane}`
127
+
128
+ return { lane: undefined, elsewhere: name }
129
+ }
130
+
131
+ function wait_of(marker: WaitMarker, now: number, home_root: string): Array<BudgetWait> {
132
+ const { command, wait_reason: reason } = marker
133
+
134
+ if (reason === undefined || marker.admitted_at !== undefined) return []
135
+
136
+ return [{ command, ...place_of(marker, home_root), waited_ms: now - marker.claimed_at, reason }]
137
+ }
138
+
139
+ // The claims still waiting, longest first, placed against the board's checkout `home`.
140
+ function waits_of(
141
+ entries: ReadonlyArray<{ reservation: WaitMarker }>,
142
+ now: number,
143
+ home: string,
144
+ ): Array<BudgetWait> {
145
+ const home_root = lanes_root_of(home)
146
+
147
+ return entries
148
+ .flatMap((entry) => wait_of(entry.reservation, now, home_root))
149
+ .toSorted((left, right) => right.waited_ms - left.waited_ms)
150
+ }
151
+
152
+ const core_wait = {
153
+ WAIT_REASONS,
154
+ hold_reason,
155
+ wait_line,
156
+ wait_reason,
157
+ waits_of,
158
+ where_of,
159
+ }
160
+
161
+ export type { BudgetWait, WaitReason }
162
+ export { core_wait }