@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
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { lane_plan_check } from './lane-plan-check'
4
+
5
+ // `josh lane:plan <issue> <path>... [--probe]` — the command line over `lane-plan-check.ts`, which holds
6
+ // the check and the yield so `run:entry` can import them without this entry's main guard.
7
+
8
+ const ARGV_OFFSET = 2
9
+ const FAILURE_EXIT_CODE = 1
10
+ const PROBE_FLAG = '--probe'
11
+ const USAGE = 'Usage: josh lane:plan <issue-number> <path> [<path> ...] [--probe]'
12
+ const { YIELD_EXIT_CODE } = lane_plan_check
13
+
14
+ async function run(
15
+ argv: ReadonlyArray<string>,
16
+ directory: string = process.cwd(),
17
+ ): Promise<number> {
18
+ const plan = lane_plan_check.plan_of(
19
+ argv.filter((token) => token !== PROBE_FLAG),
20
+ new Date(),
21
+ )
22
+ const action = argv.includes(PROBE_FLAG)
23
+ ? lane_plan_check.probe_answer
24
+ : lane_plan_check.check_plan
25
+
26
+ if (plan !== undefined) return await action(lane_plan_check.placed(plan, directory), directory)
27
+
28
+ console.error(USAGE)
29
+
30
+ return FAILURE_EXIT_CODE
31
+ }
32
+
33
+ async function main(argv: ReadonlyArray<string>): Promise<void> {
34
+ process.exitCode = await run(argv)
35
+ }
36
+
37
+ const lane_plan_cli = { USAGE, YIELD_EXIT_CODE, run }
38
+
39
+ if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
40
+
41
+ export { lane_plan_cli }
@@ -0,0 +1,144 @@
1
+ import { backlog_overlap, type Clash, type Declared } from '#scripts/backlog/backlog-overlap'
2
+ import { git_common_directory } from '#scripts/git/git-common-directory'
3
+ import { durable_state } from '#scripts/josh/durable-state'
4
+ import { stamp_file } from '#scripts/josh/stamp-file'
5
+ import { json_value } from '#scripts/lib/json-value'
6
+ import { z } from 'zod'
7
+
8
+ // The files a lane child plans to edit, recorded by `josh lane:plan` once its work summary settles.
9
+ //
10
+ // **An issue body names the paths its reporter saw, not the ones the change touches.**
11
+ // joshuafolkken/kit#4858 and joshuafolkken/kit#4859 declared disjoint paths, ran side by side, and both
12
+ // edited `scripts/lane/lane-overrun.ts`; the second ship stopped on the conflict (joshuafolkken/kit#4864).
13
+ // The plan is the first moment the touched files are known, so it is recorded here and read as the
14
+ // declaration in place of the body — by `lane:plan` to hold the later lane back, and by `backlog:next`.
15
+ //
16
+ // **Keyed to the repository and the issue, not the work tree**, and kept in the common git directory
17
+ // (`durable-state.ts`): the lane records it from its own work tree and the parent reads it from the main
18
+ // checkout, both resolve the same directory, and a reboot does not drop a running lane's plan.
19
+ // `lane:close` releases it with the lane (`release`).
20
+
21
+ const lane_plan_schema = z.object({
22
+ issue: z.number(),
23
+ paths: z.array(z.string()),
24
+ planned_at: z.string(),
25
+ cleared: z.boolean().optional(),
26
+ // The lane gave its lane back on this plan (`lane-yield.ts`), so the plan outlives the lane.
27
+ yielded: z.boolean().optional(),
28
+ })
29
+
30
+ type LanePlan = z.infer<typeof lane_plan_schema>
31
+
32
+ function plan_path(repository: string, issue: number): string {
33
+ return durable_state.path(durable_state.PREFIX.LANE_PLAN, repository, `-${String(issue)}.json`)
34
+ }
35
+
36
+ function record(plan: LanePlan, directory: string): boolean {
37
+ const repository = git_common_directory.repository(directory)
38
+
39
+ if (repository === undefined) return false
40
+
41
+ stamp_file.replace_stamp(plan_path(repository, plan.issue), plan)
42
+
43
+ return true
44
+ }
45
+
46
+ function remove(issue: number, directory: string): void {
47
+ const repository = git_common_directory.repository(directory)
48
+
49
+ if (repository !== undefined) stamp_file.remove_stamp(plan_path(repository, issue))
50
+ }
51
+
52
+ function read(issue: number, directory: string): LanePlan | undefined {
53
+ const repository = git_common_directory.repository(directory)
54
+ const text =
55
+ repository === undefined ? undefined : stamp_file.read_stamp_text(plan_path(repository, issue))
56
+
57
+ return text === undefined ? undefined : json_value.parse_with(text, lane_plan_schema)
58
+ }
59
+
60
+ // Whether `issue` has no plan that `lane:plan` cleared, in a repository that can hold one — a checkout
61
+ // with no common git directory cannot record a plan, so it is never asked for one. A plan recorded but
62
+ // not cleared — a yield, an unread listing — lifts no hold: the record is written before the check.
63
+ function is_uncleared(issue: number, directory: string): boolean {
64
+ return (
65
+ git_common_directory.repository(directory) !== undefined &&
66
+ read(issue, directory)?.cleared !== true
67
+ )
68
+ }
69
+
70
+ // What an ended lane does with its plan. A plan the lane yielded on (`lane-yield.ts`,
71
+ // joshuafolkken/kit#4926) stays: `backlog:next` holds the issue back on it while the holder runs, and
72
+ // its next lane keeps the place in line it took. Any other plan goes — cleared, or left by a lane that
73
+ // ended before its check answered — so the issue's next lane plans afresh rather than inheriting the
74
+ // files and the place in line of a run that is over.
75
+ function release(issue: number, directory: string): void {
76
+ if (read(issue, directory)?.yielded !== true) remove(issue, directory)
77
+ }
78
+
79
+ // `declared` with each issue's recorded plan, if any, in place of what it declares (joshuafolkken/kit#4937).
80
+ function with_plans(declared: Declared, directory: string): Declared {
81
+ const replaced = [...declared].map(([issue, paths]): [number, ReadonlySet<string>] => [
82
+ issue,
83
+ new Set(read(issue, directory)?.paths ?? paths),
84
+ ])
85
+
86
+ return new Map(replaced)
87
+ }
88
+
89
+ // Whether `other` holds its files ahead of `plan`: it was cleared, or it planned first. A cleared lane
90
+ // may already be editing, so a kept place in line never takes its files from it.
91
+ function goes_before(other: LanePlan, plan: LanePlan): boolean {
92
+ return other.cleared === true || other.planned_at < plan.planned_at
93
+ }
94
+
95
+ // The `holders` whose plan goes before `plan` — the only ones it yields to. Of two uncleared plans the
96
+ // earlier goes first, so two lanes that plan the same file never yield to each other.
97
+ function earlier_holders(
98
+ plan: LanePlan,
99
+ holders: ReadonlyArray<number>,
100
+ directory: string,
101
+ ): Array<number> {
102
+ return holders.filter((holder) => {
103
+ const other = holder === plan.issue ? undefined : read(holder, directory)
104
+
105
+ return other !== undefined && goes_before(other, plan)
106
+ })
107
+ }
108
+
109
+ // The first file of `plan` that a lane in `declared` — its recorded plan, else its body — holds ahead of
110
+ // it. `lane:plan` yields on it, and a named run holds the yielded issue back on the same answer.
111
+ function clash_of(plan: LanePlan, declared: Declared, directory: string): Clash | undefined {
112
+ const holders = earlier_holders(plan, [...declared.keys()], directory)
113
+
114
+ return backlog_overlap.path_clash(new Set(plan.paths), declared, holders)
115
+ }
116
+
117
+ function is_yielded(issue: number, directory: string): boolean {
118
+ return read(issue, directory)?.yielded === true
119
+ }
120
+
121
+ // Whether `issue` yielded on a plan that a lane in `declared` still holds one of its files ahead of —
122
+ // what a named run holds the issue back on, as `backlog:next` does on the same kept plan
123
+ // (joshuafolkken/kit#4926). Without it the run relaunches the issue at once, and the lane yields again.
124
+ function is_yield_held(issue: number, declared: Declared, directory: string): boolean {
125
+ const plan = read(issue, directory)
126
+
127
+ return plan?.yielded === true && clash_of(plan, declared, directory) !== undefined
128
+ }
129
+
130
+ const lane_plan = {
131
+ clash_of,
132
+ earlier_holders,
133
+ is_uncleared,
134
+ is_yield_held,
135
+ is_yielded,
136
+ read,
137
+ record,
138
+ release,
139
+ remove,
140
+ with_plans,
141
+ }
142
+
143
+ export { lane_plan }
144
+ export type { LanePlan }
@@ -1,4 +1,4 @@
1
- import { existsSync, statSync } from 'node:fs'
1
+ import { chmodSync, existsSync, statSync, writeFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { ENV_FILE_NAME } from '#ports'
4
4
  import type { AgentProfile } from '#scripts/agent/agent-role-profile'
@@ -20,6 +20,8 @@ import { lane_paths } from './lane-paths'
20
20
  // that can go stale. A counter, or a ledger beside the trees, would let a lane that was closed and
21
21
  // reopened take a seat a running lane is still using.
22
22
 
23
+ const OWNER_ONLY_MODE = 0o600
24
+
23
25
  interface LaneInfo {
24
26
  issue: string
25
27
  branch: string
@@ -109,6 +111,15 @@ function read_environment(directory: string): string | undefined {
109
111
  return file_reader.read_if_readable(path.join(directory, ENV_FILE_NAME))
110
112
  }
111
113
 
114
+ // The lane's `.env` carries the root's secrets (the Telegram token), so it is readable by its owner
115
+ // alone. `mode` applies only to a file the write creates, so an existing one is narrowed after.
116
+ function write_environment(directory: string, content: string): void {
117
+ const file = path.join(directory, ENV_FILE_NAME)
118
+
119
+ writeFileSync(file, content, { mode: OWNER_ONLY_MODE })
120
+ chmodSync(file, OWNER_ONLY_MODE)
121
+ }
122
+
112
123
  function dispatched_at(directory: string): number | undefined {
113
124
  return statSync(path.join(directory, ENV_FILE_NAME), { throwIfNoEntry: false })?.mtimeMs
114
125
  }
@@ -307,6 +318,8 @@ const lane_registry = {
307
318
  registered_directories,
308
319
  unreadable_lanes,
309
320
  used_seats,
321
+ write_environment,
322
+ OWNER_ONLY_MODE,
310
323
  }
311
324
 
312
325
  export type { LaneInfo }
@@ -7,7 +7,7 @@ import { lane_dispatch_log } from './lane-dispatch-log'
7
7
  import type { LaneInfo } from './lane-registry'
8
8
 
9
9
  // Relaunching a lane child session into its own lane — a fresh agent process started detached, under
10
- // the lane's stored profile at the effort of the phase it resumes into, logging to the lane's dispatch
10
+ // the lane's stored profile at the effort (and any model override) of the phase it resumes into, logging to the lane's dispatch
11
11
  // log and carrying the dispatch mark afresh. **It was `run:cut`'s alone until a second caller needed it**:
12
12
  // the detached `josh ship` supervisor hands a stopped stage back to an agent
13
13
  // the same way the pre-gate cut hands the gate to one, so the launch is shared rather than copied — the
@@ -0,0 +1,51 @@
1
+ import { lane_ledger, type LedgerEntry, type RoundOneEntry } from './lane-ledger'
2
+ import { lane_stats, type StatsWindow } from './lane-stats'
3
+
4
+ // How a `josh ship`'s round 1 ended: the ledger's `round-one` entries of one period, one row per
5
+ // verdict, with each reviewed verdict's share of the rounds the ship ran. The `clean` share is the rate
6
+ // a ship-time round 1 passed with no fix — the number the "CI beside the review" break-even of
7
+ // `docs/maintainers/lane-limit-measurement.md` is read against (joshuafolkken/kit#4620). A `reused`
8
+ // round never ran, so it has a count and no share.
9
+
10
+ const COLUMNS = ['round 1', 'rounds', 'share'] as const
11
+ const VERDICTS = ['clean', 'fixed', 'blocking'] as const
12
+ const { ROUND_ONE_REUSED: REUSED } = lane_ledger
13
+ const NO_SHARE = '-'
14
+ const PERCENT = 100
15
+
16
+ function is_round_one(entry: LedgerEntry): entry is RoundOneEntry {
17
+ return entry.kind === lane_ledger.KIND.ROUND_ONE
18
+ }
19
+
20
+ function count_of(rounds: ReadonlyArray<RoundOneEntry>, verdict: string): number {
21
+ return rounds.filter((round) => round.verdict === verdict).length
22
+ }
23
+
24
+ function share_of(count: number, ran: number): string {
25
+ if (ran === 0) return NO_SHARE
26
+
27
+ return `${String(Math.round((count * PERCENT) / ran))}%`
28
+ }
29
+
30
+ // The period's table: `entries` is the whole ledger, filtered here to `window`.
31
+ function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
32
+ const rounds = lane_stats.in_window(entries, window).filter(is_round_one)
33
+ const counts = VERDICTS.map((verdict) => count_of(rounds, verdict))
34
+ const ran = counts.reduce((sum, count) => sum + count, 0)
35
+ const rows = VERDICTS.map((verdict, index) => {
36
+ const count = counts[index] ?? 0
37
+
38
+ return lane_stats.to_row([verdict, String(count), share_of(count, ran)])
39
+ })
40
+
41
+ return [
42
+ lane_stats.to_row(COLUMNS),
43
+ lane_stats.to_row(COLUMNS.map(() => '---')),
44
+ ...rows,
45
+ lane_stats.to_row([REUSED, String(count_of(rounds, REUSED)), NO_SHARE]),
46
+ ].join('\n')
47
+ }
48
+
49
+ const lane_round_one_stats = { table }
50
+
51
+ export { lane_round_one_stats }
@@ -1,5 +1,7 @@
1
- import { lane_ledger } from './lane-ledger'
1
+ import { lane_ledger_write } from './lane-ledger-write'
2
2
  import { lane_load } from './lane-load'
3
+ import type { LaneSpan } from './lane-net-time'
4
+ import { lane_sleep } from './lane-sleep'
3
5
 
4
6
  // The machine-load sampler: one `load` entry appended to the lane ledger, once or on a timer.
5
7
  //
@@ -14,7 +16,8 @@ const SAMPLE_INTERVAL_MS = 60_000
14
16
  // Where the ledger is and what "now" is, overridable so a test reads a fixed ledger at a fixed instant.
15
17
  interface MeasureContext {
16
18
  ledger_path?: string
17
- // The run's event stream `lane:stats` reads parks from; absent, the repository's own.
19
+ // The run's event stream `lane:stats` reads parks from and a sleep is recorded on; absent, the
20
+ // repository's own.
18
21
  events_path?: string
19
22
  // The lane transcript directories `lane:stats` reads tool calls from; absent, this repository's lanes'.
20
23
  transcript_directories?: ReadonlyArray<string>
@@ -24,7 +27,7 @@ interface MeasureContext {
24
27
  async function take(context: MeasureContext = {}): Promise<void> {
25
28
  const at = new Date(context.now_ms ?? Date.now()).toISOString()
26
29
 
27
- await lane_ledger.record(await lane_load.sample(at), context.ledger_path)
30
+ await lane_ledger_write.record(await lane_load.sample(at), context.ledger_path)
28
31
  }
29
32
 
30
33
  // A timer tick has no caller to raise into, and a sample that could not be read must never end the run
@@ -37,10 +40,26 @@ async function take_quietly(context: MeasureContext): Promise<void> {
37
40
  }
38
41
  }
39
42
 
40
- /** Sample now and then every minute; the returned function stops it. */
43
+ // A sleep that could not be recorded is a gap in the measurement, the same as an unread sample.
44
+ async function record_quietly(span: LaneSpan, context: MeasureContext): Promise<void> {
45
+ try {
46
+ await lane_sleep.record(span, context.events_path)
47
+ } catch {
48
+ // Best-effort: an unrecorded sleep counts as lane time, never as a failure of the run.
49
+ }
50
+ }
51
+
52
+ /** Sample now and then every minute, recording a tick the host slept through; the returned function stops it. */
41
53
  function start(context: MeasureContext = {}): () => void {
54
+ let last_ms = Date.now()
55
+
42
56
  void take_quietly(context)
43
57
  const timer = setInterval(() => {
58
+ const now_ms = Date.now()
59
+ const slept = lane_sleep.gap_of(last_ms, now_ms, SAMPLE_INTERVAL_MS)
60
+
61
+ last_ms = now_ms
62
+ if (slept !== undefined) void record_quietly(slept, context)
44
63
  void take_quietly(context)
45
64
  }, SAMPLE_INTERVAL_MS).unref()
46
65
 
@@ -1,8 +1,12 @@
1
+ import { existsSync } from 'node:fs'
2
+ import path from 'node:path'
1
3
  import { agent_argv } from '#scripts/agent/agent-argv'
2
4
  import { agent_role_profile, type AgentProvider } from '#scripts/agent/agent-role-profile'
3
5
  import { api_auth } from '#scripts/agent/api-auth'
6
+ import { distributed_paths } from '#scripts/init/distributed-paths'
4
7
  import { stamp_file } from '#scripts/josh/stamp-file'
5
8
  import { error_text } from '#scripts/lib/error-message'
9
+ import { review_attest, type ReviewSlot } from '#scripts/review/review-attest'
6
10
  import { detached_launch, type AttachedLaunchResult } from '#scripts/run/detached-launch'
7
11
  import { run_ship_review } from '#scripts/run/ship/run-ship-review'
8
12
  import { run_ship_stage } from '#scripts/run/ship/run-ship-stage'
@@ -16,13 +20,14 @@ import type { LaneInfo } from './lane-registry'
16
20
  import { lane_relaunch } from './lane-relaunch'
17
21
 
18
22
  // The actions a lane's session broker performs for the ship that asked (`lane-session-broker.ts`):
19
- // starting the round-1 or round-2 reviewer, or relaunching the lane's child after a stopped ship.
23
+ // starting the round-1 reviewers or the round-2 reviewer, or relaunching the lane's child after a stopped ship.
20
24
  // **A failure names its reason**: a bare `false` left every relaunch a stale supervisor refused
21
25
  // unexplained in the ship log (joshuafolkken/kit#3974).
22
26
 
23
27
  const BRIEF_PREFIX = 'josh-ship-review-brief-'
24
28
  const FINDINGS_PREFIX = 'josh-ship-review-findings-'
25
29
  const LOG_PREFIX = 'josh-ship-review-log-'
30
+ const SUBMIT_SCRIPT = 'scripts/review/review-submit-cli.ts'
26
31
  const ANTHROPIC_PROVIDER: AgentProvider = 'anthropic'
27
32
  const stop_schema = z
28
33
  .object({
@@ -30,18 +35,45 @@ const stop_schema = z
30
35
  title: z.string(),
31
36
  flags: z.array(z.string()).readonly(),
32
37
  is_review: z.boolean(),
38
+ unpinned_ok: z.array(z.string()).readonly().exactOptional(),
33
39
  conflicts: z.array(z.string()).readonly().default([]),
34
40
  cause: z.enum(run_ship_stop_cause.CAUSE).exactOptional(),
35
41
  is_review_stale: z.boolean().exactOptional(),
36
42
  context: run_ship_stop_context.stop_context_schema.exactOptional(),
37
43
  })
38
44
  .strict()
45
+ // `slots` is omitted for `/code-review` alone, so a supervisor still on the code before it reads the
46
+ // request as before; it names the reviews a ship runs side by side (joshuafolkken/kit#4672).
47
+ const slots_schema = z.array(z.enum(review_attest.REVIEW_SLOTS)).readonly()
39
48
  const action_schema = z.discriminatedUnion('kind', [
40
- z.object({ kind: z.literal('review'), round: z.enum(['1', '2']) }).strict(),
49
+ z
50
+ .object({
51
+ kind: z.literal('review'),
52
+ round: z.enum(['1', '2']),
53
+ slots: slots_schema.exactOptional(),
54
+ })
55
+ .strict(),
41
56
  z.object({ kind: z.literal('relaunch'), stop: stop_schema }).strict(),
42
57
  ])
58
+ const request_schema = z
59
+ .object({ session: z.uuid(), nonce: z.uuid(), action: action_schema })
60
+ .strict()
43
61
  type ReviewRound = Extract<z.infer<typeof action_schema>, { kind: 'review' }>['round']
44
- type BrokerAction = { kind: 'review'; round: ReviewRound } | { kind: 'relaunch'; stop: ShipStop }
62
+
63
+ interface ReviewAction {
64
+ kind: 'review'
65
+ round: ReviewRound
66
+ slots?: ReadonlyArray<ReviewSlot>
67
+ }
68
+
69
+ type BrokerAction = ReviewAction | { kind: 'relaunch'; stop: ShipStop }
70
+
71
+ interface ReviewPaths {
72
+ brief: string
73
+ findings: string
74
+ log: string
75
+ }
76
+
45
77
  type BrokerAnswer = { is_success: true } | { is_success: false; reason: string }
46
78
 
47
79
  const SUCCESS: BrokerAnswer = { is_success: true }
@@ -50,11 +82,18 @@ function failure(reason: string): BrokerAnswer {
50
82
  return { is_success: false, reason }
51
83
  }
52
84
 
53
- function review_paths(directory: string): { brief: string; findings: string; log: string } {
85
+ // **Each review slot has its own files**: `/code-review` and the interaction review run side by side
86
+ // (joshuafolkken/kit#4672), so neither overwrites the other's brief, findings or log.
87
+ function review_paths(
88
+ directory: string,
89
+ slot: ReviewSlot = review_attest.REVIEW_SLOT.CODE,
90
+ ): ReviewPaths {
91
+ const prefix = slot === review_attest.REVIEW_SLOT.CODE ? '' : 'interaction-'
92
+
54
93
  return {
55
- brief: stamp_file.stamp_path(BRIEF_PREFIX, directory, '.md'),
56
- findings: stamp_file.stamp_path(FINDINGS_PREFIX, directory, '.txt'),
57
- log: stamp_file.stamp_path(LOG_PREFIX, directory, '.log'),
94
+ brief: stamp_file.stamp_path(`${BRIEF_PREFIX}${prefix}`, directory, '.md'),
95
+ findings: stamp_file.stamp_path(`${FINDINGS_PREFIX}${prefix}`, directory, '.txt'),
96
+ log: stamp_file.stamp_path(`${LOG_PREFIX}${prefix}`, directory, '.log'),
58
97
  }
59
98
  }
60
99
 
@@ -69,13 +108,27 @@ function provider_of(lane: LaneInfo): AgentProvider {
69
108
  // read as the `backlogrun` parent by every hook. **Its prompt ends with the review invocation**, so the
70
109
  // lane's liveness read and the park's reap find it as they find the child (joshuafolkken/kit#3878).
71
110
 
72
- function review_prompt(lane: LaneInfo, round: ReviewRound): string {
73
- const target = review_paths(lane.directory)
74
- const prompt_of =
75
- round === '1' ? run_ship_review.reviewer_prompt : run_ship_review.verification_prompt
111
+ function action_slots(action: ReviewAction): ReadonlyArray<ReviewSlot> {
112
+ return action.slots ?? [review_attest.REVIEW_SLOT.CODE]
113
+ }
114
+
115
+ // **A lane branched before `review:submit` is handed its findings path** (joshuafolkken/kit#4799): the
116
+ // reviewer runs the lane's own josh, and a supervisor reloaded onto main serves lanes that predate it.
117
+ function has_submit(directory: string): boolean {
118
+ return [SUBMIT_SCRIPT, `${distributed_paths.KIT_PACKAGE_PATH_PREFIX}${SUBMIT_SCRIPT}`].some(
119
+ (script) => existsSync(path.join(directory, script)),
120
+ )
121
+ }
122
+
123
+ function review_prompt(lane: LaneInfo, action: ReviewAction, slot: ReviewSlot): string {
124
+ const { brief, findings } = review_paths(lane.directory, slot)
125
+ const round_prompt =
126
+ action.round === '1' ? run_ship_review.reviewer_prompt : run_ship_review.verification_prompt
127
+ const prompt_of = run_ship_review.slot_prompt(round_prompt, slot, action_slots(action))
76
128
  const tail = lane_child_invocation.review_invocation(lane.issue)
129
+ const findings_path = has_submit(lane.directory) ? undefined : findings
77
130
 
78
- return `${prompt_of(target.brief, target.findings, lane.issue)} This is ${tail}`
131
+ return `${prompt_of(brief, slot, lane.issue, findings_path)} This is ${tail}`
79
132
  }
80
133
 
81
134
  // **A reviewer that could not authenticate names it** with `api_auth.AUTH_FAILURE_NOTE`, read off its
@@ -96,16 +149,21 @@ function reviewer_answer(result: AttachedLaunchResult, log_path: string): Broker
96
149
  return result.exit_code === 0 ? SUCCESS : exited_answer(result.exit_code, log_path)
97
150
  }
98
151
 
99
- async function launch_review(lane: LaneInfo, round: ReviewRound): Promise<BrokerAnswer> {
100
- const target = review_paths(lane.directory)
101
- const built = agent_argv.review_in(review_prompt(lane, round), Number(round), lane.directory)
152
+ async function launch_review(
153
+ lane: LaneInfo,
154
+ action: ReviewAction,
155
+ slot: ReviewSlot,
156
+ ): Promise<BrokerAnswer> {
157
+ const target = review_paths(lane.directory, slot)
158
+ const prompt = review_prompt(lane, action, slot)
159
+ const built = agent_argv.review_in(prompt, Number(action.round), lane.directory)
102
160
  if (built.kind === 'rejected') return failure(`the reviewer profile was rejected: ${built.note}`)
103
161
 
104
162
  if (built.profile.provider !== provider_of(lane)) {
105
163
  return failure(`the reviewer resolved to ${built.profile.provider}, not the lane's provider`)
106
164
  }
107
165
 
108
- console.error(agent_role_profile.describe_review(Number(round), built.profile))
166
+ console.error(agent_role_profile.describe_review(Number(action.round), built.profile))
109
167
  const result = await detached_launch.launch_attached(
110
168
  {
111
169
  argv: built.argv,
@@ -120,6 +178,16 @@ async function launch_review(lane: LaneInfo, round: ReviewRound): Promise<Broker
120
178
  return reviewer_answer(result, target.log)
121
179
  }
122
180
 
181
+ // **The slots' reviewers run side by side**, and the answer is the first failure among them — each
182
+ // slot's findings file then says which review finished (`run-ship-reviewer.ts`).
183
+ async function launch_reviews(lane: LaneInfo, action: ReviewAction): Promise<BrokerAnswer> {
184
+ const answers = await Promise.all(
185
+ action_slots(action).map(async (slot) => await launch_review(lane, action, slot)),
186
+ )
187
+
188
+ return answers.find((reply) => !reply.is_success) ?? SUCCESS
189
+ }
190
+
123
191
  // An OpenAI lane's successor is its supervisor's to start, never a relaunch's.
124
192
  function relaunch(lane: LaneInfo, stop: ShipStop): BrokerAnswer {
125
193
  if (lane_relaunch.is_openai_lane(lane)) {
@@ -142,7 +210,7 @@ async function perform(lane: LaneInfo, action: BrokerAction): Promise<BrokerAnsw
142
210
 
143
211
  if (action.kind === 'relaunch') return relaunch(lane, action.stop)
144
212
 
145
- return await launch_review(lane, action.round)
213
+ return await launch_reviews(lane, action)
146
214
  }
147
215
 
148
216
  // What the server answers: a thrown action is a failure naming its error, never a dead server.
@@ -154,7 +222,14 @@ async function answer(lane: LaneInfo, action: BrokerAction): Promise<BrokerAnswe
154
222
  }
155
223
  }
156
224
 
157
- const lane_session_action = { SUCCESS, action_schema, answer, failure, review_paths }
225
+ const lane_session_action = {
226
+ SUCCESS,
227
+ action_schema,
228
+ answer,
229
+ failure,
230
+ request_schema,
231
+ review_paths,
232
+ }
158
233
 
159
234
  export type { BrokerAction, BrokerAnswer, ReviewRound }
160
235
  export { lane_session_action }