@joshuafolkken/kit 1.1229.0 → 1.1370.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 (939) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +24 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +27 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +18 -29
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.github/workflows/publish.yml +2 -0
  42. package/.vscode/tasks.json +14 -0
  43. package/CLAUDE.md +10 -61
  44. package/README.md +38 -57
  45. package/SECURITY.md +1 -1
  46. package/dist/CLAUDE.md +10 -61
  47. package/dist/commands/document-section-cli.js +42 -10
  48. package/dist/config-merge/index.js +11 -2
  49. package/dist/hooks/audit-provision.js +2 -2
  50. package/dist/hooks/batch-guard.js +7 -7
  51. package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
  52. package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
  53. package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
  54. package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
  55. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  56. package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
  57. package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
  58. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  59. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  60. package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
  61. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  62. package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
  63. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  64. package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
  65. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  66. package/dist/hooks/codex-hook-adapter.js +26 -21
  67. package/dist/hooks/duplicate-read-guard.js +8 -8
  68. package/dist/hooks/format-edited.js +4 -4
  69. package/dist/hooks/inputs.json +213 -197
  70. package/dist/hooks/investigation-guard.js +8 -8
  71. package/dist/hooks/pretool-guard.js +15 -15
  72. package/dist/hooks/session-lang.js +406 -8
  73. package/dist/hooks/stop-guard.js +122 -201
  74. package/dist/josh.js +540 -137
  75. package/dist/version/index.js +15 -13
  76. package/eslint/base.js +43 -5
  77. package/eslint/rules/english-only-prose.js +3 -3
  78. package/eslint/rules/import.js +12 -0
  79. package/eslint/rules/namespace-object-export.js +2 -2
  80. package/package.json +16 -10
  81. package/pnpm-workspace.yaml +2 -4
  82. package/prompts/coding-standards.md +14 -48
  83. package/prompts/collaboration-workflow/file-edits.md +1 -1
  84. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  85. package/prompts/collaboration-workflow/issue-template.md +4 -10
  86. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  87. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  88. package/prompts/collaboration-workflow/overview.md +1 -1
  89. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  90. package/prompts/collaboration-workflow/principles.md +21 -3
  91. package/prompts/collaboration-workflow/report-format.md +16 -29
  92. package/prompts/collaboration-workflow/residency.md +1 -1
  93. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  94. package/prompts/collaboration-workflow/shell-body.md +3 -23
  95. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  96. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  97. package/prompts/refactoring.md +1 -1
  98. package/prompts/review-rubric.md +3 -22
  99. package/prompts/review.md +15 -38
  100. package/prompts/testing-guide.md +2 -4
  101. package/scripts/adopt/adopt-logic.ts +5 -5
  102. package/scripts/adopt/adopt-toolkits.ts +4 -5
  103. package/scripts/adopt/adopt.ts +2 -3
  104. package/scripts/agent/agent-argv.ts +7 -7
  105. package/scripts/agent/agent-diagnostics.ts +2 -2
  106. package/scripts/agent/agent-exit-record.ts +1 -1
  107. package/scripts/agent/agent-headless.ts +1 -1
  108. package/scripts/agent/agent-launch-environment.ts +6 -1
  109. package/scripts/agent/agent-role-profile.ts +49 -22
  110. package/scripts/agent/agent-session-role.ts +32 -0
  111. package/scripts/agent/api-outage.ts +1 -1
  112. package/scripts/agent/claude-agent-argv.ts +4 -4
  113. package/scripts/agent/claude-result-event.ts +4 -4
  114. package/scripts/agent/codex-hooks.ts +2 -2
  115. package/scripts/agent/interactive-ask.ts +3 -6
  116. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  117. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  118. package/scripts/backlog/backlog-arrival.ts +54 -17
  119. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  120. package/scripts/backlog/backlog-budget.ts +17 -24
  121. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  122. package/scripts/backlog/backlog-drive-args.ts +5 -4
  123. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  124. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  125. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  126. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  127. package/scripts/backlog/backlog-drive-named.ts +39 -9
  128. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  129. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  130. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  131. package/scripts/backlog/backlog-drive.ts +43 -28
  132. package/scripts/backlog/backlog-idle.ts +88 -0
  133. package/scripts/backlog/backlog-named.ts +11 -15
  134. package/scripts/backlog/backlog-next.ts +26 -30
  135. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  136. package/scripts/backlog/backlog-offer.ts +7 -7
  137. package/scripts/backlog/backlog-overlap.ts +178 -0
  138. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  139. package/scripts/backlog/backlog-plan-read.ts +111 -0
  140. package/scripts/backlog/backlog-plan.ts +11 -10
  141. package/scripts/backlog/backlog-pool.ts +13 -14
  142. package/scripts/backlog/backlog-rank.ts +11 -11
  143. package/scripts/backlog/backlog-ready.ts +15 -10
  144. package/scripts/backlog/backlog-scope.ts +14 -15
  145. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  146. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  147. package/scripts/backlog/backlog-stalled.ts +5 -6
  148. package/scripts/backlog/backlog-waves.ts +4 -4
  149. package/scripts/backlog/backlogrun-args.ts +74 -0
  150. package/scripts/backlog/backlogrun-cli.ts +113 -0
  151. package/scripts/backlog/backlogrun-launch.ts +178 -0
  152. package/scripts/behavior/behavior-assertion.ts +6 -8
  153. package/scripts/behavior/behavior-cli.ts +1 -1
  154. package/scripts/behavior/behavior-rules.ts +3 -3
  155. package/scripts/build/build-claude-md.ts +4 -4
  156. package/scripts/build/build-codex-hooks.ts +2 -2
  157. package/scripts/build/build-commands.ts +1 -1
  158. package/scripts/build/build-hooks.ts +5 -5
  159. package/scripts/build/build.ts +1 -1
  160. package/scripts/build/hook-bundle-stamp.ts +109 -7
  161. package/scripts/build/local-bin.ts +2 -2
  162. package/scripts/cases/cases-cli.ts +1 -1
  163. package/scripts/cases/cases-logic.ts +2 -2
  164. package/scripts/ci/composite-actions.ts +1 -2
  165. package/scripts/ci/pr-classification.ts +2 -2
  166. package/scripts/claude/workflow-destination.ts +1 -1
  167. package/scripts/clone/clone-aggregate.ts +1 -1
  168. package/scripts/clone/clone-fingerprint.ts +1 -1
  169. package/scripts/clone/clone-scan-cli.ts +1 -1
  170. package/scripts/clone/clone-scan.ts +1 -1
  171. package/scripts/config-merge/index.ts +1 -1
  172. package/scripts/config-merge/json-format.ts +1 -3
  173. package/scripts/config-merge/patch-json-array.ts +90 -0
  174. package/scripts/config-merge/patch-json-key.ts +6 -3
  175. package/scripts/config-merge/patch-json-list.ts +1 -1
  176. package/scripts/cost-runtime/codex-usage.ts +1 -1
  177. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  178. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  179. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  180. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  181. package/scripts/cost-runtime/cost-cli.ts +14 -11
  182. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  183. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  184. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  185. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  186. package/scripts/cost-runtime/cost-usage.ts +6 -7
  187. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  188. package/scripts/cost-runtime/own-session.ts +1 -1
  189. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  190. package/scripts/delegation/delegation-cli.ts +4 -4
  191. package/scripts/delegation/delegation-policy.ts +13 -15
  192. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  193. package/scripts/delegation/fanout-cli.ts +1 -1
  194. package/scripts/delegation/fanout.ts +1 -1
  195. package/scripts/delegation/investigation-guard.ts +18 -22
  196. package/scripts/delegation/investigation-reads.ts +48 -238
  197. package/scripts/discovery/repo-discovery.ts +1 -1
  198. package/scripts/discovery/repo-map-logic.ts +1 -2
  199. package/scripts/discovery/repo-origin.ts +3 -3
  200. package/scripts/discovery/repo-party-cli.ts +2 -2
  201. package/scripts/discovery/repo-party.ts +2 -2
  202. package/scripts/doctor/doctor-consumer.ts +1 -1
  203. package/scripts/doctor/doctor-io.ts +6 -7
  204. package/scripts/doctor/doctor-logic.ts +1 -1
  205. package/scripts/doctor/doctor-ports.ts +1 -1
  206. package/scripts/doctor/doctor.ts +8 -9
  207. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  208. package/scripts/document/bash-output-cap.ts +5 -7
  209. package/scripts/document/capped-print-part.ts +1 -1
  210. package/scripts/document/capped-print.ts +1 -1
  211. package/scripts/document/document-byte-budget.ts +33 -64
  212. package/scripts/document/document-byte-check.ts +4 -4
  213. package/scripts/document/document-reachability.ts +7 -8
  214. package/scripts/document/document-read-cli.ts +2 -2
  215. package/scripts/document/document-scan.ts +26 -2
  216. package/scripts/document/document-section-cli.ts +6 -8
  217. package/scripts/document/document-section.ts +8 -12
  218. package/scripts/document/edit-files-cli.ts +3 -4
  219. package/scripts/document/entry-read-budget.ts +8 -70
  220. package/scripts/document/entry-read-set.ts +51 -34
  221. package/scripts/document/lane-child-read-set.ts +9 -9
  222. package/scripts/document/read-files-cli.ts +1 -2
  223. package/scripts/document/read-set-cli.ts +16 -19
  224. package/scripts/document/read-set-cost.ts +4 -4
  225. package/scripts/document/read-set-point-of-use.ts +28 -38
  226. package/scripts/document/read-set-pricing.ts +1 -1
  227. package/scripts/document/read-set-trim.ts +3 -3
  228. package/scripts/document/resident-budget.ts +8 -10
  229. package/scripts/epic/epic-add-body.ts +15 -18
  230. package/scripts/epic/epic-add-plan.ts +26 -28
  231. package/scripts/epic/epic-add.ts +32 -25
  232. package/scripts/epic/epic-audit-checks.ts +27 -37
  233. package/scripts/epic/epic-audit-cli.ts +21 -22
  234. package/scripts/epic/epic-audit-orphans.ts +16 -17
  235. package/scripts/epic/epic-audit-rationale.ts +10 -15
  236. package/scripts/epic/epic-audit-report.ts +2 -5
  237. package/scripts/epic/epic-audit.ts +18 -14
  238. package/scripts/epic/epic-body.ts +10 -10
  239. package/scripts/epic/epic-bundle-cli.ts +36 -34
  240. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  241. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  242. package/scripts/epic/epic-bundle-poll.ts +1 -1
  243. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  244. package/scripts/epic/epic-bundle.ts +19 -20
  245. package/scripts/epic/epic-busy.ts +44 -21
  246. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  247. package/scripts/epic/epic-chains.ts +18 -23
  248. package/scripts/epic/epic-classify.ts +11 -12
  249. package/scripts/epic/epic-cli-argv.ts +5 -6
  250. package/scripts/epic/epic-cli-remove.ts +9 -4
  251. package/scripts/epic/epic-cli.ts +38 -26
  252. package/scripts/epic/epic-close-comment.ts +14 -15
  253. package/scripts/epic/epic-close.ts +25 -29
  254. package/scripts/epic/epic-cross-repo.ts +18 -21
  255. package/scripts/epic/epic-decision.ts +14 -18
  256. package/scripts/epic/epic-fetch.ts +25 -31
  257. package/scripts/epic/epic-graph.ts +15 -17
  258. package/scripts/epic/epic-index.ts +14 -16
  259. package/scripts/epic/epic-issue.ts +9 -11
  260. package/scripts/epic/epic-label-age.ts +74 -0
  261. package/scripts/epic/epic-lane-offer.ts +35 -24
  262. package/scripts/epic/epic-nested.ts +1 -1
  263. package/scripts/epic/epic-next-read.ts +8 -8
  264. package/scripts/epic/epic-next-views.ts +12 -12
  265. package/scripts/epic/epic-next.ts +29 -33
  266. package/scripts/epic/epic-outside-blocker.ts +11 -10
  267. package/scripts/epic/epic-parse.ts +22 -24
  268. package/scripts/epic/epic-promote.ts +3 -2
  269. package/scripts/epic/epic-rank.ts +1 -1
  270. package/scripts/epic/epic-read.ts +10 -8
  271. package/scripts/epic/epic-reconcile.ts +8 -6
  272. package/scripts/epic/epic-reference.ts +5 -4
  273. package/scripts/epic/epic-relation-recheck.ts +10 -11
  274. package/scripts/epic/epic-relations.ts +9 -8
  275. package/scripts/epic/epic-remove-plan.ts +4 -5
  276. package/scripts/epic/epic-remove.ts +7 -5
  277. package/scripts/epic/epic-report.ts +18 -20
  278. package/scripts/epic/epic-run.ts +6 -5
  279. package/scripts/epic/epic-sections.ts +2 -2
  280. package/scripts/epic/epic-shape.ts +3 -3
  281. package/scripts/epic/epic-solo-stale.ts +3 -2
  282. package/scripts/epic/epic-solo.ts +8 -8
  283. package/scripts/epic/epic-triage.ts +5 -4
  284. package/scripts/epic/epic-validate.ts +8 -7
  285. package/scripts/epic/epic.ts +5 -5
  286. package/scripts/exports/unused-members-cli.ts +1 -1
  287. package/scripts/followup/followup-issue-number.ts +1 -2
  288. package/scripts/followup/git-followup-cleanup.ts +6 -7
  289. package/scripts/followup/git-followup-finish.ts +11 -13
  290. package/scripts/followup/git-followup-flush.ts +11 -7
  291. package/scripts/followup/git-followup-issue-close.ts +16 -13
  292. package/scripts/followup/git-followup-label.ts +9 -6
  293. package/scripts/followup/git-followup-merged.ts +1 -1
  294. package/scripts/followup/git-followup-pending.ts +7 -9
  295. package/scripts/followup/git-followup-stages.ts +28 -17
  296. package/scripts/followup/git-followup-workflow.ts +19 -21
  297. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  298. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  299. package/scripts/followup/git-pr-followup.ts +18 -17
  300. package/scripts/gate/core-admission.ts +162 -0
  301. package/scripts/gate/core-budget.ts +134 -91
  302. package/scripts/gate/gate-ledger.ts +114 -0
  303. package/scripts/gate/gate-log.ts +7 -9
  304. package/scripts/gate/gate-plan.ts +103 -35
  305. package/scripts/gate/gate-report.ts +39 -21
  306. package/scripts/gate/gate-skip.ts +11 -13
  307. package/scripts/gate/gate-steps.ts +5 -1
  308. package/scripts/gate/gate-tree.ts +3 -4
  309. package/scripts/gate/hook-gate-reuse.ts +9 -9
  310. package/scripts/gate/machine-capacity.ts +313 -0
  311. package/scripts/gate/pre-commit-type-check.ts +4 -4
  312. package/scripts/gate/project-checks.ts +12 -4
  313. package/scripts/gate/scoped-green.ts +11 -18
  314. package/scripts/gate/type-check-command.ts +2 -2
  315. package/scripts/gate/type-check-step.ts +4 -4
  316. package/scripts/gate/verification-gate.ts +60 -53
  317. package/scripts/gh/gh-spawn.ts +2 -2
  318. package/scripts/gh/git-ai-review-scan.ts +3 -2
  319. package/scripts/gh/git-gh-api-path.ts +10 -11
  320. package/scripts/gh/git-gh-exec.ts +43 -48
  321. package/scripts/gh/git-gh-failure.ts +6 -9
  322. package/scripts/gh/git-gh-helpers.ts +1 -1
  323. package/scripts/gh/git-gh-issue-list.ts +15 -19
  324. package/scripts/gh/git-gh-issue-read.ts +43 -60
  325. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  326. package/scripts/gh/git-gh-issue-write.ts +52 -40
  327. package/scripts/gh/git-gh-issue.ts +23 -24
  328. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  329. package/scripts/gh/git-gh-pr-read.ts +46 -50
  330. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  331. package/scripts/gh/git-gh-pr-review.ts +2 -2
  332. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  333. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  334. package/scripts/gh/git-gh-pr.ts +16 -16
  335. package/scripts/gh/git-gh-reachability.ts +11 -12
  336. package/scripts/gh/git-gh-repo.ts +2 -3
  337. package/scripts/gh/git-gh-rest-state.ts +1 -1
  338. package/scripts/gh/git-pr-ai-review.ts +6 -5
  339. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  340. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  341. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  342. package/scripts/gh/git-pr-checks.ts +20 -23
  343. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  344. package/scripts/gh/git-pr-confirmation.ts +5 -5
  345. package/scripts/gh/git-pr-managed-config.ts +7 -9
  346. package/scripts/gh/git-pr-messages.ts +1 -1
  347. package/scripts/gh/git-pr.ts +15 -16
  348. package/scripts/gh/github-issue-url.ts +8 -9
  349. package/scripts/git/base-tree.ts +66 -0
  350. package/scripts/git/change-base.ts +42 -2
  351. package/scripts/git/changed-file-scope.ts +5 -5
  352. package/scripts/git/changed-paths.ts +1 -2
  353. package/scripts/git/constants.ts +2 -2
  354. package/scripts/git/git-branch.ts +1 -1
  355. package/scripts/git/git-closes-keyword.ts +3 -3
  356. package/scripts/git/git-command.ts +53 -41
  357. package/scripts/git/git-common-directory.ts +3 -3
  358. package/scripts/git/git-diff-reads.ts +14 -15
  359. package/scripts/git/git-error.ts +1 -1
  360. package/scripts/git/git-execa-error.ts +1 -2
  361. package/scripts/git/git-issue.ts +10 -8
  362. package/scripts/git/git-location-environment.ts +3 -4
  363. package/scripts/git/git-ls-remote.ts +6 -8
  364. package/scripts/git/git-pre-push-hook.ts +11 -10
  365. package/scripts/git/git-preflight.ts +5 -5
  366. package/scripts/git/git-push-transport.ts +2 -2
  367. package/scripts/git/git-remote-branch.ts +1 -2
  368. package/scripts/git/git-schemas.ts +16 -23
  369. package/scripts/git/git-spawn-sync.ts +1 -1
  370. package/scripts/git/git-spawn.ts +37 -14
  371. package/scripts/git/git-ssh-keepalive.ts +12 -5
  372. package/scripts/git/git-staging.ts +7 -8
  373. package/scripts/git/git-workflow.ts +1 -1
  374. package/scripts/git/git-worktree.ts +35 -27
  375. package/scripts/git/gone-branch.ts +2 -2
  376. package/scripts/git/listing-cutoff.ts +1 -2
  377. package/scripts/git/lockfile-sync.ts +65 -0
  378. package/scripts/git/main-merge-guard.ts +1 -2
  379. package/scripts/git/main-merge.ts +7 -7
  380. package/scripts/git/main-sync.ts +23 -8
  381. package/scripts/git/parse-json-array.ts +18 -23
  382. package/scripts/git/repository-lock.ts +34 -2
  383. package/scripts/git/stash/git-stash.ts +4 -5
  384. package/scripts/git/stash/stash-orphans.ts +5 -3
  385. package/scripts/git/stash/stash-pop-args.ts +1 -1
  386. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  387. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  388. package/scripts/hooks/batch-guard.ts +11 -13
  389. package/scripts/hooks/check-commit-message.ts +12 -9
  390. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  391. package/scripts/hooks/edited-cspell.ts +3 -4
  392. package/scripts/hooks/format-edited-cli.ts +1 -1
  393. package/scripts/hooks/format-edited-file.ts +11 -17
  394. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  395. package/scripts/hooks/pre-push-unit.ts +10 -14
  396. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  397. package/scripts/hooks/pretool-guard.ts +93 -18
  398. package/scripts/hooks/reserved-run.ts +2 -2
  399. package/scripts/hooks/step-zero-notice.ts +1 -1
  400. package/scripts/hooks/stop-guard.ts +21 -10
  401. package/scripts/init/basic-path-migration.ts +2 -2
  402. package/scripts/init/claude-kit-only-settings.ts +2 -2
  403. package/scripts/init/claude-plugin-config.ts +2 -2
  404. package/scripts/init/distributed-paths.ts +4 -4
  405. package/scripts/init/hook-command-rewrite.ts +3 -3
  406. package/scripts/init/hook-launch.ts +5 -5
  407. package/scripts/init/init-actions.ts +13 -0
  408. package/scripts/init/init-ai-copy.ts +11 -11
  409. package/scripts/init/init-bootstrap.ts +3 -3
  410. package/scripts/init/init-copy-content.ts +4 -4
  411. package/scripts/init/init-logic-json-merge.ts +7 -9
  412. package/scripts/init/init-logic-migrate.ts +1 -1
  413. package/scripts/init/init-logic-templates.ts +1 -1
  414. package/scripts/init/init-logic-workspace.ts +4 -4
  415. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  416. package/scripts/init/init-logic.ts +19 -22
  417. package/scripts/init/init.ts +12 -8
  418. package/scripts/init/kit-base-preset.ts +1 -1
  419. package/scripts/init/kit-setup-state.ts +1 -1
  420. package/scripts/init/kit-written-paths.ts +1 -2
  421. package/scripts/init/package-manager-pin.ts +35 -0
  422. package/scripts/init/project-profile-cli.ts +1 -1
  423. package/scripts/init/project-profile.ts +3 -3
  424. package/scripts/init/session-language-environment.ts +1 -1
  425. package/scripts/init/start-exec.ts +3 -4
  426. package/scripts/init/start-plan.ts +2 -2
  427. package/scripts/init/start-setup-pr.ts +3 -2
  428. package/scripts/init/start-steps.ts +2 -2
  429. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  430. package/scripts/init/vscode-tasks.ts +62 -0
  431. package/scripts/issue/baseline-measure.ts +2 -2
  432. package/scripts/issue/behavior-change-lint.ts +2 -2
  433. package/scripts/issue/defect-rate-cli.ts +6 -7
  434. package/scripts/issue/defect-rate.ts +37 -27
  435. package/scripts/issue/git-next-issues.ts +9 -8
  436. package/scripts/issue/issue-auto-ok.ts +49 -11
  437. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  438. package/scripts/issue/issue-backlinks.ts +6 -6
  439. package/scripts/issue/issue-cite-cli.ts +20 -18
  440. package/scripts/issue/issue-cite.ts +18 -8
  441. package/scripts/issue/issue-closing-pr.ts +4 -4
  442. package/scripts/issue/issue-comment-cli.ts +6 -4
  443. package/scripts/issue/issue-file-cli.ts +75 -15
  444. package/scripts/issue/issue-file-fold.ts +155 -0
  445. package/scripts/issue/issue-file.ts +14 -6
  446. package/scripts/issue/issue-fold-cli.ts +14 -9
  447. package/scripts/issue/issue-fold.ts +23 -8
  448. package/scripts/issue/issue-labels.ts +46 -37
  449. package/scripts/issue/issue-lint-cli.ts +2 -2
  450. package/scripts/issue/issue-lint.ts +1 -1
  451. package/scripts/issue/issue-merged.ts +10 -4
  452. package/scripts/issue/issue-number-shape.ts +27 -0
  453. package/scripts/issue/issue-rank.ts +1 -1
  454. package/scripts/issue/issue-read-cli.ts +4 -5
  455. package/scripts/issue/issue-read.ts +4 -5
  456. package/scripts/issue/issue-reference.ts +5 -5
  457. package/scripts/issue/issue-release-cli.ts +165 -0
  458. package/scripts/issue/issue-release.ts +58 -0
  459. package/scripts/issue/issue-report-failures.ts +7 -4
  460. package/scripts/issue/issue-scout-cli.ts +11 -11
  461. package/scripts/issue/issue-scout-closed.ts +4 -4
  462. package/scripts/issue/issue-scout.ts +4 -5
  463. package/scripts/issue/issue-state-cli.ts +17 -10
  464. package/scripts/issue/issue-state.ts +12 -13
  465. package/scripts/issue/issue-wip.ts +7 -7
  466. package/scripts/issue/markdown-section.ts +3 -3
  467. package/scripts/issue/measure-rerun-cli.ts +10 -9
  468. package/scripts/issue/reproduction-measure.ts +3 -3
  469. package/scripts/issue/session-cite.ts +56 -0
  470. package/scripts/josh/agent-session-environment.ts +10 -8
  471. package/scripts/josh/cli-body.ts +2 -2
  472. package/scripts/josh/command-suggest.ts +1 -1
  473. package/scripts/josh/file-map-stamp.ts +20 -23
  474. package/scripts/josh/hook-decision.ts +24 -28
  475. package/scripts/josh/josh-command-map.ts +4 -1
  476. package/scripts/josh/josh-command-types.ts +32 -34
  477. package/scripts/josh/josh-commands-ai.ts +6 -6
  478. package/scripts/josh/josh-commands-backlog.ts +15 -3
  479. package/scripts/josh/josh-commands-clone.ts +1 -1
  480. package/scripts/josh/josh-commands-development.ts +33 -4
  481. package/scripts/josh/josh-commands-document.ts +3 -3
  482. package/scripts/josh/josh-commands-guard.ts +3 -3
  483. package/scripts/josh/josh-commands-issue.ts +11 -5
  484. package/scripts/josh/josh-commands-lane.ts +16 -5
  485. package/scripts/josh/josh-commands-lint.ts +1 -1
  486. package/scripts/josh/josh-commands-maintenance.ts +2 -2
  487. package/scripts/josh/josh-commands-run.ts +20 -6
  488. package/scripts/josh/josh-commands-split.ts +1 -2
  489. package/scripts/josh/josh-commands-versioning.ts +5 -5
  490. package/scripts/josh/josh-commands-workflow.ts +30 -22
  491. package/scripts/josh/josh-environment-file.ts +1 -1
  492. package/scripts/josh/josh-in-process.ts +3 -3
  493. package/scripts/josh/josh-logic.ts +10 -10
  494. package/scripts/josh/josh-run.ts +3 -3
  495. package/scripts/josh/josh-verdict.ts +9 -12
  496. package/scripts/josh/josh.ts +3 -3
  497. package/scripts/josh/kit-only.ts +2 -2
  498. package/scripts/josh/path-decision.ts +3 -3
  499. package/scripts/josh/platform-temporary.ts +7 -5
  500. package/scripts/josh/process-identity.ts +24 -6
  501. package/scripts/josh/process-owner.ts +4 -4
  502. package/scripts/josh/session-language-cli.ts +53 -11
  503. package/scripts/josh/session-language.ts +1 -1
  504. package/scripts/josh/stamp-file.ts +48 -29
  505. package/scripts/josh/stamp-record.ts +57 -0
  506. package/scripts/lane/lane-await.ts +35 -11
  507. package/scripts/lane/lane-cache.ts +6 -6
  508. package/scripts/lane/lane-capacity.ts +32 -17
  509. package/scripts/lane/lane-child-invocation.ts +17 -15
  510. package/scripts/lane/lane-child-marker.ts +12 -12
  511. package/scripts/lane/lane-cli.ts +20 -13
  512. package/scripts/lane/lane-close.ts +6 -6
  513. package/scripts/lane/lane-dispatch.ts +61 -72
  514. package/scripts/lane/lane-environment.ts +5 -5
  515. package/scripts/lane/lane-guard-policy.ts +7 -21
  516. package/scripts/lane/lane-handoff.ts +2 -2
  517. package/scripts/lane/lane-install.ts +9 -10
  518. package/scripts/lane/lane-launch-cli.ts +13 -8
  519. package/scripts/lane/lane-ledger.ts +73 -11
  520. package/scripts/lane/lane-leftover.ts +44 -30
  521. package/scripts/lane/lane-limit-cli.ts +160 -0
  522. package/scripts/lane/lane-limit-override.ts +74 -0
  523. package/scripts/lane/lane-load.ts +19 -68
  524. package/scripts/lane/lane-measure-cli.ts +15 -25
  525. package/scripts/lane/lane-occupancy.ts +6 -4
  526. package/scripts/lane/lane-open.ts +25 -24
  527. package/scripts/lane/lane-output.ts +4 -3
  528. package/scripts/lane/lane-paths.ts +22 -8
  529. package/scripts/lane/lane-phase.ts +33 -0
  530. package/scripts/lane/lane-reap.ts +2 -2
  531. package/scripts/lane/lane-registry.ts +27 -15
  532. package/scripts/lane/lane-relaunch.ts +9 -9
  533. package/scripts/lane/lane-report.ts +5 -4
  534. package/scripts/lane/lane-resume.ts +2 -2
  535. package/scripts/lane/lane-sampler.ts +55 -0
  536. package/scripts/lane/lane-seed.ts +7 -7
  537. package/scripts/lane/lane-stage-stats.ts +135 -0
  538. package/scripts/lane/lane-start-point.ts +8 -11
  539. package/scripts/lane/lane-stats.ts +60 -15
  540. package/scripts/lane/lane-stray.ts +140 -0
  541. package/scripts/lane/lane-vacant.ts +1 -1
  542. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  543. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  544. package/scripts/lane/openai-review-broker.ts +2 -4
  545. package/scripts/lib/ancestor-directories.ts +1 -1
  546. package/scripts/lib/bounded-pool.ts +2 -2
  547. package/scripts/lib/buffered-process.ts +4 -6
  548. package/scripts/lib/caddy-logs.sh +0 -0
  549. package/scripts/lib/cli-flags.ts +39 -6
  550. package/scripts/lib/error-message.ts +1 -1
  551. package/scripts/lib/json-value.ts +17 -3
  552. package/scripts/lib/poll.ts +1 -1
  553. package/scripts/lib/status-icons.ts +3 -3
  554. package/scripts/lib/timed-fetch.ts +1 -1
  555. package/scripts/lib/timeouts.ts +1 -1
  556. package/scripts/lines/bytes-command.ts +3 -4
  557. package/scripts/lines/effective-limit.ts +25 -12
  558. package/scripts/lines/line-budget.ts +47 -55
  559. package/scripts/lines/line-targets.ts +6 -2
  560. package/scripts/lines/lines-command.ts +3 -3
  561. package/scripts/lint/cspell-cached.ts +1 -1
  562. package/scripts/lint/cycle-recheck.ts +122 -0
  563. package/scripts/lint/format.ts +1 -2
  564. package/scripts/lint/lint-parallel.ts +34 -19
  565. package/scripts/lint/lint-related-scope.ts +25 -15
  566. package/scripts/lint/lint-related.ts +6 -7
  567. package/scripts/managed-marker/index.ts +1 -1
  568. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  569. package/scripts/notify/git-notify.ts +9 -7
  570. package/scripts/notify/telegram-notify.ts +53 -37
  571. package/scripts/notify/telegram-test-logic.ts +3 -3
  572. package/scripts/notify/telegram-test.ts +45 -30
  573. package/scripts/observations/observation-ledger-home.ts +14 -8
  574. package/scripts/observations/observation-ledger-line.ts +3 -2
  575. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  576. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  577. package/scripts/observations/observation-ledger.ts +14 -15
  578. package/scripts/observations/observation-record-cli.ts +83 -0
  579. package/scripts/observations/observation-record.ts +91 -0
  580. package/scripts/observations/observations-flush-cli.ts +1 -1
  581. package/scripts/observations/observations-flush-landing.ts +7 -6
  582. package/scripts/observations/observations-flush.ts +26 -27
  583. package/scripts/overrides/overrides-check.ts +18 -8
  584. package/scripts/package/package-scout-cli.ts +1 -1
  585. package/scripts/package/package-scout-format.ts +2 -2
  586. package/scripts/package/package-scout.ts +1 -1
  587. package/scripts/propagate/propagate-git-failure.ts +1 -1
  588. package/scripts/propagate/propagate-git.ts +7 -7
  589. package/scripts/propagate/propagate-plan.ts +2 -2
  590. package/scripts/propagate/propagate-publish.ts +2 -3
  591. package/scripts/propagate/propagate-run.ts +5 -7
  592. package/scripts/propagate/propagate-select.ts +1 -1
  593. package/scripts/propagate/propagate-steps.ts +19 -20
  594. package/scripts/propagate/propagate-targets.ts +6 -10
  595. package/scripts/propagate/propagate.ts +5 -5
  596. package/scripts/refactor/import-graph.ts +1 -1
  597. package/scripts/refactor/refactor-lint.ts +4 -10
  598. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  599. package/scripts/refactor/refactor-scan.ts +2 -2
  600. package/scripts/refactor/refactor-targets.ts +1 -1
  601. package/scripts/release/github-release-cli.ts +25 -3
  602. package/scripts/release/github-release-environment.ts +1 -0
  603. package/scripts/release/github-release-runs.ts +115 -0
  604. package/scripts/release/github-release.ts +13 -67
  605. package/scripts/release/release-cli.ts +21 -4
  606. package/scripts/release/release-history.ts +6 -10
  607. package/scripts/release/release-plan.ts +3 -3
  608. package/scripts/release/release-progress.ts +3 -4
  609. package/scripts/release/release-publish.ts +8 -9
  610. package/scripts/release/release-scope-cli.ts +8 -10
  611. package/scripts/release/release-tag.ts +6 -8
  612. package/scripts/release/release-worktree.ts +5 -5
  613. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  614. package/scripts/repo/auto-merge-setting.ts +1 -1
  615. package/scripts/repo/repo-setting.ts +4 -4
  616. package/scripts/repo/repository-labels.ts +1 -1
  617. package/scripts/repo/required-checks-logic.ts +3 -3
  618. package/scripts/repo/required-checks-report.ts +1 -1
  619. package/scripts/repo/ruleset-check-cli.ts +1 -1
  620. package/scripts/repo/ruleset-check.ts +1 -1
  621. package/scripts/report/report-format-reference.ts +26 -0
  622. package/scripts/report/report-lint-cli.ts +2 -2
  623. package/scripts/report/report-lint.ts +16 -2
  624. package/scripts/review/disposition-cli.ts +2 -2
  625. package/scripts/review/disposition-logic.ts +1 -1
  626. package/scripts/review/live-evidence.ts +9 -6
  627. package/scripts/review/review-attest-cli.ts +1 -2
  628. package/scripts/review/review-attest.ts +3 -3
  629. package/scripts/review/review-brief-cli.ts +19 -20
  630. package/scripts/review/review-brief.ts +29 -32
  631. package/scripts/review/review-checkout.ts +2 -2
  632. package/scripts/review/review-diff-parts.ts +3 -5
  633. package/scripts/review/review-diff-write.ts +1 -1
  634. package/scripts/review/review-finding-ledger.ts +7 -4
  635. package/scripts/review/review-findings-cli.ts +2 -2
  636. package/scripts/review/review-level.ts +4 -7
  637. package/scripts/review/review-record-cli.ts +73 -16
  638. package/scripts/review/review-record.ts +5 -4
  639. package/scripts/review/review-round2-cli.ts +2 -3
  640. package/scripts/review/review-round2.ts +13 -21
  641. package/scripts/review/review-stamps.ts +9 -71
  642. package/scripts/review/review-tree.ts +4 -5
  643. package/scripts/rules/bash-triggers.ts +4 -4
  644. package/scripts/rules/decision-oracle-batch.ts +5 -6
  645. package/scripts/rules/decision-oracle-stage.ts +1 -1
  646. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  647. package/scripts/rules/decision-oracle.ts +2 -2
  648. package/scripts/rules/delivered-rules.ts +61 -406
  649. package/scripts/rules/destructive-command.ts +2 -2
  650. package/scripts/rules/direct-filing.ts +4 -4
  651. package/scripts/rules/direct-pr-create.ts +2 -2
  652. package/scripts/rules/early-heartbeat.ts +15 -19
  653. package/scripts/rules/file-body.ts +5 -6
  654. package/scripts/rules/filing-cap.ts +6 -7
  655. package/scripts/rules/filing-offer.ts +1 -1
  656. package/scripts/rules/firing-point.ts +6 -6
  657. package/scripts/rules/gh-api.ts +2 -2
  658. package/scripts/rules/git-argv.ts +3 -3
  659. package/scripts/rules/git-force.ts +2 -2
  660. package/scripts/rules/hook-context-line.ts +31 -0
  661. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  662. package/scripts/rules/implementation-cut.ts +35 -32
  663. package/scripts/rules/index-guard.ts +2 -2
  664. package/scripts/rules/issue-citation.ts +7 -7
  665. package/scripts/rules/issue-comments.ts +21 -13
  666. package/scripts/rules/josh-git-bare.ts +2 -2
  667. package/scripts/rules/lane-background.ts +14 -16
  668. package/scripts/rules/lane-carry-conflict.ts +41 -5
  669. package/scripts/rules/lane-interactive-ask.ts +6 -9
  670. package/scripts/rules/lane-park.ts +12 -16
  671. package/scripts/rules/lane-split-park.ts +1 -2
  672. package/scripts/rules/lane-switch-main.ts +10 -13
  673. package/scripts/rules/last-prompt.ts +1 -1
  674. package/scripts/rules/oracle-consulted.ts +5 -5
  675. package/scripts/rules/oracle-firing.ts +6 -9
  676. package/scripts/rules/oracle-list-cli.ts +2 -2
  677. package/scripts/rules/permission-guards.ts +2 -2
  678. package/scripts/rules/piped-verification.ts +79 -9
  679. package/scripts/rules/poll-loop.ts +9 -11
  680. package/scripts/rules/pre-gate-cut.ts +33 -30
  681. package/scripts/rules/prior-comment-read.ts +3 -3
  682. package/scripts/rules/protected-files.ts +25 -13
  683. package/scripts/rules/raw-field-body.ts +3 -4
  684. package/scripts/rules/reply-language.ts +1 -1
  685. package/scripts/rules/rule-body-guard.ts +10 -12
  686. package/scripts/rules/rule-guard.ts +1 -1
  687. package/scripts/rules/rule-list.ts +51 -0
  688. package/scripts/rules/rule-registry-rows.ts +282 -0
  689. package/scripts/rules/rule-registry.ts +109 -0
  690. package/scripts/rules/rule-value-cache.ts +2 -2
  691. package/scripts/rules/rule-value-cli.ts +6 -4
  692. package/scripts/rules/rule-value.ts +61 -22
  693. package/scripts/rules/run-tail-rule.ts +11 -15
  694. package/scripts/rules/shell-body-trigger.ts +7 -7
  695. package/scripts/rules/shell-segments.ts +2 -4
  696. package/scripts/rules/stop-rules.ts +54 -41
  697. package/scripts/rules/tail-commands.ts +1 -1
  698. package/scripts/rules/test-declared-commit.ts +2 -2
  699. package/scripts/rules/third-party-write.ts +3 -3
  700. package/scripts/rules/worktree-guard.ts +12 -5
  701. package/scripts/run/add/run-add-cli.ts +165 -0
  702. package/scripts/run/add/run-add.ts +124 -0
  703. package/scripts/run/board/run-board-cli.ts +207 -0
  704. package/scripts/run/board/run-board-closed.ts +95 -0
  705. package/scripts/run/board/run-board-every.ts +60 -0
  706. package/scripts/run/board/run-board-fetch.ts +38 -0
  707. package/scripts/run/board/run-board-fit.ts +219 -0
  708. package/scripts/run/board/run-board-github.ts +162 -0
  709. package/scripts/run/board/run-board-header.ts +275 -0
  710. package/scripts/run/board/run-board-kind.ts +35 -0
  711. package/scripts/run/board/run-board-labels.ts +299 -0
  712. package/scripts/run/board/run-board-layout.ts +222 -0
  713. package/scripts/run/board/run-board-link.ts +31 -0
  714. package/scripts/run/board/run-board-machine.ts +198 -0
  715. package/scripts/run/board/run-board-notes.ts +103 -0
  716. package/scripts/run/board/run-board-phase.ts +136 -0
  717. package/scripts/run/board/run-board-plan.ts +129 -0
  718. package/scripts/run/board/run-board-read.ts +62 -0
  719. package/scripts/run/board/run-board-render-legend.ts +82 -0
  720. package/scripts/run/board/run-board-render-notes.ts +77 -0
  721. package/scripts/run/board/run-board-render-slot.ts +50 -0
  722. package/scripts/run/board/run-board-render.ts +407 -0
  723. package/scripts/run/board/run-board-scope.ts +17 -0
  724. package/scripts/run/board/run-board-screen.ts +43 -0
  725. package/scripts/run/board/run-board-span.ts +66 -0
  726. package/scripts/run/board/run-board-spin.ts +115 -0
  727. package/scripts/run/board/run-board-state.ts +113 -0
  728. package/scripts/run/board/run-board-status.ts +279 -0
  729. package/scripts/run/board/run-board-tick.ts +210 -0
  730. package/scripts/run/board/run-board-track.ts +22 -0
  731. package/scripts/run/board/run-board-usage-read.ts +255 -0
  732. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  733. package/scripts/run/board/run-board-usage-text.ts +80 -0
  734. package/scripts/run/board/run-board-usage.ts +165 -0
  735. package/scripts/run/carry/run-carry-added.ts +62 -0
  736. package/scripts/run/carry/run-carry-args.ts +25 -22
  737. package/scripts/run/carry/run-carry-change.ts +1 -1
  738. package/scripts/run/carry/run-carry-cli.ts +71 -48
  739. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  740. package/scripts/run/carry/run-carry-ended.ts +85 -0
  741. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  742. package/scripts/run/carry/run-carry-stash.ts +3 -2
  743. package/scripts/run/carry/run-carry-streak.ts +8 -10
  744. package/scripts/run/carry/run-carry.ts +85 -89
  745. package/scripts/run/cut/run-cut-args.ts +7 -7
  746. package/scripts/run/cut/run-cut-cli.ts +68 -37
  747. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  748. package/scripts/run/cut/run-cut-report.ts +37 -16
  749. package/scripts/run/cut/run-cut.ts +63 -77
  750. package/scripts/run/detached-launch.ts +35 -50
  751. package/scripts/run/entry/run-entry-cli.ts +48 -27
  752. package/scripts/run/entry/run-entry-stop.ts +7 -9
  753. package/scripts/run/entry/run-entry.ts +5 -6
  754. package/scripts/run/event/run-event-cli.ts +5 -6
  755. package/scripts/run/event/run-event-filed.ts +69 -0
  756. package/scripts/run/event/run-event-follow.ts +3 -3
  757. package/scripts/run/event/run-event-plan.ts +38 -0
  758. package/scripts/run/event/run-event-render.ts +10 -4
  759. package/scripts/run/event/run-event-scope.ts +47 -18
  760. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  761. package/scripts/run/event/run-event-stream.ts +172 -43
  762. package/scripts/run/event/run-event-watch.ts +4 -6
  763. package/scripts/run/hold/run-hold-cli.ts +65 -62
  764. package/scripts/run/hold/run-hold.ts +88 -46
  765. package/scripts/run/merge/run-merge-cli.ts +116 -77
  766. package/scripts/run/merge/run-merge-collect.ts +107 -0
  767. package/scripts/run/merge/run-merge-steps.ts +112 -65
  768. package/scripts/run/merge/run-merge-token.ts +30 -0
  769. package/scripts/run/merge/run-merge.ts +31 -22
  770. package/scripts/run/progress/run-progress-args.ts +4 -4
  771. package/scripts/run/progress/run-progress-cli.ts +39 -50
  772. package/scripts/run/progress/run-progress-clock.ts +25 -32
  773. package/scripts/run/progress/run-progress-config.ts +6 -9
  774. package/scripts/run/progress/run-progress-read.ts +9 -10
  775. package/scripts/run/progress/run-progress.ts +48 -53
  776. package/scripts/run/review/run-review-cli.ts +6 -6
  777. package/scripts/run/review/run-review-steps.ts +6 -6
  778. package/scripts/run/review/run-review.ts +9 -11
  779. package/scripts/run/run-cli-fault.ts +29 -0
  780. package/scripts/run/run-ending-cli.ts +3 -3
  781. package/scripts/run/run-ending.ts +10 -14
  782. package/scripts/run/run-halfrun-resume.ts +6 -8
  783. package/scripts/run/run-headless.ts +25 -12
  784. package/scripts/run/run-invocation.ts +17 -22
  785. package/scripts/run/run-label.ts +7 -5
  786. package/scripts/run/run-liveness-cli.ts +19 -6
  787. package/scripts/run/run-liveness.ts +27 -38
  788. package/scripts/run/run-next-cli.ts +5 -9
  789. package/scripts/run/run-next.ts +4 -5
  790. package/scripts/run/run-parent-cut-hook.ts +10 -12
  791. package/scripts/run/run-preflight.ts +25 -29
  792. package/scripts/run/run-prep-cli.ts +17 -13
  793. package/scripts/run/run-prep-locate.ts +4 -5
  794. package/scripts/run/run-prep.ts +7 -10
  795. package/scripts/run/run-prrun-resume.ts +2 -2
  796. package/scripts/run/run-report-cli.ts +4 -4
  797. package/scripts/run/run-report.ts +9 -14
  798. package/scripts/run/run-retrospective.ts +3 -3
  799. package/scripts/run/run-section.ts +42 -0
  800. package/scripts/run/run-stage-read.ts +2 -2
  801. package/scripts/run/run-stage.ts +6 -4
  802. package/scripts/run/run-status-cli.ts +7 -5
  803. package/scripts/run/run-status.ts +6 -7
  804. package/scripts/run/run-step-cli.ts +13 -15
  805. package/scripts/run/run-step.ts +62 -48
  806. package/scripts/run/run-stop-notify.ts +7 -8
  807. package/scripts/run/run-stranded-cli.ts +1 -1
  808. package/scripts/run/run-stranded-detect.ts +4 -4
  809. package/scripts/run/run-stranded.ts +11 -13
  810. package/scripts/run/run-tail-cli.ts +15 -16
  811. package/scripts/run/run-tail.ts +14 -33
  812. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  813. package/scripts/run/run-watcher-guard.ts +11 -12
  814. package/scripts/run/run-watcher-hook.ts +6 -12
  815. package/scripts/run/ship/run-ship-cli.ts +67 -33
  816. package/scripts/run/ship/run-ship-detach.ts +15 -13
  817. package/scripts/run/ship/run-ship-lock.ts +1 -1
  818. package/scripts/run/ship/run-ship-next.ts +7 -8
  819. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  820. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  821. package/scripts/run/ship/run-ship-probe.ts +4 -4
  822. package/scripts/run/ship/run-ship-return.ts +1 -1
  823. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  824. package/scripts/run/ship/run-ship-review.ts +12 -14
  825. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  826. package/scripts/run/ship/run-ship-stage.ts +80 -26
  827. package/scripts/run/ship/run-ship-steps.ts +26 -16
  828. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  829. package/scripts/run/ship/run-ship-sync.ts +9 -8
  830. package/scripts/run/ship/run-ship.ts +17 -32
  831. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  832. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  833. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  834. package/scripts/run/tidy/run-tidy.ts +4 -3
  835. package/scripts/run/wake/run-wake-cli.ts +27 -33
  836. package/scripts/run/wake/run-wake-describe.ts +76 -29
  837. package/scripts/run/wake/run-wake-driver.ts +14 -14
  838. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  839. package/scripts/run/wake/run-wake-loop.ts +13 -21
  840. package/scripts/run/wake/run-wake-restart.ts +4 -5
  841. package/scripts/run/wake/run-wake-session.ts +23 -27
  842. package/scripts/run/wake/run-wake.ts +57 -328
  843. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  844. package/scripts/safe-chain/pack-hook.ts +2 -2
  845. package/scripts/safe-chain/preinstall-command.ts +2 -2
  846. package/scripts/security/security-audit-logic.ts +1 -1
  847. package/scripts/security/security-audit-provision-logic.ts +1 -1
  848. package/scripts/security/security-audit-provision.ts +2 -2
  849. package/scripts/security/security-audit.ts +5 -5
  850. package/scripts/security/security-updates-logic.ts +2 -3
  851. package/scripts/security/security-updates.ts +2 -4
  852. package/scripts/self-sync-guard/index.ts +1 -1
  853. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  854. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  855. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  856. package/scripts/sonar/sonar-hotspots.ts +1 -1
  857. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  858. package/scripts/sonar/sonar-new-code.ts +1 -1
  859. package/scripts/sonar/sonar-project.ts +1 -1
  860. package/scripts/split/split-assess-cli.ts +1 -1
  861. package/scripts/split/split-assess.ts +3 -3
  862. package/scripts/sync/directory-copy-guard.ts +2 -3
  863. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  864. package/scripts/sync/managed-config-scope.ts +4 -4
  865. package/scripts/sync/plugin-skill-directories.ts +2 -2
  866. package/scripts/sync/reconcile-templates.ts +17 -8
  867. package/scripts/sync/removed-skill-manifest.ts +2 -3
  868. package/scripts/sync/sync-ai-files.ts +7 -7
  869. package/scripts/sync/sync-configs.ts +30 -3
  870. package/scripts/sync/sync-hook-safety.ts +2 -2
  871. package/scripts/sync/sync.ts +23 -10
  872. package/scripts/sync/synced-paths.ts +2 -1
  873. package/scripts/sync/workflow-pin-logic.ts +1 -1
  874. package/scripts/test/test-declared-changed.ts +4 -4
  875. package/scripts/test/test-declared-logic.ts +2 -3
  876. package/scripts/test/test-declared-match.ts +25 -4
  877. package/scripts/test/test-declared.ts +26 -9
  878. package/scripts/test/test-red-commit.ts +3 -2
  879. package/scripts/test/test-red-logic.ts +7 -14
  880. package/scripts/test/test-red.ts +12 -47
  881. package/scripts/test/test-related-scope.ts +2 -3
  882. package/scripts/test/test-related.ts +3 -3
  883. package/scripts/test/test-type-logic.ts +1 -2
  884. package/scripts/test/test-unit-guard.ts +13 -17
  885. package/scripts/test/unit-worker-share.ts +7 -8
  886. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  887. package/scripts/time-runtime/time-background.ts +17 -21
  888. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  889. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  890. package/scripts/time-runtime/time-bundles.ts +11 -12
  891. package/scripts/time-runtime/time-call-identity.ts +1 -1
  892. package/scripts/time-runtime/time-command-key.ts +2 -2
  893. package/scripts/time-runtime/time-density-hook.ts +8 -11
  894. package/scripts/time-runtime/time-density.ts +5 -5
  895. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  896. package/scripts/time-runtime/time-format.ts +5 -5
  897. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  898. package/scripts/time-runtime/time-instant.ts +1 -1
  899. package/scripts/time-runtime/time-markers.ts +15 -19
  900. package/scripts/time-runtime/time-phase-names.ts +3 -3
  901. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  902. package/scripts/time-runtime/time-round-trips.ts +20 -23
  903. package/scripts/time-runtime/time-shell.ts +8 -8
  904. package/scripts/time-runtime/time-single-check.ts +1 -2
  905. package/scripts/time-runtime/time-spans.ts +35 -40
  906. package/scripts/time-runtime/time-tool-call.ts +15 -16
  907. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  908. package/scripts/time-runtime/time-writes.ts +5 -5
  909. package/scripts/ui/ui-routes-cli.ts +1 -2
  910. package/scripts/ui/ui-routes.ts +1 -2
  911. package/scripts/version/bump-version.ts +1 -1
  912. package/scripts/version/fresh-metadata-cache.ts +2 -2
  913. package/scripts/version/latest-corepack.ts +129 -98
  914. package/scripts/version/latest-lane-guard.ts +1 -1
  915. package/scripts/version/latest-scope-cli.ts +2 -2
  916. package/scripts/version/latest-stamp.ts +1 -2
  917. package/scripts/version/latest-update.ts +2 -2
  918. package/scripts/version/npm-registry.ts +2 -2
  919. package/scripts/version/package-manager-version.ts +18 -0
  920. package/scripts/version/publishable-range-check.ts +2 -1
  921. package/scripts/version/publishable-range.ts +1 -1
  922. package/scripts/version/release-age.ts +11 -11
  923. package/scripts/version/release-hold.ts +2 -2
  924. package/scripts/version/safe-chain-version-update.ts +3 -3
  925. package/scripts/version/version-check-logic.ts +2 -3
  926. package/scripts/version/version-check.ts +1 -2
  927. package/scripts/version/version-command-config.ts +2 -2
  928. package/scripts/version/version-commands.ts +3 -3
  929. package/scripts/version/version-remote.ts +4 -4
  930. package/scripts/version/version-targets.ts +2 -2
  931. package/templates/gitignore +7 -0
  932. package/templates/workflows/github-release.yml +4 -0
  933. package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
  934. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  935. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  936. package/scripts/backlog/backlog-restructure.ts +0 -152
  937. package/scripts/rules/issue-fold-rule.ts +0 -72
  938. package/scripts/rules/wip-cap.ts +0 -63
  939. package/scripts/run/run-issue-number.ts +0 -19
