@joshuafolkken/kit 1.1784.0 → 1.2116.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 (690) hide show
  1. package/.claude/agents/reviewer-verification.md +19 -0
  2. package/.claude/agents/reviewer.md +19 -0
  3. package/.claude/settings.json +5 -6
  4. package/.claude/skills/dependency-update/SKILL.md +9 -10
  5. package/.claude/skills/workflow-commands/SKILL.md +6 -6
  6. package/.claude/skills/workflow-commands/background-commands.md +8 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
  13. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  14. package/.claude/skills/workflow-commands/chain-rule.md +41 -32
  15. package/.claude/skills/workflow-commands/delegation.md +6 -6
  16. package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
  17. package/.claude/skills/workflow-commands/followup.md +7 -5
  18. package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
  19. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  20. package/.claude/skills/workflow-commands/issue-comments.md +9 -4
  21. package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +2 -2
  23. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  24. package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
  25. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
  26. package/.claude/skills/workflow-commands/prerequisite.md +3 -2
  27. package/.claude/skills/workflow-commands/retrospective.md +2 -2
  28. package/.claude/skills/workflow-commands/split-assessment.md +7 -5
  29. package/.codex/hooks.json +5 -5
  30. package/.github/actions/setup-pnpm/action.yml +9 -16
  31. package/.github/dependabot.yml +16 -0
  32. package/.github/workflows/auto-tag.yml +45 -0
  33. package/.github/workflows/ci.yml +155 -15
  34. package/.github/workflows/dependabot-auto-merge.yml +63 -4
  35. package/.github/workflows/production.yml +8 -0
  36. package/.github/workflows/publish.yml +60 -45
  37. package/.vscode/settings.json +19 -0
  38. package/CLAUDE.md +5 -12
  39. package/SECURITY.md +2 -2
  40. package/dist/CLAUDE.md +5 -12
  41. package/dist/commands/document-read-cli.js +2 -1
  42. package/dist/commands/document-section-main.js +2 -1
  43. package/dist/commands/read-set-cli.js +194 -134
  44. package/dist/commands/run-prep-main.js +9694 -10173
  45. package/dist/commands/run-step-cli.js +22138 -18285
  46. package/dist/hooks/audit-provision.js +23 -5
  47. package/dist/hooks/chunk-3GKE653K.js +6204 -0
  48. package/dist/hooks/chunk-45CJJOO7.js +1243 -0
  49. package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
  50. package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
  51. package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
  52. package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
  53. package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
  54. package/dist/hooks/chunk-VVNYJWEI.js +30 -0
  55. package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
  56. package/dist/hooks/codex-hook-adapter.js +8 -8
  57. package/dist/hooks/format-edited.js +4 -5
  58. package/dist/hooks/inputs.json +386 -360
  59. package/dist/hooks/pretool-guard.js +7 -6
  60. package/dist/hooks/session-lang.js +101 -258
  61. package/dist/hooks/stop-guard.js +1744 -2576
  62. package/dist/josh.js +7133 -6368
  63. package/dist/version/index.js +161 -1
  64. package/eslint/rules/comment-why-only.js +108 -0
  65. package/package.json +16 -9
  66. package/prompts/coding-standards.md +1 -1
  67. package/prompts/collaboration-workflow/file-edits.md +14 -11
  68. package/prompts/collaboration-workflow/issue-citation.md +0 -4
  69. package/prompts/collaboration-workflow/issue-template.md +40 -21
  70. package/prompts/collaboration-workflow/lane-instructions.md +3 -1
  71. package/prompts/collaboration-workflow/measurement.md +8 -1
  72. package/prompts/collaboration-workflow/operating-rules.md +11 -2
  73. package/prompts/collaboration-workflow/output-bounds.md +6 -2
  74. package/prompts/collaboration-workflow/plan-comment.md +1 -1
  75. package/prompts/collaboration-workflow/principles.md +9 -0
  76. package/prompts/collaboration-workflow/residency.md +3 -2
  77. package/prompts/collaboration-workflow/rule-delivery.md +13 -1
  78. package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
  79. package/prompts/collaboration-workflow/wip-cap.md +3 -1
  80. package/prompts/review-rubric.md +8 -0
  81. package/prompts/review.md +31 -22
  82. package/prompts/testing-guide.md +1 -0
  83. package/scripts/agent/agent-argv.ts +14 -16
  84. package/scripts/agent/agent-provider.ts +138 -0
  85. package/scripts/agent/agent-role-profile.ts +108 -156
  86. package/scripts/agent/agent-safe-text.ts +20 -5
  87. package/scripts/agent/api-usage-limit.ts +65 -0
  88. package/scripts/agent/claude-agent-argv.ts +19 -9
  89. package/scripts/agent/codex-agent-argv.ts +118 -22
  90. package/scripts/agent/usage-limit-reset.ts +179 -0
  91. package/scripts/auth/claude-token-output.ts +2 -2
  92. package/scripts/auto-ok/auto-ok-author.ts +53 -0
  93. package/scripts/auto-ok/auto-ok-cli.ts +20 -9
  94. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  95. package/scripts/backlog/backlog-drive-cli.ts +6 -1
  96. package/scripts/backlog/backlog-drive-hold.ts +3 -3
  97. package/scripts/backlog/backlog-drive-idle.ts +10 -0
  98. package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
  99. package/scripts/backlog/backlog-drive-launch.ts +8 -2
  100. package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
  101. package/scripts/backlog/backlog-drive-named.ts +28 -7
  102. package/scripts/backlog/backlog-drive-paused.ts +5 -4
  103. package/scripts/backlog/backlog-drive-restore.ts +11 -3
  104. package/scripts/backlog/backlog-drive.ts +21 -60
  105. package/scripts/backlog/backlog-gate-scope.ts +61 -0
  106. package/scripts/backlog/backlog-measure-close.ts +112 -0
  107. package/scripts/backlog/backlog-next.ts +39 -49
  108. package/scripts/backlog/backlog-occupied.ts +2 -2
  109. package/scripts/backlog/backlog-overlap.ts +42 -8
  110. package/scripts/backlog/backlog-plan-cli.ts +4 -1
  111. package/scripts/backlog/backlog-plan-comment.ts +81 -0
  112. package/scripts/backlog/backlog-plan-read.ts +19 -6
  113. package/scripts/backlog/backlog-pool.ts +50 -12
  114. package/scripts/backlog/backlog-rank.ts +60 -13
  115. package/scripts/backlog/backlog-stalled-detect.ts +2 -1
  116. package/scripts/backlog/backlog-waves.ts +17 -2
  117. package/scripts/backlog/backlogrun-launch.ts +7 -4
  118. package/scripts/cost-runtime/context-cut-payback.ts +27 -25
  119. package/scripts/cost-runtime/cost-cli.ts +37 -16
  120. package/scripts/cost-runtime/cost-pricing.ts +9 -0
  121. package/scripts/cost-runtime/cost-verdict.ts +4 -1
  122. package/scripts/delegation/delegation-policy.ts +2 -2
  123. package/scripts/delegation/duplicate-read-guard.ts +1 -0
  124. package/scripts/delegation/investigation-guard.ts +14 -2
  125. package/scripts/delegation/investigation-reads.ts +45 -23
  126. package/scripts/dependabot/dependabot-cooldown.ts +3 -2
  127. package/scripts/discovery/repo-party.ts +80 -20
  128. package/scripts/discovery/session-owner-pin.ts +51 -0
  129. package/scripts/document/capped-print.ts +1 -1
  130. package/scripts/document/command-reference-line-budget.ts +42 -0
  131. package/scripts/document/document-byte-budget.ts +17 -7
  132. package/scripts/document/document-checks.ts +20 -0
  133. package/scripts/document/document-ratchet-check.ts +101 -0
  134. package/scripts/document/document-section.ts +1 -0
  135. package/scripts/document/entry-read-budget.ts +7 -3
  136. package/scripts/document/issue-citation-budget.ts +94 -0
  137. package/scripts/epic/epic-cli-argv.ts +2 -2
  138. package/scripts/epic/epic-fetch.ts +4 -2
  139. package/scripts/epic/epic-graph.ts +7 -2
  140. package/scripts/epic/epic-issue.ts +3 -1
  141. package/scripts/epic/epic-rank.ts +5 -0
  142. package/scripts/exports/unused-members-check.ts +62 -0
  143. package/scripts/exports/unused-members-cli.ts +6 -51
  144. package/scripts/followup/followup-ci-path.ts +67 -0
  145. package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
  146. package/scripts/followup/followup-coderabbit-wait.ts +13 -10
  147. package/scripts/followup/followup-failed-tests.ts +160 -0
  148. package/scripts/followup/followup-job-needs.ts +100 -0
  149. package/scripts/followup/followup-job-rerun.ts +303 -0
  150. package/scripts/followup/followup-main-move.ts +113 -0
  151. package/scripts/followup/git-followup-finish.ts +43 -11
  152. package/scripts/followup/git-followup-pending.ts +3 -3
  153. package/scripts/followup/git-followup-stages.ts +41 -11
  154. package/scripts/followup/git-pr-followup-checks.ts +55 -16
  155. package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
  156. package/scripts/followup/git-pr-followup.ts +62 -27
  157. package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
  158. package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
  159. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
  160. package/scripts/gate/busy-average.ts +34 -2
  161. package/scripts/gate/check-related-pinned.ts +43 -0
  162. package/scripts/gate/check-related-reuse.ts +64 -0
  163. package/scripts/gate/check-related-section.ts +57 -0
  164. package/scripts/gate/check-related-unplanned.ts +34 -0
  165. package/scripts/gate/check-related.ts +265 -0
  166. package/scripts/gate/command-memory.ts +1 -1
  167. package/scripts/gate/core-admission.ts +24 -6
  168. package/scripts/gate/core-budget-timing.ts +20 -6
  169. package/scripts/gate/core-budget.ts +40 -11
  170. package/scripts/gate/core-wait-record.ts +3 -2
  171. package/scripts/gate/core-wait.ts +25 -2
  172. package/scripts/gate/core-weights.ts +15 -7
  173. package/scripts/gate/gate-labels.ts +46 -0
  174. package/scripts/gate/gate-ledger.ts +14 -6
  175. package/scripts/gate/gate-plan.ts +103 -58
  176. package/scripts/gate/gate-report.ts +9 -7
  177. package/scripts/gate/gate-run-steps.ts +26 -3
  178. package/scripts/gate/gate-skip.ts +45 -6
  179. package/scripts/gate/gate-static-group.ts +60 -0
  180. package/scripts/gate/gate-steps.ts +2 -1
  181. package/scripts/gate/gate-tree.ts +4 -2
  182. package/scripts/gate/hook-gate-reuse.ts +19 -2
  183. package/scripts/gate/metrics-totals.ts +59 -0
  184. package/scripts/gate/scoped-green.ts +68 -15
  185. package/scripts/gate/since-green.ts +14 -6
  186. package/scripts/gate/structural-checks.ts +96 -0
  187. package/scripts/gate/verification-gate.ts +51 -16
  188. package/scripts/gate/verification-inputs.ts +21 -6
  189. package/scripts/gate/verification-tail.ts +52 -0
  190. package/scripts/gh/gh-author-association.ts +23 -2
  191. package/scripts/gh/git-ai-review-scan.ts +1 -1
  192. package/scripts/gh/git-gh-api-path.ts +12 -3
  193. package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
  194. package/scripts/gh/git-gh-exec.ts +32 -2
  195. package/scripts/gh/git-gh-issue-read.ts +4 -2
  196. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  197. package/scripts/gh/git-gh-issue-write.ts +8 -2
  198. package/scripts/gh/git-gh-issue.ts +12 -5
  199. package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
  200. package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
  201. package/scripts/gh/git-gh-pr-read.ts +74 -13
  202. package/scripts/gh/git-gh-pr-rest.ts +3 -1
  203. package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
  204. package/scripts/gh/git-gh-pr-too-large.ts +20 -0
  205. package/scripts/gh/git-gh-pr.ts +21 -7
  206. package/scripts/gh/git-gh-retry.ts +141 -0
  207. package/scripts/gh/git-pr-ai-review.ts +15 -6
  208. package/scripts/gh/git-pr-checks-eval.ts +3 -0
  209. package/scripts/gh/git-pr-checks.ts +5 -5
  210. package/scripts/git/base-tree.ts +30 -0
  211. package/scripts/git/change-base.ts +4 -10
  212. package/scripts/git/changed-paths-sync.ts +63 -0
  213. package/scripts/git/changed-paths.ts +16 -1
  214. package/scripts/git/git-common-directory.ts +11 -1
  215. package/scripts/git/git-diff-reads.ts +66 -20
  216. package/scripts/git/git-error.ts +9 -2
  217. package/scripts/git/git-schemas.ts +13 -0
  218. package/scripts/git/git-worktree.ts +13 -0
  219. package/scripts/git/gone-branch.ts +4 -1
  220. package/scripts/git/main-merge-budget-conflict.ts +89 -0
  221. package/scripts/git/main-merge-guard.ts +55 -18
  222. package/scripts/git/main-merge-regenerate.ts +59 -25
  223. package/scripts/git/main-merge.ts +53 -5
  224. package/scripts/git/no-base-checkout.ts +127 -0
  225. package/scripts/git/stash/git-stash.ts +11 -2
  226. package/scripts/git/stash/stash-push-cli.ts +10 -0
  227. package/scripts/hooks/batch-guard.ts +40 -21
  228. package/scripts/hooks/edited-cspell.ts +37 -11
  229. package/scripts/hooks/format-edited-file.ts +22 -2
  230. package/scripts/hooks/lane-plan-guard.ts +50 -0
  231. package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
  232. package/scripts/hooks/pre-commit-lint.ts +14 -1
  233. package/scripts/hooks/pre-push-related-switch.ts +10 -0
  234. package/scripts/hooks/pre-push-unit.ts +76 -10
  235. package/scripts/hooks/pretool-guard.ts +2 -0
  236. package/scripts/hooks/reserved-run.ts +14 -1
  237. package/scripts/hooks/run-hook.sh +23 -8
  238. package/scripts/hooks/step-zero-notice.ts +6 -1
  239. package/scripts/hooks/stop-actions.ts +3 -15
  240. package/scripts/hooks/stop-guard.ts +7 -6
  241. package/scripts/init/distributed-paths.ts +1 -0
  242. package/scripts/init/hook-command-rewrite.ts +5 -1
  243. package/scripts/init/hook-launch.ts +4 -2
  244. package/scripts/issue/aggregation-split.ts +52 -0
  245. package/scripts/issue/defect-origin-line.ts +19 -1
  246. package/scripts/issue/defect-rate-cli.ts +5 -102
  247. package/scripts/issue/defect-report.ts +4 -4
  248. package/scripts/issue/effect-audit-cli.ts +178 -0
  249. package/scripts/issue/effect-audit.ts +185 -0
  250. package/scripts/issue/expected-effect-lint.ts +64 -9
  251. package/scripts/issue/git-next-issues.ts +5 -0
  252. package/scripts/issue/issue-body-or-comment.ts +38 -4
  253. package/scripts/issue/issue-cite-cli.ts +1 -3
  254. package/scripts/issue/issue-classification.ts +1 -0
  255. package/scripts/issue/issue-closing-pr.ts +8 -1
  256. package/scripts/issue/issue-evidence-exit.ts +4 -2
  257. package/scripts/issue/issue-file-cap.ts +58 -0
  258. package/scripts/issue/issue-file-cli.ts +111 -38
  259. package/scripts/issue/issue-file-deferral.ts +52 -0
  260. package/scripts/issue/issue-file-fold.ts +29 -10
  261. package/scripts/issue/issue-file-interrupt.ts +85 -0
  262. package/scripts/issue/issue-file-lane-hint.ts +30 -0
  263. package/scripts/issue/issue-file.ts +43 -6
  264. package/scripts/issue/issue-labels.ts +19 -2
  265. package/scripts/issue/issue-lint-cli.ts +27 -2
  266. package/scripts/issue/issue-measured-cli.ts +13 -35
  267. package/scripts/issue/issue-measured-close.ts +58 -0
  268. package/scripts/issue/issue-not-before-label.ts +2 -2
  269. package/scripts/issue/issue-not-before.ts +4 -1
  270. package/scripts/issue/issue-priority-cli.ts +60 -0
  271. package/scripts/issue/issue-priority-raise.ts +55 -0
  272. package/scripts/issue/issue-priority.ts +174 -43
  273. package/scripts/issue/issue-rank.ts +21 -4
  274. package/scripts/issue/issue-read-cli.ts +32 -6
  275. package/scripts/issue/issue-read.ts +37 -12
  276. package/scripts/issue/issue-sample-gate.ts +95 -74
  277. package/scripts/issue/issue-sample-prime.ts +127 -0
  278. package/scripts/issue/issue-sample-required.ts +57 -0
  279. package/scripts/issue/issue-sample-source.ts +12 -11
  280. package/scripts/issue/issue-search.ts +124 -0
  281. package/scripts/issue/issue-state.ts +13 -1
  282. package/scripts/issue/issue-template-section.ts +43 -0
  283. package/scripts/issue/issue-watch-diff.ts +31 -1
  284. package/scripts/issue/issue-watch-hook.ts +11 -2
  285. package/scripts/issue/issue-watch.ts +55 -12
  286. package/scripts/issue/markdown-section.ts +1 -0
  287. package/scripts/issue/measure-declaration.ts +121 -0
  288. package/scripts/issue/measure-rerun-cli.ts +7 -70
  289. package/scripts/issue/plan-consumers-section.ts +22 -1
  290. package/scripts/issue/reproduction-measure.ts +3 -1
  291. package/scripts/issue/size-estimate.ts +90 -0
  292. package/scripts/issue/trusted-measure.ts +84 -0
  293. package/scripts/josh/command-usage.ts +3 -2
  294. package/scripts/josh/durable-state-migrate.ts +105 -0
  295. package/scripts/josh/durable-state.ts +112 -0
  296. package/scripts/josh/josh-aliases.ts +95 -0
  297. package/scripts/josh/josh-command-map.ts +1 -82
  298. package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
  299. package/scripts/josh/josh-commands-ai.ts +5 -5
  300. package/scripts/josh/josh-commands-development.ts +59 -58
  301. package/scripts/josh/josh-commands-issue-write.ts +23 -4
  302. package/scripts/josh/josh-commands-issue.ts +32 -0
  303. package/scripts/josh/josh-commands-lane.ts +87 -4
  304. package/scripts/josh/josh-commands-lint.ts +16 -3
  305. package/scripts/josh/josh-commands-maintenance.ts +15 -0
  306. package/scripts/josh/josh-commands-review.ts +41 -6
  307. package/scripts/josh/josh-commands-ship.ts +56 -8
  308. package/scripts/josh/josh-commands-test-check.ts +80 -0
  309. package/scripts/josh/josh-commands-workflow.ts +1 -1
  310. package/scripts/josh/josh-environment-file.ts +43 -3
  311. package/scripts/josh/josh-in-process.ts +2 -2
  312. package/scripts/josh/josh-logic.ts +5 -3
  313. package/scripts/josh/josh-run.ts +19 -1
  314. package/scripts/josh/run-record-path.ts +15 -0
  315. package/scripts/josh/stamp-file.ts +11 -2
  316. package/scripts/lane/lane-adopt-cli.ts +98 -0
  317. package/scripts/lane/lane-adopt.ts +208 -0
  318. package/scripts/lane/lane-await.ts +5 -8
  319. package/scripts/lane/lane-baseline.ts +123 -0
  320. package/scripts/lane/lane-breakdown-cli.ts +64 -0
  321. package/scripts/lane/lane-breakdown-implement.ts +170 -0
  322. package/scripts/lane/lane-breakdown-laps.ts +107 -0
  323. package/scripts/lane/lane-breakdown-pinned.ts +76 -0
  324. package/scripts/lane/lane-breakdown-text.ts +145 -0
  325. package/scripts/lane/lane-breakdown.ts +239 -0
  326. package/scripts/lane/lane-check-stats.ts +29 -8
  327. package/scripts/lane/lane-child-invocation.ts +9 -2
  328. package/scripts/lane/lane-child-mark-keys.ts +12 -0
  329. package/scripts/lane/lane-child-marker.ts +20 -1
  330. package/scripts/lane/lane-ci-path-stats.ts +73 -0
  331. package/scripts/lane/lane-claim-stats.ts +84 -0
  332. package/scripts/lane/lane-close.ts +8 -3
  333. package/scripts/lane/lane-dispatch-log.ts +3 -3
  334. package/scripts/lane/lane-dispatch.ts +2 -2
  335. package/scripts/lane/lane-gap-stats.ts +7 -6
  336. package/scripts/lane/lane-guard-policy.ts +7 -1
  337. package/scripts/lane/lane-implement-stats.ts +207 -0
  338. package/scripts/lane/lane-implement-subagents.ts +90 -0
  339. package/scripts/lane/lane-investigation-switch.ts +16 -0
  340. package/scripts/lane/lane-ledger-kind.ts +31 -0
  341. package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
  342. package/scripts/lane/lane-ledger-schema.ts +119 -36
  343. package/scripts/lane/lane-ledger-write.ts +257 -0
  344. package/scripts/lane/lane-ledger.ts +31 -177
  345. package/scripts/lane/lane-load.ts +1 -1
  346. package/scripts/lane/lane-measure-cli.ts +176 -59
  347. package/scripts/lane/lane-net-read.ts +44 -0
  348. package/scripts/lane/lane-net-time.ts +212 -0
  349. package/scripts/lane/lane-open.ts +16 -7
  350. package/scripts/lane/lane-output.ts +2 -4
  351. package/scripts/lane/lane-overrun-prompt.ts +147 -0
  352. package/scripts/lane/lane-overrun.ts +274 -0
  353. package/scripts/lane/lane-paths.ts +24 -1
  354. package/scripts/lane/lane-pause-cli.ts +4 -1
  355. package/scripts/lane/lane-paused-spans.ts +97 -0
  356. package/scripts/lane/lane-plan-check.ts +207 -0
  357. package/scripts/lane/lane-plan-cli.ts +41 -0
  358. package/scripts/lane/lane-plan.ts +144 -0
  359. package/scripts/lane/lane-registry.ts +14 -1
  360. package/scripts/lane/lane-relaunch.ts +1 -1
  361. package/scripts/lane/lane-round-one-stats.ts +51 -0
  362. package/scripts/lane/lane-sampler.ts +23 -4
  363. package/scripts/lane/lane-session-action.ts +93 -18
  364. package/scripts/lane/lane-session-broker.ts +49 -21
  365. package/scripts/lane/lane-session-reread-main.ts +14 -0
  366. package/scripts/lane/lane-session-reread.ts +51 -0
  367. package/scripts/lane/lane-ship-lap-stats.ts +74 -0
  368. package/scripts/lane/lane-sleep.ts +58 -0
  369. package/scripts/lane/lane-spent.ts +1 -1
  370. package/scripts/lane/lane-split-stats.ts +28 -0
  371. package/scripts/lane/lane-stage-stats.ts +13 -1
  372. package/scripts/lane/lane-state.ts +41 -9
  373. package/scripts/lane/lane-stats-tables.ts +58 -0
  374. package/scripts/lane/lane-stats.ts +21 -5
  375. package/scripts/lane/lane-stop-stats.ts +51 -19
  376. package/scripts/lane/lane-tail-stats.ts +32 -0
  377. package/scripts/lane/lane-transcript-calls.ts +67 -10
  378. package/scripts/lane/lane-transcript-stats.ts +44 -12
  379. package/scripts/lane/lane-value-cell.ts +72 -0
  380. package/scripts/lane/lane-value.ts +118 -0
  381. package/scripts/lane/lane-withdraw-closed.ts +124 -0
  382. package/scripts/lane/lane-withdraw.ts +108 -31
  383. package/scripts/lane/lane-yield.ts +85 -0
  384. package/scripts/lane/openai-lane-ship.ts +12 -11
  385. package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
  386. package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
  387. package/scripts/lane/openai-lane-supervisor.ts +5 -4
  388. package/scripts/lib/poll.ts +38 -9
  389. package/scripts/lib/settled-together.ts +10 -0
  390. package/scripts/lib/shell-quote.ts +21 -0
  391. package/scripts/lib/token-shape.ts +111 -0
  392. package/scripts/lint/eslint-daemon-sources.ts +79 -0
  393. package/scripts/lint/eslint-daemon.ts +45 -6
  394. package/scripts/lint/eslint-warm-cli.ts +7 -0
  395. package/scripts/lint/eslint-warm.ts +66 -0
  396. package/scripts/lint/import-graph.ts +141 -11
  397. package/scripts/lint/lint-gate-scope.ts +2 -2
  398. package/scripts/lint/lint-parallel.ts +54 -6
  399. package/scripts/lint/lint-related.ts +154 -33
  400. package/scripts/lint/rename-cli.ts +179 -0
  401. package/scripts/lint/rename-identifier.ts +192 -0
  402. package/scripts/lint/type-only-imports.ts +58 -0
  403. package/scripts/notify/telegram-notify.ts +12 -3
  404. package/scripts/observations/observation-record.ts +42 -16
  405. package/scripts/observations/observations-flush.ts +32 -9
  406. package/scripts/overrides/overrides-check.ts +9 -1
  407. package/scripts/release/release-approval-prune.ts +7 -1
  408. package/scripts/repo/required-checks-logic.ts +4 -1
  409. package/scripts/repo/ruleset-check.ts +4 -3
  410. package/scripts/report/markdown-shape.ts +28 -0
  411. package/scripts/report/report-format-reference.ts +15 -1
  412. package/scripts/report/report-labels.ts +12 -1
  413. package/scripts/report/report-lint-child-summary.ts +94 -0
  414. package/scripts/report/report-lint-cli.ts +26 -7
  415. package/scripts/report/report-lint.ts +2 -20
  416. package/scripts/review/prose-stale-cli.ts +88 -0
  417. package/scripts/review/prose-stale-scan.ts +152 -0
  418. package/scripts/review/review-attest.ts +73 -23
  419. package/scripts/review/review-brief-cli.ts +68 -19
  420. package/scripts/review/review-brief-paths.ts +22 -0
  421. package/scripts/review/review-brief.ts +14 -7
  422. package/scripts/review/review-comment-carry.ts +47 -0
  423. package/scripts/review/review-comment-round.ts +85 -22
  424. package/scripts/review/review-finding-ledger.ts +109 -7
  425. package/scripts/review/review-finding-text.ts +43 -0
  426. package/scripts/review/review-interaction.ts +11 -0
  427. package/scripts/review/review-lane-handover.ts +68 -0
  428. package/scripts/review/review-lint-cli.ts +57 -0
  429. package/scripts/review/review-lint-findings.ts +92 -0
  430. package/scripts/review/review-lint-sections.ts +80 -0
  431. package/scripts/review/review-lint.ts +221 -0
  432. package/scripts/review/review-prior-findings.ts +102 -0
  433. package/scripts/review/review-readers-scan.ts +4 -2
  434. package/scripts/review/review-record-cli.ts +177 -54
  435. package/scripts/review/review-record-code-round.ts +55 -0
  436. package/scripts/review/review-record-comment.ts +60 -0
  437. package/scripts/review/review-record-interaction.ts +35 -0
  438. package/scripts/review/review-record-pinned.ts +108 -0
  439. package/scripts/review/review-record.ts +25 -1
  440. package/scripts/review/review-reviewed-tree.ts +307 -0
  441. package/scripts/review/review-round-one-closure.ts +62 -0
  442. package/scripts/review/review-round-reuse.ts +106 -0
  443. package/scripts/review/review-round2-cli.ts +91 -29
  444. package/scripts/review/review-round2-skip-comment.ts +55 -0
  445. package/scripts/review/review-round2.ts +24 -8
  446. package/scripts/review/review-stamps.ts +7 -3
  447. package/scripts/review/review-stop-log.ts +20 -6
  448. package/scripts/review/review-stops-cli.ts +2 -1
  449. package/scripts/review/review-submit-cli.ts +101 -0
  450. package/scripts/rules/agent-model.ts +1 -1
  451. package/scripts/rules/bash-triggers.ts +3 -3
  452. package/scripts/rules/concise-reply.ts +88 -0
  453. package/scripts/rules/credential-body.ts +77 -0
  454. package/scripts/rules/decision-oracle.ts +1 -1
  455. package/scripts/rules/delivered-rules.ts +36 -17
  456. package/scripts/rules/destructive-command.ts +3 -11
  457. package/scripts/rules/direct-issue-comment.ts +34 -12
  458. package/scripts/rules/direct-issue-read.ts +191 -0
  459. package/scripts/rules/direct-pr-create.ts +4 -24
  460. package/scripts/rules/early-heartbeat.ts +2 -0
  461. package/scripts/rules/edit-tool.ts +27 -0
  462. package/scripts/rules/file-edit-rows.ts +17 -0
  463. package/scripts/rules/file-rewrite.ts +146 -0
  464. package/scripts/rules/firing-point.ts +3 -2
  465. package/scripts/rules/gh-api.ts +128 -7
  466. package/scripts/rules/gh-repo-selector.ts +84 -0
  467. package/scripts/rules/git-force.ts +2 -2
  468. package/scripts/rules/guard-remedy.ts +14 -5
  469. package/scripts/rules/implementation-cut.ts +61 -28
  470. package/scripts/rules/investigator-foreground.ts +231 -0
  471. package/scripts/rules/issue-citation.ts +15 -60
  472. package/scripts/rules/issue-comments.ts +9 -4
  473. package/scripts/rules/josh-git-bare.ts +1 -1
  474. package/scripts/rules/lane-background.ts +41 -13
  475. package/scripts/rules/lane-direct-tool.ts +107 -9
  476. package/scripts/rules/lane-interactive-ask.ts +4 -1
  477. package/scripts/rules/lane-park.ts +4 -2
  478. package/scripts/rules/lane-spilled-read.ts +90 -0
  479. package/scripts/rules/lane-split-park.ts +1 -1
  480. package/scripts/rules/lane-switch-main.ts +4 -4
  481. package/scripts/rules/last-prompt.ts +20 -47
  482. package/scripts/rules/oracle-consulted.ts +1 -1
  483. package/scripts/rules/permission-guards.ts +5 -1
  484. package/scripts/rules/piped-verification-shapes.ts +110 -0
  485. package/scripts/rules/piped-verification.ts +67 -17
  486. package/scripts/rules/poll-loop.ts +72 -9
  487. package/scripts/rules/pr-merge.ts +5 -5
  488. package/scripts/rules/pre-gate-cut.ts +3 -3
  489. package/scripts/rules/protected-files.ts +88 -24
  490. package/scripts/rules/reply-language.ts +3 -17
  491. package/scripts/rules/reply-prose.ts +34 -0
  492. package/scripts/rules/repo-admin.ts +132 -0
  493. package/scripts/rules/reviewer-foreground.ts +88 -0
  494. package/scripts/rules/round-one-check-related.ts +120 -0
  495. package/scripts/rules/rule-body-guard.ts +5 -15
  496. package/scripts/rules/rule-value-cache.ts +53 -5
  497. package/scripts/rules/rule-value-candidates.ts +84 -0
  498. package/scripts/rules/rule-value-cli.ts +59 -11
  499. package/scripts/rules/rule-value.ts +17 -4
  500. package/scripts/rules/run-tail-rule.ts +1 -1
  501. package/scripts/rules/sed-in-place.ts +196 -0
  502. package/scripts/rules/shell-segments.ts +10 -2
  503. package/scripts/rules/stop-rule-rows.ts +1 -13
  504. package/scripts/rules/stop-rules.ts +33 -58
  505. package/scripts/rules/test-declared-commit.ts +1 -1
  506. package/scripts/rules/third-party-write.ts +110 -23
  507. package/scripts/rules/timed-rerun.ts +1 -1
  508. package/scripts/rules/turn-filings.ts +90 -0
  509. package/scripts/rules/worktree-guard.ts +22 -7
  510. package/scripts/run/board/run-board-ending-reason.ts +6 -2
  511. package/scripts/run/board/run-board-fit.ts +24 -1
  512. package/scripts/run/board/run-board-found.ts +134 -0
  513. package/scripts/run/board/run-board-header.ts +8 -0
  514. package/scripts/run/board/run-board-labels.ts +11 -1
  515. package/scripts/run/board/run-board-lane-time.ts +1 -0
  516. package/scripts/run/board/run-board-link.ts +15 -2
  517. package/scripts/run/board/run-board-notes.ts +7 -1
  518. package/scripts/run/board/run-board-operation.ts +4 -2
  519. package/scripts/run/board/run-board-phase.ts +2 -5
  520. package/scripts/run/board/run-board-plan.ts +1 -1
  521. package/scripts/run/board/run-board-read.ts +46 -1
  522. package/scripts/run/board/run-board-reason.ts +20 -8
  523. package/scripts/run/board/run-board-render-checks.ts +3 -2
  524. package/scripts/run/board/run-board-render-drawn.ts +11 -0
  525. package/scripts/run/board/run-board-render-found.ts +157 -0
  526. package/scripts/run/board/run-board-render-lead.ts +9 -0
  527. package/scripts/run/board/run-board-render-legend.ts +19 -0
  528. package/scripts/run/board/run-board-render-tail.ts +1 -1
  529. package/scripts/run/board/run-board-render.ts +82 -18
  530. package/scripts/run/board/run-board-spin.ts +1 -3
  531. package/scripts/run/board/run-board-status.ts +2 -0
  532. package/scripts/run/board/run-board-tick.ts +39 -10
  533. package/scripts/run/carry/run-carry-ended.ts +3 -2
  534. package/scripts/run/carry/run-carry.ts +3 -2
  535. package/scripts/run/cut/run-cut-cli.ts +33 -133
  536. package/scripts/run/cut/run-cut-digest.ts +152 -0
  537. package/scripts/run/cut/run-cut-handoff.ts +52 -8
  538. package/scripts/run/cut/run-cut-report.ts +24 -3
  539. package/scripts/run/cut/run-cut-resume.ts +129 -0
  540. package/scripts/run/cut/run-cut-review.ts +105 -0
  541. package/scripts/run/cut/run-cut.ts +18 -7
  542. package/scripts/run/detached-launch.ts +1 -1
  543. package/scripts/run/entry/run-entry-cli.ts +88 -19
  544. package/scripts/run/entry/run-entry-spill.ts +83 -0
  545. package/scripts/run/entry/run-entry-stop.ts +5 -1
  546. package/scripts/run/entry/run-entry-trust.ts +91 -0
  547. package/scripts/run/event/run-event-baseline.ts +56 -0
  548. package/scripts/run/event/run-event-filed.ts +9 -3
  549. package/scripts/run/event/run-event-overrun.ts +197 -0
  550. package/scripts/run/event/run-event-render.ts +4 -0
  551. package/scripts/run/event/run-event-stream.ts +25 -3
  552. package/scripts/run/hold/run-stop-notify.ts +3 -8
  553. package/scripts/run/merge/run-merge-cap.ts +57 -0
  554. package/scripts/run/merge/run-merge-cli.ts +66 -23
  555. package/scripts/run/merge/run-merge-outcome.ts +2 -0
  556. package/scripts/run/merge/run-merge-ship.ts +13 -3
  557. package/scripts/run/merge/run-merge-signals.ts +40 -23
  558. package/scripts/run/merge/run-merge-steps.ts +56 -36
  559. package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
  560. package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
  561. package/scripts/run/merge/run-merge.ts +41 -14
  562. package/scripts/run/review/run-review-cli.ts +306 -20
  563. package/scripts/run/review/run-review-early-push.ts +121 -0
  564. package/scripts/run/review/run-review-join-read.ts +94 -0
  565. package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
  566. package/scripts/run/review/run-review-pinned-join.ts +216 -0
  567. package/scripts/run/review/run-review-pinned-steps.ts +383 -0
  568. package/scripts/run/review/run-review-pinned-tree.ts +37 -0
  569. package/scripts/run/review/run-review-pinned.ts +53 -0
  570. package/scripts/run/review/run-review-steps.ts +70 -34
  571. package/scripts/run/review/run-review.ts +26 -6
  572. package/scripts/run/run-parent-cut-hook.ts +3 -4
  573. package/scripts/run/run-prep.ts +1 -0
  574. package/scripts/run/run-stage-read.ts +2 -6
  575. package/scripts/run/run-step-cli.ts +17 -5
  576. package/scripts/run/run-step-lane-plan.ts +27 -0
  577. package/scripts/run/run-step-section.ts +26 -7
  578. package/scripts/run/run-step.ts +5 -2
  579. package/scripts/run/ship/run-ship-args.ts +19 -0
  580. package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
  581. package/scripts/run/ship/run-ship-cli.ts +131 -39
  582. package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
  583. package/scripts/run/ship/run-ship-detach.ts +10 -4
  584. package/scripts/run/ship/run-ship-handover.ts +106 -0
  585. package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
  586. package/scripts/run/ship/run-ship-lap.ts +63 -0
  587. package/scripts/run/ship/run-ship-next.ts +27 -26
  588. package/scripts/run/ship/run-ship-overlap.ts +8 -3
  589. package/scripts/run/ship/run-ship-place.ts +9 -2
  590. package/scripts/run/ship/run-ship-planned.ts +92 -0
  591. package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
  592. package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
  593. package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
  594. package/scripts/run/ship/run-ship-preflight.ts +16 -4
  595. package/scripts/run/ship/run-ship-probe.ts +23 -9
  596. package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
  597. package/scripts/run/ship/run-ship-relaunch.ts +51 -0
  598. package/scripts/run/ship/run-ship-return.ts +103 -29
  599. package/scripts/run/ship/run-ship-review-reason.ts +24 -0
  600. package/scripts/run/ship/run-ship-review-steps.ts +230 -59
  601. package/scripts/run/ship/run-ship-review.ts +171 -51
  602. package/scripts/run/ship/run-ship-reviewer.ts +138 -42
  603. package/scripts/run/ship/run-ship-scoped.ts +39 -10
  604. package/scripts/run/ship/run-ship-stage.ts +49 -13
  605. package/scripts/run/ship/run-ship-steps.ts +24 -4
  606. package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
  607. package/scripts/run/ship/run-ship-stop-context.ts +50 -13
  608. package/scripts/run/ship/run-ship-sync.ts +171 -30
  609. package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
  610. package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
  611. package/scripts/run/ship/run-ship-waiter.ts +114 -0
  612. package/scripts/run/ship/run-ship.ts +16 -2
  613. package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
  614. package/scripts/run/wake/run-wake-cli.ts +6 -113
  615. package/scripts/run/wake/run-wake-code.ts +53 -11
  616. package/scripts/run/wake/run-wake-driver.ts +5 -3
  617. package/scripts/run/wake/run-wake-finish.ts +137 -0
  618. package/scripts/run/wake/run-wake-loop.ts +5 -3
  619. package/scripts/run/wake/run-wake-ports.ts +11 -3
  620. package/scripts/run/wake/run-wake-session.ts +2 -0
  621. package/scripts/run/wake/run-wake.ts +3 -2
  622. package/scripts/safe-chain/ci-installer-pin.ts +49 -8
  623. package/scripts/safe-chain/project-config.ts +3 -2
  624. package/scripts/security/secretlint-scan.ts +42 -9
  625. package/scripts/security/security-audit-provision-main.ts +9 -1
  626. package/scripts/security/security-audit-provision.ts +1 -1
  627. package/scripts/security/security-audit.ts +21 -1
  628. package/scripts/security/sonar-file.ts +10 -5
  629. package/scripts/split/split-assess.ts +12 -3
  630. package/scripts/split/split-early-notice.ts +116 -0
  631. package/scripts/split/split-measure.ts +20 -2
  632. package/scripts/split/split-resolution.ts +107 -0
  633. package/scripts/test/direct-importers.ts +185 -0
  634. package/scripts/test/pure-files-entries.ts +83 -0
  635. package/scripts/test/related-heavy-tests.ts +81 -0
  636. package/scripts/test/test-no-base.ts +88 -0
  637. package/scripts/test/test-pinned-cache-logic.ts +363 -0
  638. package/scripts/test/test-pinned-cache.ts +337 -0
  639. package/scripts/test/test-pinned-emit.ts +49 -0
  640. package/scripts/test/test-pinned-functions.ts +116 -0
  641. package/scripts/test/test-pinned-ledger.ts +80 -0
  642. package/scripts/test/test-pinned-logic.ts +208 -20
  643. package/scripts/test/test-pinned-main.ts +84 -18
  644. package/scripts/test/test-pinned-pool.ts +73 -0
  645. package/scripts/test/test-pinned-probe.ts +254 -0
  646. package/scripts/test/test-pinned-prune-logic.ts +118 -0
  647. package/scripts/test/test-pinned-reach.ts +194 -0
  648. package/scripts/test/test-pinned-record.ts +196 -0
  649. package/scripts/test/test-pinned-rewire.ts +148 -0
  650. package/scripts/test/test-pinned-spawn.ts +81 -0
  651. package/scripts/test/test-pinned-stage.ts +70 -0
  652. package/scripts/test/test-pinned.ts +258 -47
  653. package/scripts/test/test-reach-cli.ts +61 -0
  654. package/scripts/test/test-read-map.ts +35 -11
  655. package/scripts/test/test-read-recording.ts +17 -5
  656. package/scripts/test/test-read-trace.ts +26 -8
  657. package/scripts/test/test-red-logic.ts +46 -7
  658. package/scripts/test/test-red.ts +34 -14
  659. package/scripts/test/test-related-claim.ts +37 -0
  660. package/scripts/test/test-related-main.ts +4 -1
  661. package/scripts/test/test-related-moved.ts +91 -0
  662. package/scripts/test/test-related-record.ts +43 -23
  663. package/scripts/test/test-related-scope.ts +99 -34
  664. package/scripts/test/test-related-synced.ts +135 -0
  665. package/scripts/test/test-related-touched.ts +84 -0
  666. package/scripts/test/test-related.ts +167 -83
  667. package/scripts/test/test-unit-guard.ts +28 -5
  668. package/scripts/test/unit-durations.ts +41 -0
  669. package/scripts/test/unit-worker-share.ts +5 -4
  670. package/scripts/test/vitest-cache-directory.ts +19 -0
  671. package/scripts/test/vitest-cli-excludes.ts +14 -0
  672. package/scripts/test/vitest-failure-summary.ts +111 -0
  673. package/scripts/test/whole-suite-files.ts +12 -1
  674. package/scripts/time-runtime/time-batch-guard.ts +42 -4
  675. package/scripts/time-runtime/time-bundle-call.ts +1 -1
  676. package/scripts/time-runtime/time-bundles.ts +36 -5
  677. package/scripts/time-runtime/time-markers.ts +2 -2
  678. package/scripts/time-runtime/time-search-call.ts +38 -0
  679. package/scripts/time-runtime/time-shell.ts +1 -1
  680. package/scripts/time-runtime/time-transcript-line.ts +17 -5
  681. package/scripts/version/development-engines-verdict.ts +124 -0
  682. package/scripts/version/latest-corepack.ts +2 -0
  683. package/templates/gitignore +2 -0
  684. package/templates/workflows/ci.yml +41 -0
  685. package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
  686. package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
  687. package/dist/hooks/chunk-TUIFS5E7.js +0 -72
  688. package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
  689. package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
  690. package/scripts/rules/filing-cap.ts +0 -139
