@joshuafolkken/kit 1.1514.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -1,5 +1,5 @@
1
1
  import { readFile } from 'node:fs/promises'
2
- import { availableParallelism, cpus, totalmem } from 'node:os'
2
+ import { availableParallelism, cpus, loadavg, totalmem } from 'node:os'
3
3
  import { PROBE_TIMEOUT_MS } from '#scripts/lib/timeouts'
4
4
  import { execa } from 'execa'
5
5
 
@@ -32,12 +32,12 @@ import { execa } from 'execa'
32
32
  // The window the busy cores are measured over: long enough that one scheduler tick does not dominate it,
33
33
  // short enough that a solo admission is not visibly delayed.
34
34
  const SAMPLE_WINDOW_MS = 250
35
- // **The background a developer machine always carries, which the gate's weights were measured beside.**
36
- // On 2026-10-07 the 11-core machine idled at about 1.5 cores outside `josh` — Claude sessions 0.55, the
37
- // window server 0.47, a browser 0.5. The solo gate's weights sum to exactly the core count and were
38
- // measured with that load present, so only what exceeds it is load the budget must give way to;
39
- // counting the baseline would defer a solo gate's unit suite on every run.
40
- const BASELINE_CORES = 2
35
+ // **Run-queue load outside the ledger past this many times the cores holds the first waiter too**
36
+ // (joshuafolkken/kit#4361). The first waiter ignores outside load (joshuafolkken/kit#4313), and lanes took
37
+ // the 11-core machine to a load average of 25–34. Twice the cores is loose on purpose: the one-core
38
+ // editor load #4313 stopped holding a solo gate stays far below it, so neither its starvation nor the
39
+ // lanes' speed comes back, while a machine whose queue beyond the ledger passes two per core waits.
40
+ const OVERLOAD_FACTOR = 2
41
41
  const BYTES_PER_MB = 1_048_576
42
42
  const KB_PER_MB = 1024
43
43
  const PERCENT = 100
@@ -62,7 +62,10 @@ const PAGE_SIZE_NAME = 'hw.pagesize'
62
62
  // The kernel's memory-pressure verdict — 1 normal, 2 warning, 4 critical — the one Activity Monitor
63
63
  // colors its "memory pressure" graph by.
64
64
  const PRESSURE_NAME = 'kern.memorystatus_vm_pressure_level'
65
- const PRESSURE_WARNING = 2
65
+ // **Only critical holds; warning is sticky** (joshuafolkken/kit#4199). On macOS the verdict can stay at
66
+ // warning for hours after the pressure passed, so a hold on warning never lifts. What is pressured right
67
+ // now shows in the free figure and the swap and compressor traffic; the verdict adds only critical.
68
+ const PRESSURE_HOLD = 4
66
69
  // The swap traffic across one window that reads as pressure — 64 MB a second paged to disk. A machine
67
70
  // that swapped once still pages a few megabytes back in as old pages are touched.
68
71
  const SWAP_PRESSURE_MB = 16