@@ -0,0 +1,162 @@
1
+ import type { LedgerLoad, MachineBudget } from './machine-capacity'
2
+
3
+ // The ledger's admission arithmetic, kept apart from the markers `core-budget.ts` reads and writes so
4
+ // that file stays under its line ceiling as the budget grew a memory side.
5
+ // Everything here is a pure function of the ledger it is handed.
6
+
7
+ const MS_PER_SECOND = 1000
8
+ // **How long an admitted claim's tool takes to reach its declared peak.** The machine reading holds only
9
+ // what a tool has already allocated, so a claim admitted moments ago is not in it yet: adding its
10
+ // declared memory back would admit the next claim into memory about to be taken — the concurrent start
11
+ // this ledger exists to stop. Until the window passes, the claim's memory counts only in the FIFO walk; a
12
+ // tool partway up is then counted twice, which costs a slower admission, never a swap. Its cores are in
13
+ // the reading from the start, so the window does not apply to them.
14
+ const RAMP_UP_MS = 30_000
15
+
16
+ // What admission reads from a marker. `memory_mb` and `admitted_at` are optional because a marker an
17
+ // older `josh` wrote has neither: it declares no memory, and it counts as load from outside the ledger.
18
+ interface LedgerReservation {
19
+ weight: number
20
+ claimed_at: number
21
+ memory_mb?: number | undefined
22
+ admitted_at?: number | undefined
23
+ }
24
+
25
+ interface LedgerEntry {
26
+ // The marker's filename, which is its identity in the ledger and the tiebreak when two reservations
27
+ // share a claim time.
28
+ key: string
29
+ reservation: LedgerReservation
30
+ }
31
+
32
+ // A claim admitted at the wait cap rather than by room in the budget — the run went ahead past the
33
+ // budget, and the gate's summary says so.
34
+ interface Overflow {
35
+ waited_ms: number
36
+ ledger: LedgerLoad
37
+ budget: MachineBudget
38
+ }
39
+
40
+ interface Admission {
41
+ overflow: Overflow | undefined
42
+ }
43
+
44
+ // Claim order, with the filename as the tiebreak so every reader agrees on the same ledger order
45
+ // however the wall clock rounded two near-simultaneous claims.
46
+ function compare_claim(left: LedgerEntry, right: LedgerEntry): number {
47
+ const by_time = left.reservation.claimed_at - right.reservation.claimed_at
48
+
49
+ return by_time === 0 ? left.key.localeCompare(right.key) : by_time
50
+ }
51
+
52
+ function add_load(totals: LedgerLoad, reservation: LedgerReservation): void {
53
+ totals.cores += reservation.weight
54
+ totals.memory_mb += reservation.memory_mb ?? 0
55
+ }
56
+
57
+ function exceeds(totals: LedgerLoad, budget: MachineBudget): boolean {
58
+ return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb
59
+ }
60
+
61
+ // **The keys admitted under FIFO.** The head always runs — a single check heavier than the whole
62
+ // machine must not wait for room that will never come — and each later reservation runs while the
63
+ // cumulative weight ahead of it still fits the budget. The first that does not fit stops the walk, so a
64
+ // place is never jumped: admission is in claim order, which is what removes the start-time asymmetry.
65
+ // Memory is walked the same way, so a claim whose tool would not fit in free memory waits like one whose
66
+ // cores would not fit.
67
+ function admitted_keys(
68
+ reservations: ReadonlyArray<LedgerEntry>,
69
+ budget: number,
70
+ memory_budget = Infinity,
71
+ ): Set<string> {
72
+ const limit = { cores: budget, memory_mb: memory_budget }
73
+ const totals = { cores: 0, memory_mb: 0 }
74
+ const admitted = new Set<string>()
75
+
76
+ for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
77
+ add_load(totals, entry.reservation)
78
+
79
+ if (index !== 0 && exceeds(totals, limit)) break
80
+
81
+ admitted.add(entry.key)
82
+ }
83
+
84
+ return admitted
85
+ }
86
+
87
+ function is_admitted(
88
+ key: string,
89
+ reservations: ReadonlyArray<LedgerEntry>,
90
+ budget: MachineBudget,
91
+ ): boolean {
92
+ return admitted_keys(reservations, budget.cores, budget.memory_mb).has(key)
93
+ }
94
+
95
+ function sum_load(reservations: ReadonlyArray<LedgerEntry>): LedgerLoad {
96
+ const load = { cores: 0, memory_mb: 0 }
97
+
98
+ for (const entry of reservations) add_load(load, entry.reservation)
99
+
100
+ return load
101
+ }
102
+
103
+ function is_ramped(reservation: LedgerReservation, now: number): boolean {
104
+ const { admitted_at } = reservation
105
+
106
+ return admitted_at !== undefined && now - admitted_at >= RAMP_UP_MS
107
+ }
108
+
109
+ // **The load the ledger already accounts for.** CPU use shows in the reading the moment a tool starts,
110
+ // so every admitted claim's cores count at once; memory grows as the tool allocates, so only the claims
111
+ // admitted long enough ago to be in the reading count their memory.
112
+ function ledger_load(reservations: ReadonlyArray<LedgerEntry>, now: number): LedgerLoad {
113
+ const admitted = reservations.filter((entry) => entry.reservation.admitted_at !== undefined)
114
+ const ramped = admitted.filter((entry) => is_ramped(entry.reservation, now))
115
+
116
+ return { cores: sum_load(admitted).cores, memory_mb: sum_load(ramped).memory_mb }
117
+ }
118
+
119
+ function total_weight(reservations: ReadonlyArray<LedgerEntry>): number {
120
+ return sum_load(reservations).cores
121
+ }
122
+
123
+ // The weight actually running at once — what the reproduction test asserts stays within the budget.
124
+ function admitted_load(reservations: ReadonlyArray<LedgerEntry>, budget: number): number {
125
+ const admitted = admitted_keys(reservations, budget)
126
+
127
+ return total_weight(reservations.filter((entry) => admitted.has(entry.key)))
128
+ }
129
+
130
+ // The memory side of an overflow, so a claim held back by memory is not reported as a core shortfall.
131
+ // A budget that read no memory set no memory limit, and says nothing.
132
+ function describe_memory(ledger: LedgerLoad, budget: MachineBudget): string {
133
+ if (!Number.isFinite(budget.memory_mb)) return ''
134
+
135
+ return ` and ${String(Math.round(ledger.memory_mb))} MB of memory against ${String(Math.round(budget.memory_mb))} MB`
136
+ }
137
+
138
+ // The summary line for a claim admitted past the budget, or undefined for one that fitted.
139
+ function describe_overflow(admission: Admission): string | undefined {
140
+ const { overflow } = admission
141
+
142
+ if (overflow === undefined) return undefined
143
+
144
+ const { ledger, budget } = overflow
145
+ const waited = String(Math.round(overflow.waited_ms / MS_PER_SECOND))
146
+ const cores = `the ledger held ${String(ledger.cores)} cores against a budget of ${String(budget.cores)}`
147
+
148
+ return `started past the core budget after ${waited}s — ${cores}${describe_memory(ledger, budget)}`
149
+ }
150
+
151
+ const core_admission = {
152
+ RAMP_UP_MS,
153
+ admitted_keys,
154
+ admitted_load,
155
+ describe_overflow,
156
+ is_admitted,
157
+ ledger_load,
158
+ sum_load,
159
+ }
160
+
161
+ export type { Admission, LedgerEntry, Overflow }
162
+ export { core_admission }
@@ -6,23 +6,20 @@ import { PLATFORM_TEMP_ROOT } from '#scripts/josh/platform-temporary'
6
6
  import { process_identity } from '#scripts/josh/process-identity'