@@ -1,3 +1,4 @@
1
+ import node_path from 'node:path'
1
2
  import { issue_bug_label } from '#scripts/issue/issue-bug-label'
2
3
  import { json_value } from '#scripts/lib/json-value'
3
4
  import { observation_ledger } from '#scripts/observations/observation-ledger'
@@ -11,7 +12,15 @@ import { test_declared_logic } from './test-declared-logic'
11
12
  // that test catches anything — the added and changed tests run against the merge-base, and at least one
12
13
  // of them has to fail there.
13
14
 
14
- type RedVerdict = 'red' | 'green' | 'no-test' | 'test-only'
15
+ type RedVerdict = 'red' | 'green' | 'no-test' | 'stopped' | 'test-only'
16
+
17
+ // One run's verdict and the test files that failed in it. `ran` is the number of test files the run
18
+ // ran, absent on a verdict read back from a cache (joshuafolkken/kit#5078).
19
+ interface RedProbe {
20
+ verdict: RedVerdict
21
+ failed: ReadonlyArray<string>
22
+ ran?: number
23
+ }
15
24
 
16
25
  // The declaration a bug-fix Issue carries under its background heading, in the same slot as the
17
26
  // behavior-change declaration (`behavior-change-lint.ts`). Read from the declaration, never inferred,
