@joshuafolkken/kit 1.1471.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -1,19 +1,18 @@
1
1
  #!/usr/bin/env tsx
2
- import { availableParallelism } from 'node:os'
3
2
  import { fileURLToPath } from 'node:url'
4
3
  import type { FileMapStamp } from '#scripts/josh/file-map-stamp'
5
4
  import { GATE_COMMAND } from '#scripts/josh/josh-command-types'
6
5
  import { composite_arguments, USAGE_ERROR_EXIT_CODE } from '#scripts/josh/josh-composite-arguments'
7
6
  import { lane_ledger } from '#scripts/lane/lane-ledger'
8
- import { bounded_pool } from '#scripts/lib/bounded-pool'
9
- import { buffered_process, FAIL_EXIT_CODE } from '#scripts/lib/buffered-process'
7
+ import { FAIL_EXIT_CODE } from '#scripts/lib/buffered-process'
10
8
  import { review_stamps } from '#scripts/review/review-stamps'
11
9
  import { review_tree } from '#scripts/review/review-tree'
12
10
  import { unit_worker_share } from '#scripts/test/unit-worker-share'
13
- import { core_budget } from './core-budget'
11
+ import { check_reuse, type CheckRecords } from './check-reuse'
14
12
  import { gate_ledger, type GateLedgerStart } from './gate-ledger'
15
13
  import { gate_plan, type GatePlan } from './gate-plan'
16
- import { gate_report, type GateStep, type GateStepResult } from './gate-report'
14
+ import { gate_report, type GateStepResult } from './gate-report'
15
+ import { gate_run_steps, type ReusedChecks } from './gate-run-steps'
17
16
  import { gate_skip } from './gate-skip'
18
17
  import { build_gate_step, build_gate_steps, UNIT_WORKER_FLAG } from './gate-steps'
19
18
  import { gate_tree, type GateTree } from './gate-tree'
@@ -35,25 +34,6 @@ const { GATE_CHECKS } = gate_plan
35
34
 
36
35
  const GATE_TARGETS: ReadonlyArray<string> = GATE_CHECKS.map((check) => check.target)
37
36
 
38
- async function run_gate_step(step: GateStep): Promise<GateStepResult> {
39
- if (step.skip_reason !== undefined) {
40
- return {
41
- label: step.label,
42
- command: step.command_args.join(' '),
43
- output: project_checks.skip_notice('check', step.skip_reason),
44
- exit_code: 0,
45
- elapsed_ms: 0,
46
- }
47
- }
48
-
49
- const result = await buffered_process.run_buffered_process(
50
- step.command_args,
51
- step.cwd === undefined ? {} : { cwd: step.cwd },
52
- )
53
-
54
- return { label: step.label, command: step.command_args.join(' '), ...result }
55
- }
56
-
57
37
  // The record `josh review:brief` reads, written only on a fully green run and only with the tree it
58
38
  // was green on. `/code-review` runs in a forked process that reads none of
59
39
  // this repository's documents, so "the unit tests already passed" reaches it only if the invocation