7
7
  import { process_owner_schema } from '#scripts/josh/process-owner'
8
8
  import { stamp_file } from '#scripts/josh/stamp-file'
9
+ import { json_value } from '#scripts/lib/json-value'
9
10
  import { unit_worker_share } from '#scripts/test/unit-worker-share'
10
11
  import { z } from 'zod'
12
+ import { core_admission, type Admission, type LedgerEntry, type Overflow } from './core-admission'
13
+ import { machine_capacity, type MachineBudget, type MachineReading } from './machine-capacity'
11
14
 
12
- // A machine-wide weighted core budget with admission control (joshuafolkken/kit#2351).
15
+ // A machine-wide weighted core budget with admission control.
13
16
  //
14
- // **The gate's CPU budget used to be decided once, at the gate's start, and never revisited.**
15
- // `announce_gate_plan` counted the unit runs alive the instant it began and sized itself against that
16
- // one reading — so the common case (nothing else in a gate yet) had every gate conclude it was alone
17
- // and reserve the whole machine, and only a gate that *started* later deferred. Three overlapping gates
18
- // therefore demanded thirty cores of an eleven-core machine, which is the "usually fine, occasionally
19
- // saturates" this module removes.
20
- //
21
- // **The fix is admission rather than recomputation.** A heavy step declares the cores it needs, claims
22
- // a place in a machine-wide ledger, and waits while the ledger is full — so the peak cannot exceed the
23
- // budget by construction, and the asymmetry ("whoever started first took everything") disappears
24
- // because a place is claimed in claim order rather than seized at start. Waiting is what replaces the
25
- // recomputation `unit-worker-share.ts` did: a step that could not fit does not shrink, it defers.
17
+ // **Admission rather than a budget sized once at the gate's start.** A budget read once at the start
18
+ // has every gate that sees no sibling conclude it is alone and reserve the whole machine, so
19
+ // overlapping gates oversubscribe it. Instead a heavy step declares the cores it needs, claims a place
20
+ // in a machine-wide ledger, and waits while the ledger is full — so the peak cannot exceed the budget
21
+ // by construction, and a place is claimed in claim order rather than seized at start. A step that
22
+ // could not fit does not shrink, it defers.
26
23
  //