@@ -55,23 +64,53 @@ function ran_file_count(report: string): number {
55
64
  return json_value.parse_with(report, REPORT_SCHEMA)?.testResults.length ?? 0
56
65
  }
57
66
 
58
- // `no-test` when nothing ran; otherwise a failing run is `red` — the test caught the pre-fix tree — and
59
- // a passing one is `green`.
67
+ // The test files a run failed in, as `josh test:pinned` stores them beside a `red` verdict
68
+ // (joshuafolkken/kit#4790). Vitest names each by its absolute path, under the tree's own path or its real
69
+ // one — a macOS temporary directory sits behind `/var` → `/private/var` — so each is read relative to the
70
+ // first of `roots` it sits under. An unreadable report fails none.
71
+ const RESULT_SCHEMA = z.object({ name: z.string(), status: z.string() })
72
+ const RESULTS_SCHEMA = z.object({ testResults: z.array(RESULT_SCHEMA) })
73
+ const FAILED_STATUS = 'failed'
74
+ const PARENT_PREFIX = '..'
75
+
76
+ function is_inside(name: string): boolean {
77
+ return !name.startsWith(PARENT_PREFIX) && !node_path.isAbsolute(name)
78
+ }
79
+
80
+ function relative_in(roots: ReadonlyArray<string>, file: string): Array<string> {
81
+ const relatives = roots.map((root) => node_path.relative(root, file))
82
+
83
+ return relatives.filter((name) => is_inside(name)).slice(0, 1)
84
+ }
85
+
86
+ function failed_files(report: string, roots: ReadonlyArray<string>): Array<string> {
87
+ const results = json_value.parse_with(report, RESULTS_SCHEMA)?.testResults ?? []
88
+
89
+ return results
90
+ .filter((result) => result.status === FAILED_STATUS)
91
+ .flatMap((result) => relative_in(roots, result.name))
92
+ }
93
+
94
+ // `no-test` when nothing ran and vitest passed with no tests; `stopped` when nothing ran and it failed
95
+ // anyway — its config could not load, so no test was ever asked (joshuafolkken/kit#5043). Otherwise a
96
+ // failing run is `red` — the test caught the pre-fix tree — and a passing one is `green`.
60
97
  function verdict_for(test_count: number, is_failed: boolean): RedVerdict {
61
- if (test_count === 0) return 'no-test'
98
+ if (test_count === 0) return is_failed ? 'stopped' : 'no-test'
62
99
 
63
100
  return is_failed ? 'red' : 'green'
64
101
  }