@@ -65,7 +45,7 @@ async function run_gate_step(step: GateStep): Promise<GateStepResult> {
65
45
  // visible on the console, and a record erasing it would have the brief tell a review agent not to
66
46
  // re-run tests that never ran. A skip of a tool the project does not use (`NOT_USED_MARKER` — eslint
67
47
  // with no ESLint configuration) is not one: nothing went unverified, so it withholds nothing
68
- // (`gate_report.is_unverified_skip`). A step that passed **with a checker's warnings** is withheld for the
48
+ // (`gate_report.has_nothing_to_say`). A step that passed **with a checker's warnings** is withheld for the
69
49
  // same reason one place further on: since the record is reused instead of the checks being re-run, a
70
50
  // warning printed once would never be printed again on that tree, and hiding an eslint or
71
51
  // svelte-check finding is the same failure as hiding a skip. It is `has_checker_warning`, not
@@ -81,17 +61,13 @@ async function run_gate_step(step: GateStep): Promise<GateStepResult> {
81
61
  //
82
62
  // The destination is a parameter so a test can exercise the record without overwriting the one a
83
63
  // real run may be relying on — `josh gate` and `josh review:brief` share one path by design.
84
- function has_nothing_to_say(result: GateStepResult): boolean {
85
- return !gate_report.is_unverified_skip(result) && !gate_report.has_checker_warning(result)
86
- }
87
-
88
64
  async function record_green_gate(
89
65
  results: ReadonlyArray<GateStepResult>,
90
66
  before: Record<string, string>,
91
67
  target?: string,
92
68
  base?: string,
93
69
  ): Promise<void> {
94
- if (results.some((result) => !has_nothing_to_say(result))) return
70
+ if (results.some((result) => !gate_report.has_nothing_to_say(result))) return
95
71
 
96
72
  try {
97
73
  const after = await review_tree.read_changed_tree()
@@ -153,94 +129,6 @@ async function with_gate_marker<T>(
153
129
  }
154
130
  }
155
131
 
156
- // This gate's share of the machine, resolved once at the gate's entry and carried down as one value.
157
- // `available_cores` is the budget every check reserves against; `is_reserved`
158
- // is false for a gate nested inside another gate's unit suite — this repository's own gate tests — so
159
- // the outer gate reserves and every gate beneath it does not. Captured before this gate sets
160
- // `JOSH_UNIT_RUN_MARKED`, which is why it is read at entry rather than re-derived here.
161
- interface BudgetContext {
162
- available_cores: number
163
- is_reserved: boolean
164
- }
165
-
166
- function default_budget(): BudgetContext {
167
- return {
168
- available_cores: availableParallelism(),
169
- is_reserved: !unit_worker_share.is_nested_run() && !core_budget.is_held(),
170
- }
171
- }
172
-
173
- // A gate step paired with the cores it reserves from the machine-wide budget while it runs.
174
- // The weight travels with the step so `run_gate_steps` never has to re-pair a
175
- // step with its check by index.
176
- interface ReservedStep {
177
- step: GateStep
178
- weight: number
179
- memory_mb: number
180
- }
181
-
182
- async function build_reserved_steps(
183
- start_directory: string,
184
- plan: GatePlan,
185
- available_cores: number,
186
- ): Promise<ReadonlyArray<ReservedStep>> {
187
- return await Promise.all(
188
- plan.checks.map(async (check) => ({
189
- step: await build_gate_step(check, start_directory, plan),
190
- weight: gate_plan.check_weight(check, plan, available_cores),
191
- memory_mb: gate_plan.check_memory(check, plan, available_cores),
192
- })),
193
- )
194
- }
195
-
196
- // **A nested gate takes no reservation, and the budget is what makes that necessary rather than
197
- // merely tidy**. The unit step spawns the suite, which runs this repository's
198
- // own gate tests; each of those is a gate inside the outer gate's unit reservation, and a place it
199
- // claimed would wait for cores the outer gate cannot free until the suite — this test included —
200
- // finishes.
201
- async function run_reserved_step(
202
- reserved: ReservedStep,
203
- budget: BudgetContext,
204
- ): Promise<GateStepResult> {
205
- if (!budget.is_reserved) return await run_gate_step(reserved.step)
206
-
207
- return await core_budget.with_core_reservation(
208
- reserved.weight,
209
- async (admission) => ({
210
- ...(await run_gate_step(reserved.step)),
211
- budget_note: core_budget.describe_overflow(admission),
212
- }),
213
- { budget: budget.available_cores, memory_mb: reserved.memory_mb },
214
- )
215
- }
216
-
217
- // `bounded_pool` rather than a bare `Promise.all`, so the plan's `concurrency` is what decides how
218
- // many run at once. **The all-failures-in-one-pass property survives the
219
- // change** because no check ever rejects: `buffered_process` reports a non-zero exit as a value, so
220
- // the pool's first-failure abort — written for callers that spawn real Claude sessions — never
221
- // fires here and every queued check still runs. Results come back in input order however they
222
- // finished, which is what keeps the printed sections in declaration order. Each step first claims its
223
- // place in the machine-wide budget and waits while the budget is full.
224
- async function run_gate_steps(
225
- plan: GatePlan,
226
- budget: BudgetContext = default_budget(),
227
- ): Promise<ReadonlyArray<GateStepResult>> {
228
- const reserved = await build_reserved_steps(process.cwd(), plan, budget.available_cores)
229
-
230
- // **The checks run under the held mark, so a check's own dispatch claims nothing**.
231
- // Each check is a `pnpm josh <target>` child, and a target that declares
232
- // a weight would otherwise claim a second place for the cores reserved for it here. A nested gate
233
- // sets the mark too, since its checks are covered by the outer gate's reservation.
234
- return await core_budget.with_held_mark(
235
- async () =>
236
- await bounded_pool.bounded_map(
237
- reserved,
238
- plan.concurrency,
239
- async (entry) => await run_reserved_step(entry, budget),
240
- ),
241
- )
242
- }
243
-
244
132
  // **Both markers are claims about the unit suite, so a gate that is not running it makes neither**.
245
133
  // The in-flight marker tells the next `josh review:brief` that a gate is
246
134
  // covering this tree right now, which is what stops a review agent re-running the suite; the
@@ -276,6 +164,10 @@ async function run_marked_gate<T>(
276
164
  // The concurrent-run count is read here rather than inside `gate-plan.ts` for the reason the core
277
165
  // count already is: that module stays a pure function of its inputs, and the machine is asked once and
278
166
  // handed to both calls. Counted *before* the unit step writes its own marker, so `+ 1` is this gate.
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`).
279
171
  function announce_gate_plan(is_unit_included: boolean, available_cores: number): GatePlan {
280
172
  const concurrent_runs = unit_worker_share.live_run_count() + unit_worker_share.SOLO_RUNS
281
173
  const is_kit_repository = project_checks.is_kit_repository(process.cwd())
@@ -319,6 +211,31 @@ interface GateOptions {
319
211
  // The lane ledger a finished gate's duration is appended to. Only the CLI
320
212
  // entry resolves it, so a suite driving the gate never writes a measurement of checks that never ran.
321
213
  ledger_path?: string | undefined
214
+ // Where each check's own green record lives (`check-reuse.ts`). Only the CLI entry resolves it, for
215
+ // the ledger's reason: a suite whose checks never ran must not record them green on the live tree.
216
+ check_records?: CheckRecords | undefined
217
+ }
218
+
219
+ // **Per-check records belong to the full local gate alone**: CI's `--no-unit` gate is the safety net
220
+ // under the local reuse and stays as it was, so it neither reads nor writes one.
221
+ function check_records_of(plan: GatePlan, options: GateOptions): CheckRecords | undefined {
222
+ return gate_plan.has_unit_check(plan.checks) ? options.check_records : undefined
223
+ }
224
+
225
+ async function checks_to_reuse(
226
+ plan: GatePlan,
227
+ tree: GateTree,
228
+ options: GateOptions,
229
+ ): Promise<ReusedChecks> {
230
+ const records = check_records_of(plan, options)
231
+
232
+ if (records === undefined || options.is_forced === true) return new Map()
233
+
234
+ return await check_reuse.reusable_checks(
235
+ plan.checks.map((check) => check.label),
236
+ tree,
237
+ records,
238
+ )
322
239
  }
323
240
 
324
241
  // **The gate refuses to start when the scoped pair has not been green on this tree**
@@ -374,6 +291,10 @@ async function settle_gate(
374
291
 
375
292
  await gate_ledger.record(options.ledger, results, { elapsed_ms, is_passed })
376
293
 
294
+ const records = check_records_of(plan, options)
295
+
296
+ if (records !== undefined) await check_reuse.record_green_checks(results, tree, records)
297
+
377
298
  if (!is_passed) return FAIL_EXIT_CODE
378
299
 
379
300
  await record_whole_gate(plan, results, tree, options)
@@ -396,8 +317,9 @@ async function run_checked_gate(
396
317
  const ledger = await gate_ledger.start(options.ledger_path)
397
318
  // Resolved at the gate's entry, before this gate sets `JOSH_UNIT_RUN_MARKED`, so a gate nested in the
398
319
  // unit suite reads the flag as set and reserves nothing.
399
- const budget = default_budget()
320
+ const budget = gate_run_steps.default_budget()
400
321
  const plan = announce_gate_plan(is_unit_included, budget.available_cores)
322
+ const reused = await checks_to_reuse(plan, tree, options)
401
323
 
402
324
  // **The gate holds the unit-run marker for its whole run, not just its unit step.** The step that
403
325
  // would write it is a subprocess started a second or so after the count above, so two lanes launched
@@ -406,7 +328,7 @@ async function run_checked_gate(
406
328
  // the next lane asks; the guard inside the spawned `josh test:unit` sees the handoff and adds no
407
329
  // second marker for the same run.
408
330
  async function run_and_settle(): Promise<number> {
409
- const results = await run_gate_steps(plan, budget)
331
+ const results = await gate_run_steps.run_gate_steps(plan, budget, reused)
410
332
 
411
333
  return await settle_gate(plan, results, tree, { ...options, started_at, ledger })
412
334
  }
@@ -422,17 +344,30 @@ function reusable_stamp(tree: GateTree, options: GateOptions): FileMapStamp | un
422
344
  return gate_skip.reusable_green_gate(tree.files, tree.base, options.stamp_path)
423
345
  }
424
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
+
425
360
  // The two ways a gate ends before it runs a check: a green record it can reuse (exit 0), and the
426
361
  // scoped pre-check refusing a tree the pair has not been green on (exit 1). `undefined` means neither
427
362
  // fired and the checks run. **Nothing else stands between the skip and the checks.**
428
- 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> {
429
368
  const reusable = reusable_stamp(tree, options)
430
369
 
431
- if (reusable !== undefined) {
432
- process.stdout.write(`${gate_skip.format_skip(reusable.taken_at)}\n`)
433
-
434
- return 0
435
- }
370
+ if (reusable !== undefined) return await reuse_gate(reusable, options, started_at)
436
371
 
437
372
  const scoped_refusal = scoped_precheck_refusal(tree, options)
438
373
 
@@ -448,7 +383,7 @@ async function run_verification_gate(options: GateOptions = {}): Promise<number>
448
383
  // four checks alone took — the gate's own bookkeeping is part of the wait either way.
449
384
  const started_at = performance.now()
450
385
  const tree = await gate_tree.read_gate_tree()
451
- const short_circuit = short_circuit_gate(tree, options)
386
+ const short_circuit = await short_circuit_gate(tree, options, started_at)
452
387
 
453
388
  if (short_circuit !== undefined) return short_circuit
454
389
 
@@ -506,6 +441,7 @@ async function run_gate_command(
506
441
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
507
442
  process.exitCode = await run_gate_command(process.argv.slice(FIRST_ARGUMENT_INDEX), {
508
443
  ledger_path: await lane_ledger.target(),
444
+ check_records: check_reuse.DEFAULT_RECORDS,
509
445
  })
510
446
  }
511
447
 
@@ -519,11 +455,11 @@ const verification_gate = {
519
455
  clear_gate_running,
520
456
  mark_gate_running,
521
457
  record_green_gate,
522
- run_gate_steps,
458
+ run_gate_steps: gate_run_steps.run_gate_steps,
523
459
  scoped_precheck_refusal,
524
460
  with_gate_marker,
525
461
  run_gate_command,
526
- run_gate_step,
462
+ run_gate_step: gate_run_steps.run_gate_step,
527
463
  run_verification_gate,
528
464
  }
529
465
 
@@ -0,0 +1,250 @@
1
+ import { readFileSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { PROJECT_ROOT } from '#scripts/init/init-paths'
4
+ import { lint_related_scope } from '#scripts/lint/lint-related-scope'
5
+ import { gate_plan } from './gate-plan'
6
+ import { input_fingerprint } from './input-fingerprint'
7
+ import { toolchain_inputs } from './toolchain-inputs'
8
+
9
+ // **What each verification depends on, declared once** (joshuafolkken/kit#4495). Every reuse of a
10
+ // verdict — the whole gate (`gate-skip.ts`), one check (`check-reuse.ts`), a scoped record
11
+ // (`scoped-green.ts`) and the since-green narrowing (`since-green.ts`) — answers from the declaration
12
+ // here — the paths through `check-inputs.ts`, the tools and environment through `fingerprint` — so a
13
+ // new reuse picks a declaration rather than writing its own invalidation.
14
+ //
15
+ // A declaration names:
16
+ // - `is_input` — whether a path is a content input; `undefined` leaves it to `reads`.
17
+ // - `reads` — `matched`: the inputs are the paths `is_input` accepts. `recorded`: the inputs are the
18
+ // files a run read, as the run recorded them — the test-read map (joshuafolkken/kit#4314), whose
19
+ // file digests are `input-fingerprint.ts`'s — so a path is an input only when some recorded test
20
+ // reads it.
21
+ // - `is_config` — the files that configure the check: one that moves invalidates the verdict whatever
22
+ // else moved, and stops the since-green narrowing.
23
+ // - `tools` — the packages whose installed version runs the check.
24
+ // - `env` — the environment variables whose value changes the verdict.
25
+ //
26
+ // **A check with no declaration always runs**: `cspell` reads every text file and `behavior` reads a
27
+ // transcript outside the tree. Naming inputs for either would be a guess, and a wrong guess is a check
28
+ // reported green without having run. **The declarations over-approximate, never under**: a path in
29
+ // doubt is an input. `metrics` reads the scripts it counts, the approvals under
30
+ // `.josh/metrics-accepted/` (JSON) and the Markdown it measures (joshuafolkken/kit#4085). `lint` is
31
+ // prettier plus eslint, so its inputs are the sources plus every file prettier formats, less what
32
+ // prettier's own ignore files leave out — prettier answers that itself (`check-inputs.ts`).
33
+
34
+ const GIT_IGNORE = '.gitignore'
35
+ const PRETTIER_IGNORE = '.prettierignore'
36
+ const PRETTIER_IGNORE_FILES = [GIT_IGNORE, PRETTIER_IGNORE] as const
37
+
38
+ // A manifest or lock file moves the installed tools (`toolchain-inputs.ts`, the list every kept result
39
+ // shares), and an ignore or editor file moves what prettier formats — a configuration of every
40
+ // declared check.
41
+ const MANIFEST = 'package.json'
42
+
43
+ const TOOLCHAIN_FILES: ReadonlySet<string> = new Set([
44
+ ...toolchain_inputs.PACKAGE_FILES.map((relative) => path.basename(relative)),
45
+ '.editorconfig',
46
+ ...PRETTIER_IGNORE_FILES,
47
+ ])
48
+
49
+ const PRETTIER_CONFIG_PREFIX = '.prettierrc'
50
+
51
+ // A file name starting with one of these configures the TypeScript program a check compiles, and the
52
+ // test runner for the unit step.
53
+ const COMPILER_CONFIG_PREFIXES = ['tsconfig', 'svelte.config.'] as const
54
+ const TEST_CONFIG_PREFIXES = [...COMPILER_CONFIG_PREFIXES, 'vitest.config.', 'vite.config.']
55
+
56
+ // A file name starting with one of these, or a path under one of the directories, configures prettier,
57
+ // eslint or the TypeScript program its type-aware rules read. Prettier keys its cache on the options
58
+ // too, so a changed `prettier.config.*` re-checks every file the whole-tree run reads.
59
+ const LINT_CONFIG_PREFIXES = ['eslint.config.', 'prettier.config.', ...COMPILER_CONFIG_PREFIXES]
60
+ const LINT_CONFIG_DIRECTORIES: ReadonlySet<string> = new Set(['eslint', 'prettier', 'tsconfig'])
61
+
62
+ const SOURCE_EXTENSIONS: ReadonlySet<string> = new Set([
63
+ '.ts',
64
+ '.tsx',
65
+ '.mts',
66
+ '.cts',
67
+ '.js',
68
+ '.jsx',
69
+ '.mjs',
70
+ '.cjs',
71
+ '.svelte',
72
+ '.vue',
73
+ '.json',
74
+ '.jsonc',
75
+ ])
76
+
77
+ const MARKDOWN_EXTENSION = '.md'
78
+ // `NODE_OPTIONS` is left out: package managers and hooks set it differently around the same check,
79
+ // and it tunes the runtime rather than what a check answers.
80
+ const COMMON_ENV = ['NODE_ENV'] as const
81
+ const ABSENT = 'absent'
82
+
83
+ type Environment = Readonly<Record<string, string | undefined>>
84
+
85
+ // Whether prettier would leave `relative` out; `false` when prettier cannot be asked, which keeps the
86
+ // path an input.
87
+ type PrettierIgnored = (relative: string) => Promise<boolean>
88
+
89
+ type FileTest = (relative: string, is_ignored: PrettierIgnored) => Promise<boolean>
90
+
91
+ type InputReads = 'matched' | 'recorded'
92
+
93
+ interface InputDeclaration {
94
+ readonly is_input: FileTest | undefined
95
+ readonly reads: InputReads
96
+ readonly is_config: (relative: string) => boolean
97
+ readonly tools: ReadonlyArray<string>
98
+ readonly env: ReadonlyArray<string>
99
+ }
100
+
101
+ function is_source(relative: string): boolean {
102
+ return SOURCE_EXTENSIONS.has(path.extname(relative))
103
+ }
104
+
105
+ async function is_lint_input(relative: string, is_ignored: PrettierIgnored): Promise<boolean> {
106
+ if (is_source(relative)) return true
107
+ if (!lint_related_scope.is_lintable(relative)) return false
108
+
109
+ return !(await is_ignored(relative))
110
+ }
111
+
112
+ async function is_source_input(relative: string): Promise<boolean> {
113
+ return is_source(relative)
114
+ }
115
+
116
+ async function is_metrics_input(relative: string): Promise<boolean> {
117
+ return is_source(relative) || path.extname(relative) === MARKDOWN_EXTENSION
118
+ }
119
+
120
+ function configures_toolchain(relative: string): boolean {
121
+ const name = path.basename(relative)
122
+
123
+ return TOOLCHAIN_FILES.has(name) || name.startsWith(PRETTIER_CONFIG_PREFIX)
124
+ }
125
+
126
+ function names_any(relative: string, prefixes: ReadonlyArray<string>): boolean {
127
+ const name = path.basename(relative)
128
+
129
+ return configures_toolchain(relative) || prefixes.some((prefix) => name.startsWith(prefix))
130
+ }
131
+
132
+ function configures_compiler(relative: string): boolean {
133
+ return names_any(relative, COMPILER_CONFIG_PREFIXES)
134
+ }
135
+
136
+ function configures_tests(relative: string): boolean {
137
+ return names_any(relative, TEST_CONFIG_PREFIXES)
138
+ }
139
+
140
+ function configures_lint(relative: string): boolean {
141
+ const [top = ''] = relative.split('/', 1)
142
+
143
+ return LINT_CONFIG_DIRECTORIES.has(top) || names_any(relative, LINT_CONFIG_PREFIXES)
144
+ }
145
+
146
+ const LINT: InputDeclaration = {
147
+ is_input: is_lint_input,
148
+ reads: 'matched',
149
+ is_config: configures_lint,
150
+ tools: ['prettier', 'eslint', 'typescript'],
151
+ env: COMMON_ENV,
152
+ }
153
+
154
+ const UNIT: InputDeclaration = {
155
+ is_input: undefined,
156
+ reads: 'recorded',
157
+ is_config: configures_tests,
158
+ tools: ['vitest', 'typescript'],
159
+ env: [...COMMON_ENV, 'TZ'],
160
+ }
161
+
162
+ function compiled(is_input: FileTest): InputDeclaration {
163
+ return {
164
+ is_input,
165
+ reads: 'matched',
166
+ is_config: configures_compiler,
167
+ tools: ['typescript'],
168
+ env: COMMON_ENV,
169
+ }
170
+ }
171
+
172
+ const DECLARATIONS: ReadonlyMap<string, InputDeclaration> = new Map([
173
+ [gate_plan.LINT_LABEL, LINT],
174
+ [gate_plan.TYPE_CHECK_LABEL, compiled(is_source_input)],
175
+ [gate_plan.EXPORTS_LABEL, compiled(is_source_input)],
176
+ [gate_plan.METRICS_LABEL, compiled(is_metrics_input)],
177
+ [gate_plan.UNIT_LABEL, UNIT],
178
+ ])
179
+
180
+ function declaration_of(label: string): InputDeclaration | undefined {
181
+ return DECLARATIONS.get(label)
182
+ }
183
+
184
+ function is_declared(label: string): boolean {
185
+ return DECLARATIONS.has(label)
186
+ }
187
+
188
+ // Whether any of `relatives` (repository-root relative) configures the check `label` — `true` for an
189
+ // undeclared one, which no narrowing can read past.
190
+ function configures(label: string, relatives: ReadonlyArray<string>): boolean {
191
+ const declaration = DECLARATIONS.get(label)
192
+
193
+ return declaration === undefined || relatives.some((relative) => declaration.is_config(relative))
194
+ }
195
+
196
+ function tool_version(root: string, tool: string): string {
197
+ try {
198
+ const manifest: unknown = JSON.parse(
199
+ readFileSync(path.join(root, 'node_modules', tool, MANIFEST), 'utf8'),
200
+ )
201
+
202
+ return typeof manifest === 'object' && manifest !== null && 'version' in manifest
203
+ ? String(manifest.version)
204
+ : ABSENT
205
+ } catch {
206
+ return ABSENT
207
+ }
208
+ }
209
+
210
+ function entries_of(
211
+ declaration: InputDeclaration,
212
+ root: string,
213
+ environment: Environment,
214
+ ): ReadonlyArray<string> {
215
+ return [
216
+ ...declaration.tools.map((tool) => `tool:${tool}=${tool_version(root, tool)}`),
217
+ ...declaration.env.map((name) => `env:${name}=${environment[name] ?? ABSENT}`),
218
+ ]
219
+ }
220
+
221
+ // **The fingerprint of what the checks `labels` read beside the files**: the installed version of every
222
+ // declared tool and the value of every declared environment variable, sorted into one digest. The
223
+ // file contents are the record's own file map (`file-map-stamp.ts`) and the merge base its `base`, so a
224
+ // reuse matches all three. One label answers a check's record; every declared label the whole gate's.
225
+ function fingerprint(
226
+ labels: ReadonlyArray<string>,
227
+ root: string = PROJECT_ROOT,
228
+ environment: Environment = process.env,
229
+ ): string {
230
+ const declarations = labels.flatMap((label) => DECLARATIONS.get(label) ?? [])
231
+ const entries = new Set(
232
+ declarations.flatMap((declaration) => entries_of(declaration, root, environment)),
233
+ )
234
+
235
+ return input_fingerprint.of_entries(entries)
236
+ }
237
+
238
+ const DECLARED_LABELS: ReadonlyArray<string> = [...DECLARATIONS.keys()]
239
+
240
+ const verification_inputs = {
241
+ configures,
242
+ declaration_of,
243
+ DECLARED_LABELS,
244
+ fingerprint,
245
+ is_declared,
246
+ PRETTIER_IGNORE_FILES,
247
+ }
248
+
249
+ export type { InputDeclaration, InputReads, PrettierIgnored }
250
+ export { verification_inputs }
@@ -1,14 +1,101 @@
1
- // Whose words kit acts on: the `author_association` REST reports with an issue or a comment, and the
2
- // ones that can write to the repository. On a public repository anyone can file an issue or comment,
3
- // so a body kit runs (`josh measure:rerun`) or copies into the ledger (`review:record`) is taken only
4
- // from an author with write access — and an unknown author is not a trusted one.
5
- const TRUSTED_ASSOCIATIONS: ReadonlySet<string> = new Set(['OWNER', 'MEMBER', 'COLLABORATOR'])
6
- const TRUSTED_LIST = [...TRUSTED_ASSOCIATIONS].join(' / ')
1
+ import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
2
+ import { git_gh_exec } from '#scripts/gh/git-gh-exec'
3
+ import { parse_json } from '#scripts/git/parse-json-array'
4
+ import { z } from 'zod'
7
5
 
8
- function is_trusted(association: string | null | undefined): boolean {
9
- return typeof association === 'string' && TRUSTED_ASSOCIATIONS.has(association)
6
+ // Whose words kit acts on: the author of an issue or a comment who can write to the repository. On a
7
+ // public repository anyone can file an issue or comment, so a body kit runs (`josh measure:rerun`) or
8
+ // copies into the ledger (`review:record`) is taken only from an author with write access — and an
9
+ // unknown author is not a trusted one.
10
+ //
11
+ // **`author_association` alone does not say "can write"** (joshuafolkken/kit#4037). `OWNER` does, so it
12
+ // is trusted without a request. `MEMBER` is any member of the owning org, whatever their access to this
13
+ // repository, and `COLLABORATOR` includes outside collaborators with read or triage access only — so
14
+ // those two are asked of the collaborator-permission endpoint, once per login per process, and trusted
15
+ // only on a write role. A lookup that fails is not trust.
16
+ const OWNER = 'OWNER'
17
+ const ASKED_ASSOCIATIONS: ReadonlySet<string> = new Set(['MEMBER', 'COLLABORATOR'])
18
+ const WRITE_ROLES: ReadonlySet<string> = new Set(['admin', 'maintain', 'write'])
19
+ // A GitHub user login, an Enterprise Managed User's `name_shortcode` included — it is placed in a REST
20
+ // path, so anything else (a `[bot]` login, a slash) is refused before a request is made.
21
+ const LOGIN_PATTERN = /^[\da-z](?:[\w-]*[\da-z])?$/iu
22
+ const TRUSTED_LIST = 'OWNER, or MEMBER / COLLABORATOR with write access'
23
+
24
+ const permission_schema = z.looseObject({
25
+ permission: z.string().nullish(),
26
+ role_name: z.string().nullish(),
27
+ })
28
+
29
+ // `timeout_ms` bounds the lookup for a caller inside a hook's own timeout (`issue-watch`).
30
+ interface Author {
31
+ login: string | undefined
32
+ association: string | null | undefined
33
+ timeout_ms?: number | undefined
34
+ }
35
+
36
+ const answers = new Map<string, Promise<boolean | undefined>>()
37
+
38
+ function permission_path(login: string): string {
39
+ return `${git_gh_api_path.repo_api_path()}/collaborators/${login}/permission`
40
+ }
41
+
42
+ // `role_name` names `maintain` exactly; `permission` folds it into `write`, so either answers.
43
+ function has_write_role(raw: string): boolean {
44
+ const parsed = parse_json.parse_json_object_or_undefined(raw, permission_schema)
45
+ const roles = [parsed?.role_name, parsed?.permission]
46
+
47
+ return roles.some((role) => typeof role === 'string' && WRITE_ROLES.has(role))
48
+ }
49
+
50
+ // `undefined` for a lookup that failed, which is not an answer.
51
+ async function ask_permission(login: string, timeout_ms?: number): Promise<boolean | undefined> {
52
+ try {
53
+ const raw = await git_gh_exec.exec_gh_api({ path: permission_path(login), timeout_ms })
54
+
55
+ return has_write_role(raw)
56
+ } catch {
57
+ return undefined
58
+ }
59
+ }
60
+
61
+ // A failed lookup is not remembered: the backlog driver keeps one process for hours, so one dropped
62
+ // request would otherwise leave that author unanswered until it restarts. Only the caller's own
63
+ // request is evicted, never a newer one another caller has stored since.
64
+ async function can_write(login: string, timeout_ms?: number): Promise<boolean | undefined> {
65
+ const asked = answers.get(login) ?? ask_permission(login, timeout_ms)
66
+
67
+ answers.set(login, asked)
68
+
69
+ const has_write = await asked
70
+
71
+ if (has_write === undefined && answers.get(login) === asked) answers.delete(login)
72
+
73
+ return has_write
74
+ }
75
+
76
+ function is_user_login(login: string | undefined): login is string {
77
+ return login !== undefined && LOGIN_PATTERN.test(login)
78
+ }
79
+
80
+ function is_asked(author: Author): boolean {
81
+ return ASKED_ASSOCIATIONS.has(author.association ?? '') && is_user_login(author.login)
82
+ }
83
+
84
+ // `undefined` when the lookup failed: neither trusted nor refused, for a caller that must not settle a
85
+ // permanent answer on it (`review-comment-round`).
86
+ async function trust_of(author: Author): Promise<boolean | undefined> {
87
+ if (author.association === OWNER) return true
88
+ if (author.login === undefined || !is_asked(author)) return false
89
+
90
+ return await can_write(author.login, author.timeout_ms)
91
+ }
92
+
93
+ // A lookup that failed is not trust.
94
+ async function is_trusted(author: Author): Promise<boolean> {
95
+ return (await trust_of(author)) === true
10
96
  }
11
97
 
12
- const gh_author_association = { TRUSTED_LIST, is_trusted }
98
+ const gh_author_association = { TRUSTED_LIST, is_trusted, trust_of }
13
99
 
100
+ export type { Author }
14
101
  export { gh_author_association }