27
24
  // **A solo run is bit-for-bit unchanged, and that is arithmetic rather than a branch.** The gate's
28
25
  // weights are its `reserved_cores` (the static checks) and its `unit_worker_cap` (the unit suite), and
@@ -30,10 +27,15 @@ import { z } from 'zod'
30
27
  // to the whole budget and every one is admitted the instant it is made, with no poll and no wait. Under
31
28
  // concurrency the same weights sum past the budget and the ledger is what holds the machine down.
32
29
  //
33
- // **Liveness is `process_identity`'s, reused rather than re-invented** (joshuafolkken/kit#1245). A run
30
+ // **Liveness is `process_identity`'s, reused rather than re-invented.** A run
34
31
  // killed outright leaves its marker behind, and a ledger that trusted the file alone would fill forever
35
32
  // and admit nothing. The pid-and-start-time pair a marker carries is the same identity the unit-run
36
33
  // marker keeps, swept on read the moment its process is gone.
34
+ //
35
+ // **The budget is what the machine has free, in cores and in memory.** The
36
+ // core count stays the ceiling, but load from outside the ledger is subtracted from it, and a claim
37
+ // waits while the memory its tool holds is not free — `machine-capacity.ts` reads both. A claim marks
38
+ // its marker admitted once it runs, so the reading's load is split into the ledger's and the rest.
37
39
 