@@ -81,10 +84,13 @@ const SYSCTL_ARGUMENTS = [
81
84
  const SYSCTL_LINE = /^(?<name>[\w.]+): (?<value>\d+)$/gmu
82
85
 
83
86
  // `memory_pressured` says why `available_mb` read none, so a claim that waits can name the pressure.
87
+ // `run_queue` is the one-minute load average: the busy cores stop at the core count, so only the queue
88
+ // tells a machine at twice its cores from one at once (`is_overloaded`).
84
89
  interface MachineReading {
85
90
  busy_cores: number | undefined
86
91
  available_mb: number | undefined
87
92
  memory_pressured?: boolean | undefined
93
+ run_queue?: number | undefined
88
94
  }
89
95
 
90
96
  // The memory half of a reading. `swapped_mb` is a counter — every page swapped in or out since boot —
@@ -103,10 +109,15 @@ interface LedgerLoad {
103
109
  memory_mb: number
104
110
  }
105
111
 
112
+ // `busy_excess` is the measured cores beyond what the ledger declares — what `cores` gave up to load the
113
+ // ledger does not hold, so a claim that waits on it can name the CPU as saturated. `is_overloaded` lifts
114
+ // the first waiter's exemption from that load (`core_admission.is_admitted`).
106
115
  interface MachineBudget {
107
116
  cores: number
108
117
  memory_mb: number
109
118
  memory_pressured?: boolean | undefined
119
+ busy_excess?: number | undefined
120
+ is_overloaded?: boolean | undefined
110
121
  }
111
122
 
112
123
  interface CpuTimes {
@@ -287,22 +298,23 @@ function moved_over(from: number | undefined, to: number | undefined, limit: num
287
298
 
288
299
  function is_pressured(before: MemoryReading, after: MemoryReading): boolean {
289
300
  return (
290
- (after.pressure_level ?? 0) >= PRESSURE_WARNING ||
301
+ (after.pressure_level ?? 0) >= PRESSURE_HOLD ||
291
302
  moved_over(before.swapped_mb, after.swapped_mb, SWAP_PRESSURE_MB) ||
292
303
  moved_over(before.compressed_mb, after.compressed_mb, COMPRESSION_PRESSURE_MB)
293
304
  )
294
305
  }
295
306
 
296
- // **Memory under compression and swap pressure has nothing free to admit against.** The level counts
297
- // compressible pages as available, so on 2026-10-16 it read 5.4 GB free while the compressor held
298
- // 5.9 GB and compressed and decompressed about 3.3 GB every three seconds, and 5.2 GB of reservations
299
- // were admitted on top. A reading the kernel calls pressured, or one with swap or compressor traffic
300
- // across the window, answers no free memory: what the ledger holds keeps running and a heavy claim waits
301
- // for the pressure to pass.
302
- function pressured_available(before: MemoryReading, after: MemoryReading): number | undefined {
307
+ // **Only a reading the kernel calls critical has nothing free to admit against.** Swap and compressor
308
+ // traffic across the window used to answer no free memory too (joshuafolkken/kit#3943), but this machine
309
+ // swaps out 0.4–1.3 TB a day as a matter of course, so that traffic held about a third of every wait
310
+ // with memory to spare (joshuafolkken/kit#4313). A claim now waits on memory only when the free figure
311
+ // falls short of what it declares; the traffic still names the wait as pressure (`memory_pressured`),
312
+ // and holds a claim past the shortfall that running alone or the wait cap would otherwise start
313
+ // (`core_admission.is_swap_held`, joshuafolkken/kit#4451).
314
+ function pressured_available(after: MemoryReading): number | undefined {
303
315
  if (after.available_mb === undefined) return undefined
304
316
 
305
- return is_pressured(before, after) ? 0 : after.available_mb
317
+ return (after.pressure_level ?? 0) >= PRESSURE_HOLD ? 0 : after.available_mb
306
318
  }
307
319
 
308
320
  // Memory is read at both ends of the window, so the swap counter's difference is the activity during it.
@@ -312,13 +324,13 @@ async function read_machine(
312
324
  const before = cpu_times()
313
325
  const [memory_before] = await Promise.all([read_memory(), sleep(SAMPLE_WINDOW_MS)])
314
326
  const memory_after = await read_memory()
315
- const busy_cores = is_unquoted()
316
- ? busy_cores_between(before, cpu_times(), cpus().length)
317
- : undefined
327
+ const is_host = is_unquoted()
328
+ const busy_cores = is_host ? busy_cores_between(before, cpu_times(), cpus().length) : undefined
318
329
 
319
330
  return {
320
331
  busy_cores,
321
- available_mb: pressured_available(memory_before, memory_after),
332
+ run_queue: is_host ? loadavg()[0] : undefined,
333
+ available_mb: pressured_available(memory_after),
322
334
  memory_pressured: is_pressured(memory_before, memory_after),
323
335
  }
324
336
  }
@@ -327,31 +339,52 @@ async function read_sample(): Promise<MachineSample> {
327
339
  return { cpu: cpu_times(), memory: await read_memory(), total_mb: totalmem() / BYTES_PER_MB }
328
340
  }
329
341
 
330
- // The busy cores the ledger does not account for, beyond the baseline the weights were measured beside,
331
- // in whole cores — the budget is in whole cores, and a fraction of a core is not a core to give up.
342
+ // The busy cores the ledger does not account for, in whole cores — the budget is in whole cores, and a
343
+ // fraction of a core is not a core to give up.
344
+ //
345
+ // **Every busy core counts, the background included** (joshuafolkken/kit#4238). A baseline of two cores
346
+ // used to be exempt, so with 10 cores reserved and all 11 busy the reading saw no excess and admitted
347
+ // another claim onto a saturated CPU.
332
348
  function external_cores(busy_cores: number | undefined, ledger_cores: number): number {
333
349
  if (busy_cores === undefined) return 0
334
350
 
335
- return Math.floor(Math.max(0, busy_cores - ledger_cores - BASELINE_CORES))
351
+ return Math.floor(Math.max(0, busy_cores - ledger_cores))
336
352
  }
337
353
 
338
- // **The budget the ledger admits against: what is free plus what the ledger itself already holds.**
339
- // The admitted reservations' load is inside the reading, and the admission walk counts their declared
340
- // weight again, so it is added back — what is subtracted is only the load from outside the ledger. The
341
- // caller passes every admitted claim's cores but only the memory of claims past
342
- // `core_admission.RAMP_UP_MS`, whose tools have had time to allocate.
354
+ // The run queue beyond what the ledger declares, past `OVERLOAD_FACTOR` times the cores. The ledger's own
355
+ // claims running past their weight count as outside load. The load average trails by a minute, so a
356
+ // first waiter held here waits out the decay — only at a load already this far past the machine. A queue
357
+ // that could not be read, and Windows' constant zero, never hold.
358
+ function is_overloaded(
359
+ run_queue: number | undefined,
360
+ ledger_cores: number,
361
+ cores: number,
362
+ ): boolean {
363
+ if (run_queue === undefined) return false
364
+
365
+ return run_queue - ledger_cores > cores * OVERLOAD_FACTOR
366
+ }
367
+
368
+ // **The budget the ledger admits against: `cores − max(ledger, busy)` free, plus what the ledger itself
369
+ // already holds.** The admission walk counts the ledger's declared weight again, so it is added back —
370
+ // what is subtracted is only the busy load beyond it. A claim admitted moments ago is not busy yet, and
371
+ // the ledger's declared cores cover it. The caller passes every admitted claim's cores but only the
372
+ // memory of claims past `core_admission.RAMP_UP_MS`, whose tools have had time to allocate.
343
373
  // Memory that could not be read is no limit at all, the behavior before memory was read.
344
374
  function machine_budget(cores: number, reading: MachineReading, ledger: LedgerLoad): MachineBudget {
375
+ const busy_excess = external_cores(reading.busy_cores, ledger.cores)
376
+
345
377
  return {
346
- cores: cores - external_cores(reading.busy_cores, ledger.cores),
378
+ cores: Math.max(0, cores - busy_excess),
347
379
  memory_mb:
348
380
  reading.available_mb === undefined ? Infinity : reading.available_mb + ledger.memory_mb,
349
381
  memory_pressured: reading.memory_pressured,
382
+ busy_excess,
383
+ is_overloaded: is_overloaded(reading.run_queue, ledger.cores, cores),
350
384
  }
351
385
  }
352
386
 
353
387
  const machine_capacity = {
354
- BASELINE_CORES,
355
388
  busy_cores_between,
356
389
  busy_share_between,
357
390
  COMPRESSION_PRESSURE_MB,
@@ -360,6 +393,7 @@ const machine_capacity = {
360
393
  parse_darwin_memory,
361
394
  parse_linux_available,
362
395
  parse_linux_swapped,
396
+ PRESSURE_HOLD,
363
397
  pressured_available,
364
398
  read_machine,
365
399
  read_memory,
@@ -0,0 +1,67 @@
1
+ import { git_spawn } from '#scripts/git/git-spawn'
2
+ import { file_map_stamp, type FileMapStamp } from '#scripts/josh/file-map-stamp'
3
+ import type { GateTree } from './gate-tree'
4
+
5
+ // Every path whose content can differ from the tree a green record was taken on — the one reading the
6
+ // gate's per-check reuse (`check-reuse.ts`) and the scoped checks' since-green narrowing
7
+ // (`since-green.ts`) both act on, so the two can never disagree about what moved.
8
+ //
9
+ // **What moved is the union of two diffs**. The changed-file map is a diff against the merge base, so a
10
+ // path absent from both maps holds the merge base's content — and the base's own diff
11
+ // (`git diff <recorded> <current>`) names every path that content moved for, which is what a main sync
12
+ // brought in. A path in either map whose digest differs is the other half
13
+ // (`file_map_stamp.changed_since`).
14
+
15
+ const NAME_SEPARATOR = '\0'
16
+ const BASE_DIFF = ['diff', '--name-only', '--no-renames', '-z'] as const
17
+
18
+ async function base_diff(from: string, to: string): Promise<ReadonlyArray<string> | undefined> {
19
+ if (from === to) return []
20
+
21
+ try {
22
+ const names = await git_spawn.read([...BASE_DIFF, from, to])
23
+
24
+ return names.split(NAME_SEPARATOR).filter((name) => name !== '')
25
+ } catch {
26
+ return undefined
27
+ }
28
+ }
29
+
30
+ // The two diffs apart: `synced` is what a main sync brought in, `changed` the paths whose digest moved.
31
+ // A path can be in both.
32
+ interface MovedParts {
33
+ changed: ReadonlyArray<string>
34
+ synced: ReadonlyArray<string>
35
+ }
36
+
37
+ // `undefined` when the record cannot be compared: no base on either side, or a tree map that came back
38
+ // empty — also what `gate-tree.ts` answers when git could not be read, so it describes no tree.
39
+ async function moved_parts(stamp: FileMapStamp, tree: GateTree): Promise<MovedParts | undefined> {
40
+ const is_unread = Object.keys(tree.files).length === 0
41
+
42
+ if (is_unread || stamp.base === undefined || tree.base === undefined) return undefined
43
+
44
+ const synced = await base_diff(stamp.base, tree.base)
45
+
46
+ if (synced === undefined) return undefined
47
+
48
+ return { changed: file_map_stamp.changed_since(stamp, tree.files), synced }
49
+ }
50
+
51
+ function union_of(parts: MovedParts): ReadonlyArray<string> {
52
+ return [...new Set([...parts.changed, ...parts.synced])]
53
+ }
54
+
55
+ async function moved_since(
56
+ stamp: FileMapStamp,
57
+ tree: GateTree,
58
+ ): Promise<ReadonlyArray<string> | undefined> {
59
+ const parts = await moved_parts(stamp, tree)
60
+
61
+ return parts === undefined ? undefined : union_of(parts)
62
+ }
63
+
64
+ const moved_paths = { moved_parts, moved_since, union_of }
65
+
66
+ export type { MovedParts }
67
+ export { moved_paths }
@@ -1,4 +1,4 @@
1
- import { existsSync, globSync, readFileSync } from 'node:fs'
1
+ import { existsSync, globSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { find_local_bin_upwards } from '#scripts/build/local-bin'
4
4
  import { doctor_consumer } from '#scripts/doctor/doctor-consumer'
@@ -6,10 +6,10 @@ import { own_formatter } from '#scripts/init/own-formatter'
6
6
  import { project_profile } from '#scripts/init/project-profile'
7
7
  import { ancestor_directories } from '#scripts/lib/ancestor-directories'
8
8
  import { json_value } from '#scripts/lib/json-value'
9
+ import { package_manifest } from '#scripts/lib/package-manifest'
9
10
  import { NOT_USED_MARKER, SKIP_MARKER } from '#scripts/test/skip-marker'
10
11
  import { z } from 'zod'
11
12
 
12
- const PACKAGE_JSON = 'package.json'
13
13
  const IGNORED_DIRS = new Set([
14
14
  'node_modules',
15
15
  '.git',
@@ -48,7 +48,7 @@ const object_schema = z.record(z.string(), z.unknown())
48
48
  function project_root(directory: string): string {
49
49
  return (
50
50
  ancestor_directories.nearest(directory, (candidate) =>
51
- existsSync(path.join(candidate, PACKAGE_JSON)),
51
+ existsSync(package_manifest.manifest_path(candidate)),
52
52
  ) ?? directory
53
53
  )
54
54
  }
@@ -86,16 +86,9 @@ function is_basic_manifest(manifest: unknown): boolean {
86
86
  return project_profile.parse_profile(josh['profile']) === 'basic'
87
87
  }
88
88
 
89
- // The try covers the read alone — a missing or unreadable manifest — since the parse already answers
90
- // `undefined` for text that is not JSON.
89
+ // A missing, unreadable or non-JSON manifest answers `undefined`; the shape is each caller's question.
91
90
  function read_manifest(directory: string): unknown {
92
- try {
93
- const manifest_path = path.join(project_root(directory), PACKAGE_JSON)
94
-
95
- return json_value.parse_or_undefined(readFileSync(manifest_path, 'utf8'))
96
- } catch {
97
- return undefined
98
- }
91
+ return package_manifest.read_manifest_if_valid(project_root(directory), z.unknown())
99
92
  }
100
93
 
101
94
  function is_basic(directory: string): boolean {
@@ -12,14 +12,14 @@ import { gate_tree, type GateTree } from './gate-tree'
12
12
  // tree neither check has read return their findings one round trip at a time; one call running both
13
13
  // checks first returns most of them at once.
14
14
  //
15
- // **It fixes when the checks run, never whether they run, and never what they check.** Nothing here
16
- // skips a check, narrows one, or reinterprets its output — a green record buys ordering and nothing
17
- // else, and `josh gate` still runs its four checks exactly as before. It never *reuses* a scoped
18
- // check's result in place of re-running it.
15
+ // **It fixes when the checks run, never whether they run.** Nothing here skips a check or
16
+ // reinterprets its output, and `josh gate` still runs its four checks exactly as before. The one other
17
+ // reader is the checks' own re-run, which narrows to what moved since this record (`since-green.ts`).
19
18
  //
20
19
  // **The judgement is the gate's own, not a second one.** "There is a record and nothing it covers has
21
20
  // moved" is `review_brief.matching_stamp` plus the base equality `gate_skip.reusable_green_gate`
22
- // already compares, over the same `FileMapStamp` shape written to the same kind of file. A second
21
+ // already compares and the inputs fingerprint each record carries (`verification-inputs.ts`), over the
22
+ // same `FileMapStamp` shape written to the same kind of file. A second
23
23
  // definition of "this tree is unchanged" is the clone `CLAUDE.md` prohibits, and it is exactly where
24
24
  // two commands would start disagreeing about one working tree.
25
25
  //
@@ -95,7 +95,11 @@ function checks_of(sources: ScopedSources): ReadonlyArray<ScopedCheck> {
95
95
  function describes_tree(check: ScopedCheck, tree: Record<string, string>, base: string): boolean {
96
96
  const stamp = review_brief.matching_stamp(check.stamp.read(check.source), tree)
97
97
 
98
- return stamp !== undefined && file_map_stamp.describes_base(stamp, base)
98
+ return (
99
+ stamp !== undefined &&
100
+ file_map_stamp.describes_base(stamp, base) &&
101
+ check.stamp.describes_inputs(stamp)
102
+ )
99
103
  }
100
104
 
101
105
  // **Whether there is a tree to speak about at all**, asked once and used from both ends: the reader
@@ -161,8 +165,8 @@ function refusal(missing: ReadonlyArray<string>): string {
161
165
  '282 seconds, 31% of the run, picking up one lint rule and one failing test at a time after its ' +
162
166
  'review had already started. Run them in one call — ' +
163
167
  `\`${LINT_COMMAND} && ${TEST_COMMAND}\`, measured at 13.8 seconds — and reissue this command. ` +
164
- 'The record fixes when the checks run and never whether they run: nothing is skipped, narrowed ' +
165
- 'or reused because of it. `prompts/review.md` → "The scoped checks answer on the last edit".'
168
+ 'The record fixes when the checks run and never whether they run: nothing is skipped or reused ' +
169
+ 'because of it. `prompts/review.md` → "The scoped checks answer on the last edit".'
166
170
  )
167
171
  }
168
172
 
@@ -0,0 +1,62 @@
1
+ import type { FileMapStampAccess } from '#scripts/josh/file-map-stamp'
2
+ import { gate_tree } from './gate-tree'
3
+ import { moved_paths, type MovedParts } from './moved-paths'
4
+ import { verification_inputs } from './verification-inputs'
5
+
6
+ // **A scoped check re-run reads only what moved since its last green run on this checkout**
7
+ // (joshuafolkken/kit#4393). A lane's ship retry — after a review fix or a preflight stop — re-ran
8
+ // `josh lint:related` and `josh test:related` (the gate's unit step too) over the whole branch diff,
9
+ // though everything outside the fix had been green on the tree before it.
10
+ //
11
+ // **The check is no weaker.** The green record (`scoped-green.ts`) vouches that the check passed over
12
+ // the branch diff of the tree it names; what moved since is every path whose content can differ from
13
+ // that tree (`moved-paths.ts`), a main sync's own changes included. A record written by a narrowed run
14
+ // vouches for the same thing, by the same argument one run earlier.
15
+ //
16
+ // **Whatever cannot be narrowed answers `undefined`**, and the caller reads the whole branch change as
17
+ // before: no record, one that cannot be compared, one written under other tools or environment, or a
18
+ // moved file the check's declaration names a configuration — a file green under the old configuration
19
+ // says nothing under the new one. An empty list is
20
+ // the positive fact that nothing moved: the gate's unit step on the tree the preflight just passed.
21
+
22
+ // The narrowing line each command prints before it runs, so a since-green run is never read as one
23
+ // over the whole branch.
24
+ function describe(label: string, moved: ReadonlyArray<string>): string {
25
+ return `${label}: reading only the ${String(moved.length)} file(s) changed since its last green run on this checkout.`
26
+ }
27
+
28
+ function is_narrowable(label: string, parts: MovedParts | undefined): parts is MovedParts {
29
+ return parts !== undefined && !verification_inputs.configures(label, moved_paths.union_of(parts))
30
+ }
31
+
32
+ // What moved with a main sync's part kept apart, for a caller that records how much of its input the
33
+ // sync brought in (`josh test:related`, joshuafolkken/kit#4465). `label` names the gate check whose
34
+ // declaration (`verification-inputs.ts`) the record vouches for.
35
+ async function read_moved_parts(
36
+ stamp: FileMapStampAccess,
37
+ label: string,
38
+ source?: string,
39
+ ): Promise<MovedParts | undefined> {
40
+ const record = stamp.read(source)
41
+
42
+ if (record === undefined || !stamp.describes_inputs(record)) return undefined
43
+
44
+ const parts = await moved_paths.moved_parts(record, await gate_tree.read_gate_tree())
45
+
46
+ return is_narrowable(label, parts) ? parts : undefined
47
+ }
48
+
49
+ // Repository-root-relative paths, or `undefined` when the caller has to read the whole branch change.
50
+ async function read_moved(
51
+ stamp: FileMapStampAccess,
52
+ label: string,
53
+ source?: string,
54
+ ): Promise<ReadonlyArray<string> | undefined> {
55
+ const parts = await read_moved_parts(stamp, label, source)
56
+
57
+ return parts === undefined ? undefined : moved_paths.union_of(parts)
58
+ }
59
+
60
+ const since_green = { describe, read_moved, read_moved_parts }
61
+
62
+ export { since_green }
@@ -0,0 +1,115 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { existsSync, readdirSync, readFileSync } from 'node:fs'
3
+ import path from 'node:path'
4
+
5
+ // **The toolchain's inputs, listed once** (joshuafolkken/kit#4496): the files whose content moves what
6
+ // a tool answers while every source stays byte-identical — the installed packages, the eslint config
7
+ // and the TypeScript program's options. Every result kept across runs is discarded when they move:
8
+ // the metrics base cache (`metrics-base-cache.ts`), the hook bundles (`hook-bundle-stamp.ts`), the
9
+ // warm ESLint daemon (`eslint-daemon.ts`) and the gate's verdicts (`verification-inputs.ts`). A file
10
+ // added here reaches all of them.
11
+ //
12
+ // Loaded by plain `node` on every hook launch (`tools/hooks/hook-bundle-ready.ts`), so this module
13
+ // imports `node:` built-ins alone.
14
+
15
+ // The package manager's manifest, lock and settings files, and the record pnpm rewrites on every
16
+ // install — a consumer's eslint config imports its rules from installed packages.
17
+ const PACKAGE_FILES: ReadonlyArray<string> = [
18
+ 'package.json',
19
+ 'pnpm-lock.yaml',
20
+ 'pnpm-workspace.yaml',
21
+ 'package-lock.json',
22
+ 'yarn.lock',
23
+ 'bun.lock',
24
+ 'bun.lockb',
25
+ '.npmrc',
26
+ 'node_modules/.modules.yaml',
27
+ ]
28
+ // The root entries of the eslint flat config and of the TypeScript program, and the directories of
29
+ // the rule modules and the shared compiler options they import.
30
+ const CONFIG_ENTRIES: ReadonlyArray<RegExp> = [
31
+ /^eslint\.config\.[cm]?[jt]s$/u,
32
+ /^tsconfig(?:\.[\w-]+)?\.json$/u,
33
+ ]
34
+ const CONFIG_DIRECTORIES: ReadonlySet<string> = new Set(['eslint', 'tsconfig'])
35
+ // A test beside the rule modules configures nothing.
36
+ const TEST_MARKER = '.test.'
37
+ const SEPARATOR = '/'
38
+ const DIGEST_ALGORITHM = 'sha256'
39
+
40
+ // Code-unit order, so the digest does not depend on the locale of the machine that computes it.
41
+ function by_code_unit(left: string, right: string): number {
42
+ if (left === right) return 0
43
+
44
+ return left < right ? -1 : 1
45
+ }
46
+
47
+ function to_posix(relative: string): string {
48
+ return relative.split(path.sep).join(SEPARATOR)
49
+ }
50
+
51
+ function is_config_entry(name: string): boolean {
52
+ return CONFIG_ENTRIES.some((entry) => entry.test(name))
53
+ }
54
+
55
+ function is_config_module(relative: string): boolean {
56
+ const [top = ''] = relative.split(SEPARATOR, 1)
57
+
58
+ return CONFIG_DIRECTORIES.has(top) && !path.basename(relative).includes(TEST_MARKER)
59
+ }
60
+
61
+ // Whether the root-relative `relative` is a toolchain input.
62
+ function is_input(relative: string): boolean {
63
+ const posix = to_posix(relative)
64
+ if (PACKAGE_FILES.includes(posix)) return true
65
+
66
+ return is_config_entry(posix) || is_config_module(posix)
67
+ }
68
+
69
+ // Files only: a directory moves on every entry created in it, an editor's temp file too.
70
+ function modules_under(root: string, directory: string): ReadonlyArray<string> {
71
+ const absolute = path.join(root, directory)
72
+ if (!existsSync(absolute)) return []
73
+
74
+ return readdirSync(absolute, { recursive: true, withFileTypes: true })
75
+ .filter((entry) => entry.isFile())
76
+ .map((entry) => to_posix(path.relative(root, path.join(entry.parentPath, entry.name))))
77
+ .filter((relative) => is_config_module(relative))
78
+ }
79
+
80
+ // The root-relative toolchain inputs present under `root`, in code-unit order.
81
+ function paths(root: string): ReadonlyArray<string> {
82
+ const present = PACKAGE_FILES.filter((relative) => existsSync(path.join(root, relative)))
83
+ const entries = readdirSync(root).filter((name) => is_config_entry(name))
84
+ const modules = [...CONFIG_DIRECTORIES].flatMap((directory) => modules_under(root, directory))
85
+
86
+ return [...present, ...entries, ...modules].toSorted(by_code_unit)
87
+ }
88
+
89
+ function read_or_empty(file: string): Uint8Array {
90
+ try {
91
+ return readFileSync(file)
92
+ } catch {
93
+ return new Uint8Array()
94
+ }
95
+ }
96
+
97
+ // **The fingerprint of the toolchain under `root`**: each input's path and content, in code-unit
98
+ // order, so an added, removed, renamed or edited input changes it. A file gone between the listing
99
+ // and its read hashes as empty.
100
+ function digest(root: string): string {
101
+ const hash = createHash(DIGEST_ALGORITHM)
102
+
103
+ for (const relative of paths(root)) {
104
+ hash
105
+ .update(`${relative}\0`)
106
+ .update(read_or_empty(path.join(root, relative)))
107
+ .update('\0')
108
+ }
109
+
110
+ return hash.digest('hex')
111
+ }
112
+
113
+ const toolchain_inputs = { digest, is_input, PACKAGE_FILES, paths }
114
+
115
+ export { toolchain_inputs }
@@ -9,7 +9,6 @@ import { review_stamps } from '#scripts/review/review-stamps'
9
9
  import { review_tree } from '#scripts/review/review-tree'
10
10
  import { unit_worker_share } from '#scripts/test/unit-worker-share'
11
11
  import { check_reuse, type CheckRecords } from './check-reuse'
12
- import { free_cores } from './free-cores'
13
12
  import { gate_ledger, type GateLedgerStart } from './gate-ledger'
14
13
  import { gate_plan, type GatePlan } from './gate-plan'
15
14
  import { gate_report, type GateStepResult } from './gate-report'
@@ -165,21 +164,19 @@ async function run_marked_gate<T>(
165
164
  // The concurrent-run count is read here rather than inside `gate-plan.ts` for the reason the core
166
165
  // count already is: that module stays a pure function of its inputs, and the machine is asked once and
167
166
  // handed to both calls. Counted *before* the unit step writes its own marker, so `+ 1` is this gate.
168
- // `free` bounds the unit cap the run count produced (`gate_plan.bound_by_free`).
169
- function announce_gate_plan(
170
- is_unit_included: boolean,
171
- available_cores: number,
172
- free: number | undefined,
173
- ): GatePlan {
167
+ //
168
+ // **The free cores do not cap the plan** (joshuafolkken/kit#4167). The unit claim's admission narrows it
169
+ // to the room the outside load leaves, read over its wait rather than once at the gate's start — a
170
+ // width fixed off one busy instant held for the whole suite (`core_admission.is_too_narrow`).
171
+ function announce_gate_plan(is_unit_included: boolean, available_cores: number): GatePlan {
174
172
  const concurrent_runs = unit_worker_share.live_run_count() + unit_worker_share.SOLO_RUNS
175
173
  const is_kit_repository = project_checks.is_kit_repository(process.cwd())
176
- const resolved = gate_plan.resolve_gate_plan(
174
+ const plan = gate_plan.resolve_gate_plan(
177
175
  available_cores,
178
176
  concurrent_runs,
179
177
  is_unit_included,
180
178
  is_kit_repository,
181
179
  )
182
- const plan = gate_plan.bound_by_free(resolved, available_cores, free)
183
180
 
184
181
  process.stdout.write(`${gate_plan.format_gate_plan(plan, available_cores, concurrent_runs)}\n`)
185
182
 
@@ -217,10 +214,6 @@ interface GateOptions {
217
214
  // Where each check's own green record lives (`check-reuse.ts`). Only the CLI entry resolves it, for
218
215
  // the ledger's reason: a suite whose checks never ran must not record them green on the live tree.
219
216
  check_records?: CheckRecords | undefined
220
- // The cores free of load from outside the core budget's ledger (`free-cores.ts`). Only the CLI entry
221
- // resolves it, for the ledger's reason: a suite driving the gate never reads the machine, so its plan
222
- // does not depend on what else happened to be running.
223
- read_free_cores?: ((available_cores: number) => Promise<number | undefined>) | undefined
224
217
  }
225
218
 
226
219
  // **Per-check records belong to the full local gate alone**: CI's `--no-unit` gate is the safety net
@@ -325,9 +318,7 @@ async function run_checked_gate(
325
318
  // Resolved at the gate's entry, before this gate sets `JOSH_UNIT_RUN_MARKED`, so a gate nested in the
326
319
  // unit suite reads the flag as set and reserves nothing.
327
320
  const budget = gate_run_steps.default_budget()
328
- // Read before the count for the ledger's reason: the reading waits out a sample window.
329
- const free = await options.read_free_cores?.(budget.available_cores)
330
- const plan = announce_gate_plan(is_unit_included, budget.available_cores, free)
321
+ const plan = announce_gate_plan(is_unit_included, budget.available_cores)
331
322
  const reused = await checks_to_reuse(plan, tree, options)
332
323
 
333
324
  // **The gate holds the unit-run marker for its whole run, not just its unit step.** The step that
@@ -353,17 +344,30 @@ function reusable_stamp(tree: GateTree, options: GateOptions): FileMapStamp | un
353
344
  return gate_skip.reusable_green_gate(tree.files, tree.base, options.stamp_path)
354
345
  }
355
346
 
347
+ // The reuse leaves its line in the ledger too, so `josh lane:stats` counts the gates it saved
348
+ // (joshuafolkken/kit#4397).
349
+ async function reuse_gate(
350
+ stamp: FileMapStamp,
351
+ options: GateOptions,
352
+ started_at: number,
353
+ ): Promise<number> {
354
+ process.stdout.write(`${gate_skip.format_skip(stamp.taken_at)}\n`)
355
+ await gate_ledger.record_reused(options.ledger_path, performance.now() - started_at)
356
+
357
+ return 0
358
+ }
359
+
356
360
  // The two ways a gate ends before it runs a check: a green record it can reuse (exit 0), and the
357
361
  // scoped pre-check refusing a tree the pair has not been green on (exit 1). `undefined` means neither
358
362
  // fired and the checks run. **Nothing else stands between the skip and the checks.**
359
- function short_circuit_gate(tree: GateTree, options: GateOptions): number | undefined {
363
+ async function short_circuit_gate(
364
+ tree: GateTree,
365
+ options: GateOptions,
366
+ started_at: number,
367
+ ): Promise<number | undefined> {
360
368
  const reusable = reusable_stamp(tree, options)
361
369
 
362
- if (reusable !== undefined) {
363
- process.stdout.write(`${gate_skip.format_skip(reusable.taken_at)}\n`)
364
-
365
- return 0
366
- }
370
+ if (reusable !== undefined) return await reuse_gate(reusable, options, started_at)
367
371
 
368
372
  const scoped_refusal = scoped_precheck_refusal(tree, options)
369
373
 
@@ -379,7 +383,7 @@ async function run_verification_gate(options: GateOptions = {}): Promise<number>
379
383
  // four checks alone took — the gate's own bookkeeping is part of the wait either way.
380
384
  const started_at = performance.now()
381
385
  const tree = await gate_tree.read_gate_tree()
382
- const short_circuit = short_circuit_gate(tree, options)
386
+ const short_circuit = await short_circuit_gate(tree, options, started_at)
383
387
 
384
388
  if (short_circuit !== undefined) return short_circuit
385
389
 
@@ -438,7 +442,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
438
442
  process.exitCode = await run_gate_command(process.argv.slice(FIRST_ARGUMENT_INDEX), {
439
443
  ledger_path: await lane_ledger.target(),
440
444
  check_records: check_reuse.DEFAULT_RECORDS,
441
- read_free_cores: async (available_cores) => await free_cores.read({ available_cores }),
442
445
  })
443
446
  }
444
447