65
102
 
66
103
  // Only `green` on a declared bug fix is refused. `no-test` is already `josh test:declared`'s refusal
67
- // when a runtime file changed, a declared fix that touched only docs has nothing to reproduce, and a
68
- // `test-only` fix runs the same code on the merge-base as on HEAD.
104
+ // when a runtime file changed, a declared fix that touched only docs has nothing to reproduce, a
105
+ // `stopped` run asked no test, so it is neither red evidence nor green, and a `test-only` fix runs the
106
+ // same code on the merge-base as on HEAD.
69
107
  function is_refused(body: string, verdict: RedVerdict): boolean {
70
108
  return verdict === 'green' && is_bug_fix(body)
71
109
  }
72
110
 
73
111
  const test_red_logic = {
74
112
  BUG_DECLARATION_LINE,
113
+ failed_files,
75
114
  is_bug_fix,
76
115
  is_refused,
77
116
  is_test_only,
@@ -80,5 +119,5 @@ const test_red_logic = {
80
119
  verdict_for,
81
120
  }
82
121
 
83
- export type { RedVerdict }
122
+ export type { RedProbe, RedVerdict }
84
123
  export { test_red_logic }
@@ -1,15 +1,16 @@
1
1
  import { existsSync } from 'node:fs'
2
- import { readFile, rm } from 'node:fs/promises'
2
+ import { readFile, realpath, rm } from 'node:fs/promises'
3
3
  import path from 'node:path'
4
4
  import { base_tree, type BaseTree } from '#scripts/git/base-tree'
5
5
  import { change_base } from '#scripts/git/change-base'
6
6
  import { changed_paths } from '#scripts/git/changed-paths'
7
7
  import { git_location_environment } from '#scripts/git/git-location-environment'
8
8
  import { execa } from 'execa'
9
- import { test_red_logic, type RedVerdict } from './test-red-logic'
9
+ import { test_red_logic, type RedProbe, type RedVerdict } from './test-red-logic'
10
+ import { vitest_cache_directory } from './vitest-cache-directory'
10
11
 
11
12
  // `josh test:red` — run the added and changed Vitest files against the pre-fix tree and print `red`,
12
- // `green`, `no-test` or `test-only`.
13
+ // `green`, `no-test`, `stopped` or `test-only`.
13
14
  //
14
15
  // **The pre-fix tree is a detached worktree at the merge-base, never the caller's checkout**
15
16
  // (`base-tree.ts`). The tests are copied in from the working tree, so what runs is the new test
@@ -17,9 +18,12 @@ import { test_red_logic, type RedVerdict } from './test-red-logic'
17
18
 
18
19
  const TREE_PREFIX = 'josh-test-red-'
19
20
  const REPORT_NAME = 'report.json'
21
+ // Beside the tree, so the run's dependency optimizer never rewrites the borrowed `node_modules/.vite`
22
+ // a gate beside it imports from (`vitest-cache-directory.ts`).
23
+ const CACHE_NAME = 'vite-cache'
20
24
  const VITEST_BIN = path.join(base_tree.NODE_MODULES, '.bin', 'vitest')
21
25
  const USAGE =
22
- 'Usage: josh test:red — prints red / green / no-test / test-only for the changed tests on the merge-base'
26
+ 'Usage: josh test:red — prints red / green / no-test / stopped / test-only for the changed tests on the merge-base'
23
27
 
24
28
  interface RedRun {
25
29
  verdict: RedVerdict
@@ -45,32 +49,43 @@ async function read_report(report: string): Promise<string> {
45
49
  // `josh test:pinned`. `--passWithNoTests` keeps "the filter matched nothing" from reading as a
46
50
  // failure, and the JSON report — written beside the tree, never into it — says whether anything ran at
47
51
  // all, so a file the old config excludes is `no-test` rather than a `green` that refuses a correct fix.
48
- // A test that ran and broke, or a file that could not load against the old code, makes it `red`. The
49
- // report is removed first, so a run that writes none never reads the one before it.
50
- async function verdict_in(
52
+ // A test that ran and broke, or a file that could not load against the old code, makes it `red`, and
53
+ // the files it broke in come back beside the verdict. The report is removed first, so a run that writes
54
+ // none never reads the one before it.
55
+ async function probe_in(
51
56
  { parent, tree }: BaseTree,
52
57
  selection: ReadonlyArray<string>,
53
- ): Promise<RedVerdict> {
58
+ ): Promise<RedProbe> {
54
59
  const report = path.join(parent, REPORT_NAME)
55
60
  const vitest_args = [...selection, '--passWithNoTests', ...reporter_arguments(report)]
56
61
 
57
62
  await rm(report, { force: true })
58
63
  const result = await execa(path.join(tree, VITEST_BIN), vitest_args, {
59
64
  cwd: tree,
60
- env: git_location_environment.location_free_environment(),
65
+ env: {
66
+ ...git_location_environment.location_free_environment(),
67
+ [vitest_cache_directory.CACHE_DIRECTORY_KEY]: path.join(parent, CACHE_NAME),
68
+ },
61
69
  extendEnv: true,
62
70
  reject: false,
63
71
  })
64
- const ran = test_red_logic.ran_file_count(await read_report(report))
72
+ const text = await read_report(report)
73
+ const ran = test_red_logic.ran_file_count(text)
65
74
 
66
- return test_red_logic.verdict_for(ran, result.exitCode !== 0)
75
+ return {
76
+ verdict: test_red_logic.verdict_for(ran, result.exitCode !== 0),
77
+ failed: test_red_logic.failed_files(text, [tree, await realpath(tree)]),
78
+ ran,
79
+ }
67
80
  }
68
81
 
69
82
  async function verdict_on(base: string, files: ReadonlyArray<string>): Promise<RedVerdict> {
70
83
  return await base_tree.with_tree(TREE_PREFIX, base, async (pre_fix) => {
71
84
  await base_tree.copy_in(pre_fix.tree, files)
72
85
 
73
- return await verdict_in(pre_fix, ['run', ...files])
86
+ const probe = await probe_in(pre_fix, ['run', ...files])
87
+
88
+ return probe.verdict
74
89
  })
75
90
  }
76
91
 
@@ -78,7 +93,7 @@ async function verdict_on(base: string, files: ReadonlyArray<string>): Promise<R
78
93
  // `no-test` — there is no pre-fix tree to run against, and a guard fails open. A change whose every path
79
94
  // is a test file is `test-only` without a run: the merge-base runs the same code as HEAD.
80
95
  async function run(): Promise<RedRun> {
81
- const base = await change_base.resolved()
96
+ const base = await change_base.resolved_through_merge()
82
97
  const paths = await changed_paths.read_changed_paths(false)
83
98
  const files = changed_tests(paths)
84
99
 
@@ -103,7 +118,12 @@ async function main(argv: ReadonlyArray<string>): Promise<number> {
103
118
  return 0
104
119
  }
105
120
 
106
- const test_red = { main, run, verdict_in }
121
+ // Whether the checkout has the Vitest `probe_in` runs; without it every run would read `no-test`.
122
+ function has_runner(): boolean {
123
+ return existsSync(VITEST_BIN)
124
+ }
125
+
126
+ const test_red = { has_runner, main, probe_in, run }
107
127
 
108
128
  export type { RedRun }
109
129
  export { test_red }
@@ -0,0 +1,37 @@
1
+ import { core_budget } from '#scripts/gate/core-budget'
2
+ import { gate_plan } from '#scripts/gate/gate-plan'
3
+ import { test_pinned_reach } from './test-pinned-reach'
4
+ import { related_scope } from './test-related-scope'
5
+
6
+ // The cores a `josh test:related` vitest pass claims once its files are known (joshuafolkken/kit#5135):
7
+ // a narrowed pass by the test files its imports reach — not by its own files, one of which may reach
8
+ // hundreds — and the whole suite (`undefined`), or files no graph can be built for, by the full width
9
+ // a direct unit run holds.
10
+ async function claim_weight(files: ReadonlyArray<string> | undefined): Promise<number> {
11
+ const tests = files === undefined ? undefined : await test_pinned_reach.reached_test_count(files)
12
+
13
+ return tests === undefined ? gate_plan.direct_unit_weight() : gate_plan.scoped_unit_weight(tests)
14
+ }
15
+
16
+ // **Each vitest pass takes its claim here, not on the command entry**: the entry is reserved before
17
+ // the scope resolves, so it could only ever claim the whole width. `vitest_share` reads this claim
18
+ // back as the `--maxWorkers` bound. Under `josh gate` the gate's claim covers the run, so none is
19
+ // sized.
20
+ async function with_unit_claim(
21
+ files: ReadonlyArray<string> | undefined,
22
+ run: () => Promise<number>,
23
+ ): Promise<number> {
24
+ if (core_budget.is_covered()) return await run()
25
+
26
+ const weight = await claim_weight(files)
27
+
28
+ return await core_budget.with_command_reservation(weight, run, {
29
+ memory_mb: gate_plan.unit_memory(weight),
30
+ command: related_scope.COMMAND_NAME,
31
+ is_unit: true,
32
+ })
33
+ }
34
+
35
+ const test_related_claim = { with_unit_claim }
36
+
37
+ export { test_related_claim }
@@ -2,17 +2,20 @@
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { changed_file_scope } from '#scripts/git/changed-file-scope'
4
4
  import { run_ship_removed_rows } from '#scripts/run/ship/run-ship-removed-rows'
5
+ import { split_early_notice } from '#scripts/split/split-early-notice'
5
6
  import { test_related } from './test-related'
6
7
 
7
8
  // The `josh test:related` entry, kept apart from `test-related.ts` because `check-inputs.ts` imports
8
9
  // that one: a bundle is one file, so a main guard there would fire for every command that carries it
9
10
  // (joshuafolkken/kit#4186). A green run then shows the tests the change removed, the one place a run
10
- // meets them before `josh ship` (joshuafolkken/kit#4563).
11
+ // meets them before `josh ship` (joshuafolkken/kit#4563), and any run shows the split notice once per
12
+ // Issue when the diff has outgrown the guide (joshuafolkken/kit#4642).
11
13
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
12
14
  const exit_code = await test_related.run_related_tests(
13
15
  process.argv.slice(changed_file_scope.ARGV_START),
14
16
  )
15
17
 
16
18
  if (exit_code === 0) await run_ship_removed_rows.surface()
19
+ await split_early_notice.surface()
17
20
  process.exitCode = exit_code
18
21
  }
@@ -0,0 +1,91 @@
1
+ import type { MovedParts } from '#scripts/gate/moved-paths'
2
+ import { test_declared_logic } from './test-declared-logic'
3
+ import type { ReadMap } from './test-read-map'
4
+ import { related_scope, type ScopeRequest } from './test-related-scope'
5
+ import { test_related_synced, type SyncedSplit } from './test-related-synced'
6
+ import { whole_suite_files } from './whole-suite-files'
7
+
8
+ // How `josh test:related` reads what moved since its last green run (`since-green.ts`) into the change
9
+ // it narrows by — split out of `test-related.ts`, which runs the reading.
10
+
11
+ // The change a narrowing reads, and the map it reads it against. `is_unmoved` is the since-green
12
+ // reading's positive fact that nothing moved since this command was last green on this checkout.
13
+ // `synced` is the part of the change a main sync brought in, kept for the run's ledger record, and
14
+ // `since_map` the part the change since the map's tree joined to what this change moved. `branch` is
15
+ // this branch's own change from its merge base, where it was read.
16
+ type ChangeReading = Pick<ScopeRequest, 'changed' | 'map' | 'since_map'> & {
17
+ is_unmoved?: true
18
+ synced?: ReadonlyArray<string>
19
+ branch?: ReadonlyArray<string> | undefined
20
+ }
21
+
22
+ function is_whole_suite(file: string): boolean {
23
+ return whole_suite_files.WHOLE_SUITE_FILES.has(file)
24
+ }
25
+
26
+ // **A non-code file a main sync brought in is not this branch's change** (joshuafolkken/kit#4572), so it
27
+ // joins `since_map`: it neither adds the tests reading it nor sends the run to the whole suite — main's
28
+ // CI verified it. So does a synced file every test depends on, which the split cannot narrow
29
+ // (joshuafolkken/kit#4993): main's CI ran the whole suite on it, and this branch's own tests run on it
30
+ // anyway. Any other synced module is `test-related-synced.ts`'s: only this branch's change runs for it,
31
+ // where the two meet. A branch change git cannot read marks nothing.
32
+ function synced_data(
33
+ synced: ReadonlyArray<string>,
34
+ branch: ReadonlyArray<string> | undefined,
35
+ ): ReadonlyArray<string> {
36
+ const data = synced.filter((file) => !related_scope.is_relatable(file) || is_whole_suite(file))
37
+
38
+ return data.filter((file) => !(branch ?? data).includes(file))
39
+ }
40
+
41
+ // **The branch's own test files stay out of `since_map`** (joshuafolkken/kit#4393), so each runs again
42
+ // on every bare run after a green one — the map holds no entry for a read one started since its tree.
43
+ // Only main's and another lane's test files are left to CI (joshuafolkken/kit#4896). A branch change git
44
+ // cannot read keeps every test file.
45
+ function without_own_tests(
46
+ since_map: ReadonlyArray<string>,
47
+ branch: ReadonlyArray<string> | undefined,
48
+ ): ReadonlyArray<string> {
49
+ return since_map.filter(
50
+ (file) => !test_declared_logic.is_test_file(file) || branch?.includes(file) === false,
51
+ )
52
+ }
53
+
54
+ // The moved files handed on as explicit arguments, the synced modules the split left out taken away.
55
+ // Where one meets this branch's change, the change runs in its place (`test-related-synced.ts`) — named
56
+ // even when only the sync moved, since a green branch side would otherwise run nothing.
57
+ function narrowed_moved(
58
+ moved: ReadonlyArray<string>,
59
+ split: SyncedSplit,
60
+ branch: ReadonlyArray<string> | undefined,
61
+ map: ReadMap | undefined,
62
+ ): ReadonlyArray<string> {
63
+ const kept = moved.filter((file) => !split.left.includes(file))
64
+ const own = split.shared.length === 0 ? [] : test_related_synced.own_of(branch, map)
65
+
66
+ return [...new Set([...kept, ...(own ?? [])])]
67
+ }
68
+
69
+ // The reading's `since_map`: what this branch did not change. The synced modules left out join it and
70
+ // the change, so they settle as reaching no test rather than leaving an empty selection that runs the
71
+ // whole suite.
72
+ function moved_reading(
73
+ change: ChangeReading,
74
+ parts: MovedParts,
75
+ branch: ReadonlyArray<string> | undefined,
76
+ split: SyncedSplit,
77
+ ): ChangeReading {
78
+ const since_map = [
79
+ ...without_own_tests(change.since_map ?? [], branch),
80
+ ...synced_data(parts.synced, branch),
81
+ ...split.left,
82
+ ]
83
+ const changed = [...new Set([...(change.changed ?? []), ...split.left])]
84
+
85
+ return { ...change, changed, since_map: [...new Set(since_map)], synced: parts.synced, branch }
86
+ }
87
+
88
+ const test_related_moved = { is_whole_suite, moved_reading, narrowed_moved }
89
+
90
+ export type { ChangeReading }
91
+ export { test_related_moved }
@@ -1,7 +1,8 @@
1
1
  import { mkdtempSync, rmSync } from 'node:fs'
2
2
  import { tmpdir } from 'node:os'
3
3
  import path from 'node:path'
4
- import { lane_ledger, type TestRelatedRecord } from '#scripts/lane/lane-ledger'
4
+ import type { TestRelatedRecord } from '#scripts/lane/lane-ledger-schema'
5
+ import { lane_ledger_write } from '#scripts/lane/lane-ledger-write'
5
6
  import { related_scope, type RelatedScope } from './test-related-scope'
6
7
  import { unit_count_file } from './unit-count-file'
7
8
 
@@ -21,9 +22,13 @@ interface RunInput {
21
22
  // The part of `changed` a main sync brought in, empty outside a since-green reading.
22
23
  synced: ReadonlyArray<string>
23
24
  // The part of `changed` the change since the test-read map's tree joined to the named or moved
24
- // files — main merges that landed after the map among them — never the run's own change. It holds
25
- // the synced non-code files as well, which the record counts as `synced` alone.
25
+ // files — main merges that landed after the map among them. A file of `branch` in it counts as
26
+ // `changed`; it holds the synced non-code files as well, which the record counts as `synced` alone.
26
27
  since_map: ReadonlyArray<string>
28
+ // This branch's own change from its merge base, where it was read.
29
+ branch?: ReadonlyArray<string> | undefined
30
+ // The name the run is recorded under when it is not the scope's own — `touched` for a `--touched` run.
31
+ kind?: string
27
32
  }
28
33
 
29
34
  interface RunResult {
@@ -69,15 +74,11 @@ async function with_test_count(
69
74
  }
70
75
  }
71
76
 
72
- // The scope's files the change did not name — the map's readers and the code readers it added.
73
- function readers_of(input: RunInput, changed: ReadonlySet<string>): number {
77
+ // The scope's files the record counted in no part — the map's readers.
78
+ function readers_of(input: RunInput, counted: ReadonlySet<string>): number {
74
79
  if (input.scope.mode !== 'related') return 0
75
80
 
76
- return input.scope.files.filter((file) => !changed.has(path.relative(input.root, file))).length
77
- }
78
-
79
- function part_of(part: ReadonlyArray<string>, changed: ReadonlySet<string>): number {
80
- return part.filter((file) => changed.has(file)).length
81
+ return input.scope.files.filter((file) => !counted.has(path.relative(input.root, file))).length
81
82
  }
82
83
 
83
84
  // The changed files that sent a full-suite run there, repository-root-relative, or none.
@@ -87,20 +88,39 @@ function triggers_of(input: RunInput): Partial<TestRelatedRecord> {
87
88
  return { trigger_files: input.scope.files.map((file) => path.relative(input.root, file)) }
88
89
  }
89
90
 
91
+ // **The run's own change is the branch's, where it was read** (joshuafolkken/kit#5041): a synced file
92
+ // the split cannot vouch for is in `changed` without being this branch's change. Unread, it is what
93
+ // neither a main sync nor the map's tree joined.
94
+ function own_of(input: RunInput): ReadonlyArray<string> {
95
+ const { changed = [], branch } = input
96
+ const joined = new Set([...input.synced, ...input.since_map])
97
+
98
+ return changed.filter((file) => branch?.includes(file) ?? !joined.has(file))
99
+ }
100
+
101
+ // The input split into its counted parts, each file in one. A synced non-code file is in `since_map`
102
+ // too (`synced_data` in `test-related.ts`), counted as synced alone.
103
+ function parts_of(input: RunInput): Record<'own' | 'synced' | 'since_map', ReadonlyArray<string>> {
104
+ const own = own_of(input)
105
+ const rest = (input.changed ?? []).filter((file) => !own.includes(file))
106
+
107
+ return {
108
+ own,
109
+ synced: rest.filter((file) => input.synced.includes(file)),
110
+ since_map: rest.filter(
111
+ (file) => input.since_map.includes(file) && !input.synced.includes(file),
112
+ ),
113
+ }
114
+ }
115
+
90
116
  function record_of(input: RunInput, result: RunResult): TestRelatedRecord {
91
- const changed = new Set(input.changed)
92
- const synced = part_of(input.synced, changed)
93
- // A synced non-code file is in `since_map` too (`synced_data` in `test-related.ts`), counted once.
94
- const since_map = part_of(
95
- input.since_map.filter((file) => !input.synced.includes(file)),
96
- changed,
97
- )
117
+ const { own, synced, since_map } = parts_of(input)
98
118
  const record = {
99
- scope: related_scope.scope_kind(input.scope),
100
- changed: changed.size - synced - since_map,
101
- synced,
102
- since_map,
103
- readers: readers_of(input, changed),
119
+ scope: input.kind ?? related_scope.scope_kind(input.scope),
120
+ changed: own.length,
121
+ synced: synced.length,
122
+ since_map: since_map.length,
123
+ readers: readers_of(input, new Set([...own, ...synced, ...since_map])),
104
124
  ...triggers_of(input),
105
125
  elapsed_ms: Math.round(result.elapsed_ms),
106
126
  }
@@ -110,7 +130,7 @@ function record_of(input: RunInput, result: RunResult): TestRelatedRecord {
110
130
 
111
131
  // Best-effort, as every ledger write is.
112
132
  async function record_run(input: RunInput, result: RunResult, ledger?: string): Promise<void> {
113
- await lane_ledger.record_test_related(record_of(input, result), ledger)
133
+ await lane_ledger_write.record_test_related(record_of(input, result), ledger)
114
134
  }
115
135
 
116
136
  const test_related_record = { record_of, record_run, with_test_count }