38
40
  const RESERVED_PREFIX = 'josh-core-reserved-'
39
41
  const RESERVED_SUFFIX = '.json'
@@ -48,7 +50,7 @@ const WAIT_CAP_MS = 120_000
48
50
  const MIN_BUDGET = 1
49
51
 
50
52
  // **The cores each heavy tool occupies, declared once for both places that reserve them**
51
- // (joshuafolkken/kit#3345). `gate-plan.ts`'s checks and the `josh` commands that run the same tools
53
+ // `gate-plan.ts`'s checks and the `josh` commands that run the same tools
52
54
  // directly read these, so a direct `josh lint` claims what the gate's lint claims. The lint, type check
53
55
  // and spell check numbers are `gate-plan.ts`'s measured table, floored. The whole-tree eslint scan
54
56
  // behind `josh lines` and `josh refactor:scan` runs in one process: measured cold on the 11-core
@@ -60,29 +62,47 @@ const CORE_WEIGHTS = {
60
62
  eslint_scan: 1,
61
63
  } as const
62
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
+
63
78
  // **The environment mark that says a parent already holds this process's cores**
64
- // (joshuafolkken/kit#3345). `josh gate` reserves per check and then spawns `pnpm josh lint`. Without
79
+ // `josh gate` reserves per check and then spawns `pnpm josh lint`. Without
65
80
  // the mark, that child's own dispatch would claim a second place for the cores its parent already
66
81
  // holds. Every holder sets it, and every child inherits it through the environment and claims nothing.
67
82
  const HELD_KEY = 'JOSH_CORE_RESERVED'
68
83
  const HELD_VALUE = '1'
69
84
 
85
+ // `memory_mb` and `admitted_at` are optional so a marker an older `josh` wrote still reads: it holds no
86
+ // declared memory, and it counts as load from outside the ledger until it is gone.
70
87
  const reservation_schema = process_owner_schema.extend({
71
88
  weight: z.number(),
72
89
  claimed_at: z.number(),
90
+ memory_mb: z.number().optional(),
91
+ admitted_at: z.number().optional(),
73
92
  })
74
93
 
75
94
  type Reservation = z.infer<typeof reservation_schema>
76
95
 
77
- interface LiveReservation {
78
- // The marker's filename, which is its identity in the ledger and the tiebreak when two reservations
79
- // share a claim time.
80
- key: string
96
+ type ReservationFields = Pick<Reservation, 'weight' | 'claimed_at' | 'memory_mb' | 'admitted_at'>
97
+
98
+ interface LiveReservation extends LedgerEntry {
81
99
  reservation: Reservation
82
100
  }
83
101
 
84
102
  interface ReserveOptions {
85
103
  budget?: number
104
+ memory_mb?: number | undefined
105
+ read_machine?: () => Promise<MachineReading>
86
106
  wait_cap_ms?: number
87
107
  poll_interval_ms?: number
88
108
  directory?: string
@@ -92,6 +112,7 @@ interface ReserveOptions {
92
112
 
93
113
  interface Handle {
94
114
  target: string
115
+ admission: Admission
95
116
  }
96
117
 
97
118
  function marker_name(key: string): string {
@@ -109,13 +130,7 @@ function read_reservation(source: string): Reservation | undefined {
109
130
 
110
131
  if (raw === undefined) return undefined
111
132
 
112
- try {
113
- const parsed = reservation_schema.safeParse(JSON.parse(raw))
114
-
115
- return parsed.success ? parsed.data : undefined
116
- } catch {
117
- return undefined
118
- }
133
+ return json_value.parse_with(raw, reservation_schema)
119
134
  }
120
135
 
121
136
  // **A dead marker is removed, not merely skipped** — otherwise a reissued pid turns a leaked place into
@@ -141,10 +156,13 @@ function live_reservation(source: string): Reservation | undefined {
141
156
  }
142
157
 
143
158
  // An unreadable temp directory answers "no other reservation", the direction that admits rather than
144
- // stalls a run on a guess.
159
+ // stalls a run on a guess. The suffix leaves out `replace_stamp`'s in-flight temporary copy of a marker,
160
+ // which would otherwise count one place twice.
145
161
  function marker_files(directory: string): Array<string> {
146
162
  try {
147
- return readdirSync(directory).filter((name) => name.startsWith(RESERVED_PREFIX))
163
+ return readdirSync(directory).filter(
164
+ (name) => name.startsWith(RESERVED_PREFIX) && name.endsWith(RESERVED_SUFFIX),
165
+ )
148
166
  } catch {
149
167
  return []
150
168
  }
@@ -158,50 +176,6 @@ function live_reservations(directory: string = PLATFORM_TEMP_ROOT): Array<LiveRe
158
176
  })
159
177
  }
160
178
 
161
- // Claim order, with the filename as the tiebreak so every reader agrees on the same ledger order
162
- // however the wall clock rounded two near-simultaneous claims.
163
- function compare_claim(left: LiveReservation, right: LiveReservation): number {
164
- const by_time = left.reservation.claimed_at - right.reservation.claimed_at
165
-
166
- return by_time === 0 ? left.key.localeCompare(right.key) : by_time
167
- }
168
-
169
- // **The keys admitted under FIFO.** The head always runs — a single check heavier than the whole
170
- // machine must not wait for room that will never come — and each later reservation runs while the
171
- // cumulative weight ahead of it still fits the budget. The first that does not fit stops the walk, so a
172
- // place is never jumped: admission is in claim order, which is what removes the start-time asymmetry.
173
- function admitted_keys(reservations: ReadonlyArray<LiveReservation>, budget: number): Set<string> {
174
- const admitted = new Set<string>()
175
- let cumulative = 0
176
-
177
- for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
178
- cumulative += entry.reservation.weight
179
-
180
- if (index !== 0 && cumulative > budget) break
181
-
182
- admitted.add(entry.key)
183
- }
184
-
185
- return admitted
186
- }
187
-
188
- function is_admitted(
189
- key: string,
190
- reservations: ReadonlyArray<LiveReservation>,
191
- budget: number,
192
- ): boolean {
193
- return admitted_keys(reservations, budget).has(key)
194
- }
195
-
196
- // The weight actually running at once — what the reproduction test asserts stays within the budget.
197
- function admitted_load(reservations: ReadonlyArray<LiveReservation>, budget: number): number {
198
- const admitted = admitted_keys(reservations, budget)
199
-
200
- return reservations
201
- .filter((entry) => admitted.has(entry.key))
202
- .reduce((total, entry) => total + entry.reservation.weight, 0)
203
- }
204
-
205
179
  // `Math.max` propagates `NaN` rather than clamping it, so an unusable budget is caught before it could
206
180
  // make every comparison false and admit everything — the hole `gate-plan.ts` closes for the same reason.
207
181
  function normalize_budget(budget: number): number {
@@ -214,23 +188,30 @@ async function default_sleep(ms: number): Promise<void> {
214
188
  })
215
189
  }
216
190
 
217
- function write_reservation(target: string, weight: number, claimed_at: number): void {
218
- stamp_file.write_stamp(target, { ...process_identity.own_fields(), weight, claimed_at })
191
+ // **Replaced atomically, never unlinked and recreated**: the admitted rewrite lands on a marker other
192
+ // lanes are polling, and a reader that hit the gap between an unlink and its create would see the ledger
193
+ // without this place and admit past it.
194
+ function write_reservation(target: string, fields: ReservationFields): void {
195
+ stamp_file.replace_stamp(target, { ...process_identity.own_fields(), ...fields })
219
196
  }
220
197
 
221
198
  // The clock and cadence a wait runs on, resolved apart from the ledger fields so `reserve` stays under
222
- // the complexity limit — each default is a branch, and six in one function is past it.
199
+ // the complexity limit — each default is a branch.
223
200
  interface TimingConfig {
224
201
  now: () => number
225
202
  sleep: (ms: number) => Promise<void>
226
203
  poll_interval_ms: number
204
+ wait_cap_ms: number
227
205
  }
228
206
 
229
207
  interface WaitContext extends TimingConfig {
208
+ read_machine: () => Promise<MachineReading>
230
209
  key: string
210
+ target: string
231
211
  directory: string
232
212
  budget: number
233
213
  deadline: number
214
+ fields: ReservationFields
234
215
  }
235
216
 
236
217
  function resolve_timing(options: ReserveOptions): TimingConfig {
@@ -238,39 +219,96 @@ function resolve_timing(options: ReserveOptions): TimingConfig {
238
219
  now: options.now ?? Date.now,
239
220
  sleep: options.sleep ?? default_sleep,
240
221
  poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
222
+ wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS,
241
223
  }
242
224
  }
243
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.
228
+ async function current_budget(
229
+ context: WaitContext,
230
+ reservations: ReadonlyArray<LiveReservation>,
231
+ ): Promise<MachineBudget> {
232
+ if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity }
233
+
234
+ const reading = await context.read_machine()
235
+ const ledger = core_admission.ledger_load(reservations, context.now())
236
+ const budget = machine_capacity.machine_budget(context.budget, reading, ledger)
237
+
238
+ return { ...budget, cores: normalize_budget(budget.cores) }
239
+ }
240
+
241
+ // The claim is admitted: its marker records when, which moves its load from "load outside the ledger"
242
+ // to "load the ledger holds" for every later reader — its cores at once, its memory once its tool has
243
+ // had time to ramp up.
244
+ function admit(context: WaitContext, overflow?: Overflow): Admission {
245
+ write_reservation(context.target, { ...context.fields, admitted_at: context.now() })
246
+
247
+ return { overflow }
248
+ }
249
+
250
+ function overflow_of(
251
+ context: WaitContext,
252
+ reservations: ReadonlyArray<LiveReservation>,
253
+ budget: MachineBudget,
254
+ ): Overflow {
255
+ return {
256
+ waited_ms: context.now() - context.fields.claimed_at,
257
+ ledger: core_admission.sum_load(reservations),
258
+ budget,
259
+ }
260
+ }
261
+
262
+ async function poll_admission(context: WaitContext): Promise<Admission | undefined> {
263
+ const reservations = live_reservations(context.directory)
264
+ const budget = await current_budget(context, reservations)
265
+
266
+ if (core_admission.is_admitted(context.key, reservations, budget)) return admit(context)
267
+
268
+ if (context.now() >= context.deadline) {
269
+ return admit(context, overflow_of(context, reservations, budget))
270
+ }
271
+
272
+ return undefined
273
+ }
274
+
244
275
  // Poll the ledger until this reservation is admitted, or until the wait cap admits it at minimum width.
245
276
  // A solo run is admitted on the first read — its own claim is the ledger's head — so the loop body never
246
277
  // runs and the wait costs nothing.
247
- async function await_admission(context: WaitContext): Promise<void> {
248
- while (!is_admitted(context.key, live_reservations(context.directory), context.budget)) {
249
- if (context.now() >= context.deadline) return
278
+ async function await_admission(context: WaitContext): Promise<Admission> {
279
+ let admission = await poll_admission(context)
250
280
 
281
+ while (admission === undefined) {
251
282
  // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
252
283
  await context.sleep(context.poll_interval_ms)
284
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
285
+ admission = await poll_admission(context)
253
286
  }
287
+
288
+ return admission
254
289
  }
255
290
 
256
291
  async function reserve(weight: number, options: ReserveOptions = {}): Promise<Handle> {
257
292
  const timing = resolve_timing(options)
258
293
  const directory = options.directory ?? PLATFORM_TEMP_ROOT
259
- const budget = normalize_budget(options.budget ?? availableParallelism())
260
294
  const claimed_at = timing.now()
261
295
  const name = marker_name(randomUUID())
262
296
  const target = path.join(directory, name)
297
+ const fields = { weight, claimed_at, memory_mb: options.memory_mb }
263
298
 
264
- write_reservation(target, weight, claimed_at)
265
- await await_admission({
299
+ write_reservation(target, fields)
300
+ const admission = await await_admission({
266
301
  ...timing,
267
302
  key: name,
303
+ target,
268
304
  directory,
269
- budget,
270
- deadline: claimed_at + (options.wait_cap_ms ?? WAIT_CAP_MS),
305
+ budget: normalize_budget(options.budget ?? availableParallelism()),
306
+ deadline: claimed_at + timing.wait_cap_ms,
307
+ fields,
308
+ read_machine: options.read_machine ?? machine_capacity.read_machine,
271
309
  })
272
310
 
273
- return { target }
311
+ return { target, admission }
274
312
  }
275
313
 
276
314
  function release(handle: Handle): void {
@@ -278,16 +316,17 @@ function release(handle: Handle): void {
278
316
  }
279
317
 
280
318
  // The whole reservation lifetime around a step: claim a place, wait for admission, run, and free the
281
- // place on any exit. `finally`, so a step that threw still releases its cores.
319
+ // 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.
282
321
  async function with_core_reservation<T>(
283
322
  weight: number,
284
- run: () => Promise<T>,
323
+ run: (admission: Admission) => Promise<T>,
285
324
  options: ReserveOptions = {},
286
325
  ): Promise<T> {
287
326
  const handle = await reserve(weight, options)
288
327
 
289
328
  try {
290
- return await run()
329
+ return await run(handle.admission)
291
330
  } finally {
292
331
  release(handle)
293
332
  }
@@ -319,7 +358,7 @@ async function with_held_mark<T>(run: () => Promise<T>): Promise<T> {
319
358
  }
320
359
 
321
360
  // **A command's reservation: the gate's claim, unless a parent already holds the cores**
322
- // (joshuafolkken/kit#3345). `josh-logic.ts` calls this around every command that declares a weight.
361
+ // `josh-logic.ts` calls this around every command that declares a weight.
323
362
  // Each command then only declares its weight, and no command carries a copy of the claim, run and
324
363
  // release steps. A solo run is admitted on the first read, so a run with room on the machine starts
325
364
  // with no wait. A command inside a unit suite claims nothing either, for the reason `reserved-run.ts`
@@ -338,9 +377,11 @@ const core_budget = {
338
377
  CORE_WEIGHTS,
339
378
  HELD_KEY,
340
379
  HELD_VALUE,
380
+ MEMORY_MB,
341
381
  RESERVED_PREFIX,
342
- admitted_keys,
343
- admitted_load,
382
+ admitted_keys: core_admission.admitted_keys,
383
+ admitted_load: core_admission.admitted_load,
384
+ describe_overflow: core_admission.describe_overflow,
344
385
  is_held,
345
386
  live_reservations,
346
387
  release,
@@ -352,3 +393,5 @@ const core_budget = {
352
393
 
353
394
  export type { LiveReservation, Reservation, ReserveOptions }
354
395
  export { core_budget }
396
+
397
+ export { type Admission } from './core-admission'
@@ -0,0 +1,114 @@
1
+ import { process_identity } from '#scripts/josh/process-identity'
2
+ import { lane_ledger } from '#scripts/lane/lane-ledger'
3
+ import { core_admission } from './core-admission'
4
+ import { core_budget } from './core-budget'
5
+ import { gate_plan } from './gate-plan'
6
+ import type { GateStepResult } from './gate-report'
7
+ import { machine_capacity } from './machine-capacity'
8
+
9
+ // A finished gate's line in the lane ledger: its duration, its verdict, its
10
+ // unit suite's duration, and the load it ran beside, so `josh metrics`
11
+ // compares only gates the machine was quiet for. Another gate's span is not the only load: another
12
+ // lane's lint, related tests or `ship` doubled a solo gate's duration within minutes.
13
+ //
14
+ // **The machine is read where none of the gate's own checks runs — before the first starts and after
15
+ // the last ends.** The load average cannot tell the two apart: a solo gate started at 4 on the 11-core
16
+ // machine ended at 21, its own load. The reading is the core budget's own, so "quiet" means what
17
+ // admission means by it: no whole core busy beyond the baseline the gate's weights were measured beside.
18
+ //
19
+ // **Between the ends, the load is read off the core budget's ledger, not the CPU**.
20
+ // Two readings missed every lane whose lint, tests or `ship` ran only while
21
+ // the gate did: seven lanes moved the solo median from 50.5s to 60.9s with no commit between. The CPU
22
+ // mid-gate holds this gate's own checks, whose declared weights are not what they burn, so the ledger
23
+ // is what tells the two apart: another `josh` run's admitted claim is another process's place, and its
24
+ // weight is the cores it holds. A claim still waiting holds none.
25
+
26
+ const NO_LEDGER_CORES = 0
27
+ // Often enough to catch another lane's shortest related lint, seldom enough that reading the markers —
28
+ // a process probe each — costs the gate nothing it could measure.
29
+ const SAMPLE_INTERVAL_MS = 3000
30
+
31
+ // Where the line goes, the external load read so far — before the first check started, then every
32
+ // sample since — and the timer taking the samples. No readings and no timer when no ledger was
33
+ // resolved: a suite driving the gate reads the machine for nothing.
34
+ interface GateLedgerStart {
35
+ ledger_path: string | undefined
36
+ readings: Array<number | undefined>
37
+ sampler: ReturnType<typeof setInterval> | undefined
38
+ }
39
+
40
+ interface GateOutcome {
41
+ elapsed_ms: number
42
+ is_passed: boolean
43
+ }
44
+
45
+ // `undefined` where the machine could not be read — a CI runner, a CPU quota narrower than the host.
46
+ async function read_external_cores(): Promise<number | undefined> {
47
+ const { busy_cores } = await machine_capacity.read_machine()
48
+
49
+ if (busy_cores === undefined) return undefined
50
+
51
+ return machine_capacity.external_cores(busy_cores, NO_LEDGER_CORES)
52
+ }
53
+
54
+ // The cores other processes' admitted claims hold now. This gate's own claims are written by this
55
+ // process, and its checks' dispatches claim nothing under its held mark.
56
+ function read_foreign_cores(): number {
57
+ const foreign = core_budget
58
+ .live_reservations()
59
+ .filter(
60
+ ({ reservation }) =>
61
+ !process_identity.is_own_process(reservation.pid, reservation.process_start),
62
+ )
63
+
64
+ return core_admission.ledger_load(foreign, Date.now()).cores
65
+ }
66
+
67
+ // The highest reading; one unread reading leaves the whole gate unread rather than half-quiet.
68
+ function peak(readings: ReadonlyArray<number | undefined>): number | undefined {
69
+ const read = readings.filter((reading) => reading !== undefined)
70
+
71
+ if (read.length < readings.length) return undefined
72
+
73
+ return Math.max(...read)
74
+ }
75
+
76
+ // Unreferenced, so a gate that throws before `record` never holds the process open on the timer.
77
+ function start_sampler(readings: Array<number | undefined>): ReturnType<typeof setInterval> {
78
+ return setInterval(() => {
79
+ readings.push(read_foreign_cores())
80
+ }, SAMPLE_INTERVAL_MS).unref()
81
+ }
82
+
83
+ async function start(ledger_path: string | undefined): Promise<GateLedgerStart> {
84
+ if (ledger_path === undefined) return { ledger_path, readings: [], sampler: undefined }
85
+
86
+ const readings = [await read_external_cores()]
87
+
88
+ return { ledger_path, readings, sampler: start_sampler(readings) }
89
+ }
90
+
91
+ // The caller measures the elapsed time before this, so the end's reading is never part of it.
92
+ async function record(
93
+ begun: GateLedgerStart,
94
+ results: ReadonlyArray<GateStepResult>,
95
+ outcome: GateOutcome,
96
+ ): Promise<void> {
97
+ clearInterval(begun.sampler)
98
+
99
+ if (begun.ledger_path === undefined) return
100
+
101
+ const unit_ms = results.find((result) => result.label === gate_plan.UNIT_LABEL)?.elapsed_ms
102
+ const external_cores = peak([...begun.readings, await read_external_cores()])
103
+
104
+ await lane_ledger.record_gate(begun.ledger_path, { ...outcome, unit_ms, external_cores })
105
+ }
106
+
107
+ const gate_ledger = {
108
+ SAMPLE_INTERVAL_MS,
109
+ record,
110
+ start,
111
+ }
112
+
113
+ export type { GateLedgerStart }
114
+ export { gate_ledger }