@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,11 +1,28 @@
1
- import { agent_session_environment } from '#scripts/josh/agent-session-environment'
2
1
  import { z } from 'zod'
2
+ import {
3
+ agent_provider,
4
+ type AgentEnvironment,
5
+ type AgentProvider,
6
+ type Rejected,
7
+ } from './agent-provider'
3
8
  import { agent_safe_text } from './agent-safe-text'
4
9
 
5
- const EMPTY_LENGTH = 0
10
+ const {
11
+ ANTHROPIC_PROVIDER,
12
+ CODEX_SESSION_KEY,
13
+ HANDED_PROVIDER_KEY,
14
+ OPENAI_PROVIDER,
15
+ PROVIDER_SCHEMA,
16
+ default_notice,
17
+ handoff_environment,
18
+ has_completion_callback,
19
+ rejection,
20
+ resolve_provider,
21
+ trimmed,
22
+ warn_of_default,
23
+ } = agent_provider
6
24
 
7
25
  const ROLE_SCHEMA = z.enum(['scheduler', 'worker', 'reviewer'])
8
- const PROVIDER_SCHEMA = z.enum(['anthropic', 'openai'])
9
26
  const EFFORT_SCHEMA = z.enum(['low', 'medium', 'high', 'xhigh', 'max'])
10
27
  // The run phases effort may vary by. They are the cut boundaries a lane child
11
28
  // resumes across — `run-cut.ts` imports these names for its own cut record, so the phase a run passes
@@ -20,15 +37,11 @@ const PROFILE_SCHEMA = z.object({
20
37
  })
21
38
 
22
39
  type AgentRole = z.infer<typeof ROLE_SCHEMA>
23
- type AgentProvider = z.infer<typeof PROVIDER_SCHEMA>
24
40
  type AgentEffort = z.infer<typeof EFFORT_SCHEMA>
25
41
  type AgentPhase = z.infer<typeof PHASE_SCHEMA>
26
42
  type AgentProfile = z.infer<typeof PROFILE_SCHEMA>
27
- type AgentEnvironment = Readonly<Record<string, string | undefined>>
28
- type ProfileResult = { kind: 'profile'; profile: AgentProfile } | { kind: 'rejected'; note: string }
29
- type Rejected = Extract<ProfileResult, { kind: 'rejected' }>
43
+ type ProfileResult = Rejected | { kind: 'profile'; profile: AgentProfile }
30
44
  type EffortResult = Rejected | { kind: 'effort'; effort: AgentEffort }
31
- type ProviderResult = Rejected | { kind: 'provider'; provider: AgentProvider; is_default?: true }
32
45
  type OverrideField = 'model' | 'effort'
33
46
 
34
47
  interface Override {
@@ -36,6 +49,13 @@ interface Override {
36
49
  value: string | undefined
37
50
  }
38
51
 
52
+ interface PhaseModel {
53
+ key: string
54
+ value: string
55
+ }
56
+
57
+ type PhaseTable<Value> = Readonly<Partial<Record<AgentRole, Partial<Record<AgentPhase, Value>>>>>
58
+
39
59
  // What a resolution is keyed on beyond the role: the run phase (effort) and the review round (profile).
40
60
  interface AgentStage {
41
61
  phase?: string | undefined
@@ -47,38 +67,33 @@ const WORKER: AgentRole = 'worker'
47
67
  const REVIEWER: AgentRole = 'reviewer'
48
68
  const IMPLEMENTATION_PHASE: AgentPhase = 'implementation'
49
69
  const PRE_GATE_PHASE: AgentPhase = 'pre-gate'
50
- const ANTHROPIC_PROVIDER: AgentProvider = 'anthropic'
51
- const OPENAI_PROVIDER: AgentProvider = 'openai'
52
70
  // **Pinned model ids, never a floating alias**. An alias such as `opus` moves
53
71
  // whenever the CLI moves it, so a run log could not say which model produced it and a model migration
54
72
  // could not be measured apart from everything else. A new lane records the id it resolved; a lane
55
- // created before a migration keeps the model it recorded (`with_phase_effort` leaves it untouched).
73
+ // created before a migration keeps the model it recorded (`with_phase` moves it only by a phase key).
56
74
  const OPENAI_MODEL = 'gpt-6.1-sol'
57
75
  const ANTHROPIC_MODEL = 'claude-opus-5-5'
58
- const CODEX_SESSION_KEY = 'CODEX_THREAD_ID'
59
-
60
- const DEFAULT_PROFILES: Readonly<Record<AgentRole, AgentProfile>> = {
61
- scheduler: {
62
- provider: ANTHROPIC_PROVIDER,
63
- role: SCHEDULER,
64
- model: ANTHROPIC_MODEL,
65
- effort: 'medium',
66
- },
67
- worker: { provider: ANTHROPIC_PROVIDER, role: WORKER, model: ANTHROPIC_MODEL, effort: 'medium' },
68
- reviewer: {
69
- provider: ANTHROPIC_PROVIDER,
70
- role: REVIEWER,
71
- model: ANTHROPIC_MODEL,
72
- effort: 'high',
73
- },
74
- }
75
76
 
76
- const OPENAI_PROFILES: Readonly<Record<AgentRole, AgentProfile>> = {
77
- scheduler: { provider: OPENAI_PROVIDER, role: SCHEDULER, model: OPENAI_MODEL, effort: 'medium' },
78
- worker: { provider: OPENAI_PROVIDER, role: WORKER, model: OPENAI_MODEL, effort: 'medium' },
79
- reviewer: { provider: OPENAI_PROVIDER, role: REVIEWER, model: OPENAI_MODEL, effort: 'high' },
77
+ // **Round 1 reviews at `medium`** (joshuafolkken/kit#5106): it ended clean on 88% of diffs while its
78
+ // `high` run sat on the lane's critical path; the verification pass below keeps `high`.
79
+ const REVIEW_EFFORT: AgentEffort = 'medium'
80
+ const VERIFICATION_EFFORT: AgentEffort = 'high'
81
+
82
+ // Every provider runs each role at the same effort; only the model differs.
83
+ function role_profiles(
84
+ provider: AgentProvider,
85
+ model: string,
86
+ ): Readonly<Record<AgentRole, AgentProfile>> {
87
+ return {
88
+ scheduler: { provider, role: SCHEDULER, model, effort: 'medium' },
89
+ worker: { provider, role: WORKER, model, effort: 'medium' },
90
+ reviewer: { provider, role: REVIEWER, model, effort: REVIEW_EFFORT },
91
+ }
80
92
  }
81
93
 
94
+ const DEFAULT_PROFILES = role_profiles(ANTHROPIC_PROVIDER, ANTHROPIC_MODEL)
95
+ const OPENAI_PROFILES = role_profiles(OPENAI_PROVIDER, OPENAI_MODEL)
96
+
82
97
  const PROVIDER_PROFILES = { anthropic: DEFAULT_PROFILES, openai: OPENAI_PROFILES }
83
98
 
84
99
  // **The verification pass resolves a profile of its own** (joshuafolkken/kit#3926). A round after the
@@ -89,8 +104,12 @@ const FIRST_REVIEW_ROUND = 1
89
104
  // pass/fail equals Opus's (100% agreement), and Opus passes all 4.
90
105
  const VERIFICATION_MODEL = 'claude-sonnet-5-5'
91
106
  const VERIFICATION_PROFILES: Readonly<Record<AgentProvider, AgentProfile>> = {
92
- anthropic: { ...DEFAULT_PROFILES.reviewer, model: VERIFICATION_MODEL },
93
- openai: OPENAI_PROFILES.reviewer,
107
+ anthropic: {
108
+ ...DEFAULT_PROFILES.reviewer,
109
+ model: VERIFICATION_MODEL,
110
+ effort: VERIFICATION_EFFORT,
111
+ },
112
+ openai: { ...OPENAI_PROFILES.reviewer, effort: VERIFICATION_EFFORT },
94
113
  }
95
114
  const VERIFICATION_KEYS = {
96
115
  model: 'JOSH_REVIEWER_VERIFICATION_MODEL',
@@ -101,15 +120,21 @@ const VERIFICATION_KEYS = {
101
120
  // merge only the mechanical ship/bookkeeping region is lowered: the pre-gate resume drives the gate,
102
121
  // commit, PR and merge, applying fixes the gate has already named — work delegation.md calls the opposite
103
122
  // of judgement. The design-judgment implementation phases keep the role default, as does any role/phase
104
- // with no entry, and the review's own judgement is the reviewer role's (`high`), untouched by lowering
123
+ // with no entry, and the review's own judgement is the reviewer role's, untouched by lowering
105
124
  // the worker here. The investigation phase — highest output density — is left for a later merge, once
106
125
  // the delegation half of this Issue has moved its reading out.
107
126
  const SHIP_EFFORT: AgentEffort = 'low'
108
- type PhaseEffortTable = Partial<Record<AgentRole, Partial<Record<AgentPhase, AgentEffort>>>>
109
- const PHASE_EFFORT: Readonly<PhaseEffortTable> = {
127
+ const PHASE_EFFORT: PhaseTable<AgentEffort> = {
110
128
  worker: { [PRE_GATE_PHASE]: SHIP_EFFORT },
111
129
  }
112
130
 
131
+ // **The ship phase may run on a model of its own** (joshuafolkken/kit#5343), read from its key ahead of
132
+ // the role's and applied on the same cut relaunch as `SHIP_EFFORT`. Unset, the phase keeps the role's
133
+ // model, so the default is unchanged.
134
+ const PHASE_MODEL_KEYS: PhaseTable<string> = {
135
+ worker: { [PRE_GATE_PHASE]: 'JOSH_WORKER_SHIP_MODEL' },
136
+ }
137
+
113
138
  const ENV_KEYS: Readonly<Record<AgentRole, { model: string; effort: string }>> = {
114
139
  scheduler: { model: 'JOSH_SCHEDULER_MODEL', effort: 'JOSH_SCHEDULER_EFFORT' },
115
140
  worker: { model: 'JOSH_WORKER_MODEL', effort: 'JOSH_WORKER_EFFORT' },
@@ -120,12 +145,6 @@ const LEGACY_WORKER_KEYS = { model: 'JOSH_LANE_MODEL', effort: 'JOSH_LANE_EFFORT
120
145
 
121
146
  const { MAX_VALUE_LENGTH, is_safe_prompt, is_safe_value, printable } = agent_safe_text
122
147
 
123
- function trimmed(value: string | undefined): string | undefined {
124
- const result = value?.trim()
125
-
126
- return result === undefined || result.length === EMPTY_LENGTH ? undefined : result
127
- }
128
-
129
148
  function is_verification(role: AgentRole, round: number | undefined): boolean {
130
149
  return role === REVIEWER && round !== undefined && round > FIRST_REVIEW_ROUND
131
150
  }
@@ -157,19 +176,44 @@ function override_value(
157
176
  : { key, value: trimmed(environment[key]) }
158
177
  }
159
178
 
179
+ // A role's entry in a phase table; `undefined` for a phase-less or unrecognized phase, or no entry.
180
+ function phase_entry<Value>(
181
+ table: PhaseTable<Value>,
182
+ role: AgentRole,
183
+ phase: string | undefined,
184
+ ): Value | undefined {
185
+ const parsed = PHASE_SCHEMA.safeParse(phase)
186
+
187
+ return parsed.success ? table[role]?.[parsed.data] : undefined
188
+ }
189
+
190
+ // The phase's own model key when it is set; `undefined` for a phase with no key, an unset key, or an
191
+ // OpenAI session, whose model is never read from env.
192
+ function phase_model(
193
+ role: AgentRole,
194
+ provider: AgentProvider,
195
+ phase: string | undefined,
196
+ environment: AgentEnvironment,
197
+ ): PhaseModel | undefined {
198
+ const key = provider === OPENAI_PROVIDER ? undefined : phase_entry(PHASE_MODEL_KEYS, role, phase)
199
+ if (key === undefined) return undefined
200
+ const value = trimmed(environment[key])
201
+
202
+ return value === undefined ? undefined : { key, value }
203
+ }
204
+
160
205
  function model_override(
161
206
  role: AgentRole,
162
207
  environment: AgentEnvironment,
163
208
  provider: AgentProvider,
164
- round: number | undefined,
209
+ stage: AgentStage,
165
210
  ): Override {
211
+ const phased = phase_model(role, provider, stage.phase, environment)
212
+ if (phased !== undefined) return phased
213
+
166
214
  return provider === OPENAI_PROVIDER
167
215
  ? { key: ENV_KEYS[role].model, value: undefined }
168
- : override_value(role, 'model', environment, round)
169
- }
170
-
171
- function rejection(key: string, value: string, expected: string): Rejected {
172
- return { kind: 'rejected', note: `${key}=${value} ${expected}, so the agent was not started` }
216
+ : override_value(role, 'model', environment, stage.round)
173
217
  }
174
218
 
175
219
  function resolved_effort(override: Override, fallback: AgentEffort): EffortResult {
@@ -180,93 +224,6 @@ function resolved_effort(override: Override, fallback: AgentEffort): EffortResul
180
224
  : rejection(override.key, override.value ?? '', 'is not an allowed effort')
181
225
  }
182
226
 
183
- function has_session(environment: AgentEnvironment, keys: ReadonlyArray<string>): boolean {
184
- return keys.some((key) => trimmed(environment[key]) !== undefined)
185
- }
186
-
187
- const CONFLICTING_SESSIONS: Rejected = {
188
- kind: 'rejected',
189
- note: 'both Codex and Claude Code sessions were detected',
190
- }
191
-
192
- // The provider a detached launcher hands a process that is not itself an agent session.
193
- // `detached_launch` strips the parent-session keys — the very keys the
194
- // detection below reads — so a `josh ship --detach --review` supervisor could never resolve its reviewer.
195
- // **It is a fallback, read only when no session is detected**: the mark is inherited by everything the
196
- // supervisor starts, and a real session's own keys must keep deciding for that session.
197
- const HANDED_PROVIDER_KEY = 'JOSH_AGENT_PROVIDER'
198
-
199
- // **Nothing named a provider, so Claude Code is the default** — a person typing `josh lane:launch` in a
200
- // plain terminal has no session and no mark. Only silence defaults: two detected sessions and a mark
201
- // naming no allowed provider still refuse. `is_default` lets a launch say so, and lets `josh cost` keep
202
- // reading "no session of its own" rather than pricing another session's transcript.
203
- const DEFAULT_PROVIDER: ProviderResult = {
204
- kind: 'provider',
205
- provider: ANTHROPIC_PROVIDER,
206
- is_default: true,
207
- }
208
- const DEFAULT_NOTICE = ` No agent session or ${HANDED_PROVIDER_KEY} was found, so the provider defaulted to ${ANTHROPIC_PROVIDER} (Claude Code).`
209
-
210
- function handed_provider(environment: AgentEnvironment): ProviderResult {
211
- const value = trimmed(environment[HANDED_PROVIDER_KEY])
212
- if (value === undefined) return DEFAULT_PROVIDER
213
- const parsed = PROVIDER_SCHEMA.safeParse(value)
214
-
215
- return parsed.success
216
- ? { kind: 'provider', provider: parsed.data }
217
- : rejection(HANDED_PROVIDER_KEY, value, 'is not an allowed provider')
218
- }
219
-
220
- // The session this process runs in, read from its own keys: `undefined` when none is detected.
221
- function detected_provider(environment: AgentEnvironment): ProviderResult | undefined {
222
- const has_codex = has_session(environment, [CODEX_SESSION_KEY])
223
- const has_claude = has_session(environment, agent_session_environment.PARENT_SESSION_KEYS)
224
-
225
- if (has_codex === has_claude) return has_codex ? CONFLICTING_SESSIONS : undefined
226
-
227
- return { kind: 'provider', provider: has_codex ? OPENAI_PROVIDER : ANTHROPIC_PROVIDER }
228
- }
229
-
230
- function resolve_provider(environment: AgentEnvironment = process.env): ProviderResult {
231
- return detected_provider(environment) ?? handed_provider(environment)
232
- }
233
-
234
- // The sentence a launch appends when it ran on the default, so falling back is never silent; empty when
235
- // a session or a mark decided.
236
- function default_notice(environment: AgentEnvironment = process.env): string {
237
- const selected = resolve_provider(environment)
238
-
239
- return selected.kind === 'provider' && selected.is_default === true ? DEFAULT_NOTICE : ''
240
- }
241
-
242
- // The same sentence on stderr, for a launcher whose own line is a verdict or a brief another process
243
- // reads: `run:wake --start`, `review:brief` and `ship --detach` default exactly as a dispatch does.
244
- function warn_of_default(environment: AgentEnvironment = process.env): void {
245
- const notice = default_notice(environment).trim()
246
-
247
- if (notice !== '') console.error(notice)
248
- }
249
-
250
- // Whether this session is woken when a background command it started completes.
251
- // Claude Code re-invokes the session at the completion; a Codex session is not
252
- // re-invoked, so a parent there can only wait by polling, each poll a model call over its whole context.
253
- // Only a resolved Codex session answers no — a defaulted or conflicting one keeps the callback.
254
- function has_completion_callback(environment: AgentEnvironment = process.env): boolean {
255
- const selected = resolve_provider(environment)
256
-
257
- return selected.kind !== 'provider' || selected.provider !== OPENAI_PROVIDER
258
- }
259
-
260
- // The mark a detached launch sets on its child: the provider this session resolved, the default
261
- // included, or nothing when it was refused — the child then fails the same way this session would have.
262
- function handoff_environment(
263
- environment: AgentEnvironment = process.env,
264
- ): Readonly<Record<string, string>> {
265
- const selected = resolve_provider(environment)
266
-
267
- return selected.kind === 'provider' ? { [HANDED_PROVIDER_KEY]: selected.provider } : {}
268
- }
269
-
270
227
  function validate(profile: AgentProfile, model_key: string): ProfileResult {
271
228
  if (!is_safe_value(profile.model)) {
272
229
  return rejection(model_key, profile.model, 'is not a safe model')
@@ -283,10 +240,7 @@ function phase_effort(
283
240
  phase: string | undefined,
284
241
  fallback: AgentEffort,
285
242
  ): AgentEffort {
286
- const parsed = PHASE_SCHEMA.safeParse(phase)
287
- if (!parsed.success) return fallback
288
-
289
- return PHASE_EFFORT[role]?.[parsed.data] ?? fallback
243
+ return phase_entry(PHASE_EFFORT, role, phase) ?? fallback
290
244
  }
291
245
 
292
246
  // The effort a stored profile takes in a phase: an env override wins, then the phase value, then the
@@ -302,14 +256,18 @@ function overridden_effort(
302
256
  return parsed.success ? parsed.data : phase_effort(profile.role, phase, profile.effort)
303
257
  }
304
258
 
305
- // A stored profile with its effort resolved for the phase the run is entering, its model and provider
306
- // left as they were.
307
- function with_phase_effort(
259
+ // A stored profile resolved for the phase the run is entering: its effort, and its model only where the
260
+ // phase's own model key is set — the role's model key never moves a lane off the model it recorded.
261
+ function with_phase(
308
262
  profile: AgentProfile,
309
263
  phase: string,
310
264
  environment: AgentEnvironment = process.env,
311
- ): AgentProfile {
312
- return { ...profile, effort: overridden_effort(profile, phase, environment) }
265
+ ): ProfileResult {
266
+ const effort = overridden_effort(profile, phase, environment)
267
+ const model = phase_model(profile.role, profile.provider, phase, environment)
268
+ if (model === undefined) return { kind: 'profile', profile: { ...profile, effort } }
269
+
270
+ return validate({ ...profile, model: model.value, effort }, model.key)
313
271
  }
314
272
 
315
273
  function stage_defaults(
@@ -330,7 +288,7 @@ function resolve_stage(
330
288
  const selected = resolve_provider(environment)
331
289
  if (selected.kind === 'rejected') return selected
332
290
  const defaults = stage_defaults(selected.provider, role, stage.round)
333
- const model = model_override(role, environment, selected.provider, stage.round)
291
+ const model = model_override(role, environment, selected.provider, stage)
334
292
  const effort = override_value(role, 'effort', environment, stage.round)
335
293
  const resolved = resolved_effort(effort, phase_effort(role, stage.phase, defaults.effort))
336
294
 
@@ -401,16 +359,10 @@ const agent_role_profile = {
401
359
  resolve_provider,
402
360
  resolve_review,
403
361
  warn_of_default,
404
- with_phase_effort,
362
+ with_phase,
405
363
  }
406
364
 
407
- export type {
408
- AgentEffort,
409
- AgentEnvironment,
410
- AgentPhase,
411
- AgentProfile,
412
- AgentProvider,
413
- AgentRole,
414
- ProfileResult,
415
- }
365
+ export type { AgentEffort, AgentPhase, AgentProfile, AgentRole, ProfileResult }
416
366
  export { agent_role_profile }
367
+
368
+ export { type AgentEnvironment, type AgentProvider } from './agent-provider'
@@ -6,6 +6,11 @@ const DELETE_CODE = 0x7f
6
6
  const FIRST_CODE_POINT = 0
7
7
  const EMPTY_LENGTH = 0
8
8
  const MAX_VALUE_LENGTH = 4096
9
+ // A prompt is prose that grows with its instructions, so it gets a cap of its own rather than a
10
+ // value's: an overrun investigation's prompt grew past 4096 and its launch was refused
11
+ // (joshuafolkken/kit#4930). 64 Ki UTF-16 units of mostly ASCII text stay under Linux's 128 KiB
12
+ // `MAX_ARG_STRLEN` per element; a launch the system still refuses fails as a noted launch failure.
13
+ const MAX_PROMPT_LENGTH = 65_536
9
14
  const LINE_FEED = '\n'
10
15
  const SPACE = ' '
11
16
 
@@ -27,8 +32,12 @@ function is_refused(character: string, is_allowed: (character: string) => boolea
27
32
  return is_control_character(character) && !is_allowed(character)
28
33
  }
29
34
 
30
- function is_safe_text(value: string, is_allowed: (character: string) => boolean): boolean {
31
- if (value.length === EMPTY_LENGTH || value.length > MAX_VALUE_LENGTH) return false
35
+ function is_safe_text(
36
+ value: string,
37
+ is_allowed: (character: string) => boolean,
38
+ max_length: number,
39
+ ): boolean {
40
+ if (value.length === EMPTY_LENGTH || value.length > max_length) return false
32
41
 
33
42
  for (const character of value) if (is_refused(character, is_allowed)) return false
34
43
 
@@ -36,13 +45,13 @@ function is_safe_text(value: string, is_allowed: (character: string) => boolean)
36
45
  }
37
46
 
38
47
  function is_safe_value(value: string): boolean {
39
- return is_safe_text(value, is_never_allowed)
48
+ return is_safe_text(value, is_never_allowed, MAX_VALUE_LENGTH)
40
49
  }
41
50
 
42
51
  // **An agent's prompt is the one value a line break belongs in.** A ship-stop prompt carries the failed
43
52
  // output's lines (joshuafolkken/kit#3964); every other control character is refused as in any value.
44
53
  function is_safe_prompt(value: string): boolean {
45
- return is_safe_text(value, is_line_feed)
54
+ return is_safe_text(value, is_line_feed, MAX_PROMPT_LENGTH)
46
55
  }
47
56
 
48
57
  function printable_character(character: string): string {
@@ -55,6 +64,12 @@ function printable(text: string): string {
55
64
  return Array.from(text, printable_character).join('')
56
65
  }
57
66
 
58
- const agent_safe_text = { MAX_VALUE_LENGTH, is_safe_prompt, is_safe_value, printable }
67
+ const agent_safe_text = {
68
+ MAX_PROMPT_LENGTH,
69
+ MAX_VALUE_LENGTH,
70
+ is_safe_prompt,
71
+ is_safe_value,
72
+ printable,
73
+ }
59
74
 
60
75
  export { agent_safe_text }
@@ -0,0 +1,65 @@
1
+ import { agent_exit_record } from './agent-exit-record'
2
+ import type { ClaudeResultEvent } from './claude-result-event'
3
+ import { usage_limit_reset } from './usage-limit-reset'
4
+
5
+ // Whether a Claude session's exit record is a usage-limit stop, and when it may run again — observed on
6
+ // 2026-10-23, when four lane children ended `You've hit your weekly limit · resets 10am (...)` at once
7
+ // and the parent parked each as a child that stopped on its own (joshuafolkken/kit#4745).
8
+ //
9
+ // **Kept apart from `api-outage.ts` and `api-auth.ts`**: an outage clears within minutes and an
10
+ // authentication failure needs a person, but a usage limit clears at a time the record itself names, so
11
+ // the run waits for that time and resumes. The read is the same mechanical one — the error flag AND a
12
+ // fixed marker in the harness's own `reason`, never the marker alone.
13
+
14
+ // The limit sentences' stable parts, lower-cased: the current `You've hit your [weekly|session] limit`
15
+ // and the older `Claude AI usage limit reached|<epoch>`.
16
+ const LIMIT_PATTERN = /hit your (?:\w+ )?limit|usage limit reached/u
17
+ // How long a stop whose reset time could not be read waits before one child tries again.
18
+ const RECHECK_MS = 1_800_000
19
+
20
+ // The record's `reason` when it is a usage limit, else `undefined`.
21
+ function limit_reason(record: ClaudeResultEvent | undefined): string | undefined {
22
+ if (record === undefined || !record.is_error || record.reason === undefined) return undefined
23
+
24
+ return LIMIT_PATTERN.test(record.reason.toLowerCase()) ? record.reason : undefined
25
+ }
26
+
27
+ function is_usage_limit(record: ClaudeResultEvent | undefined): boolean {
28
+ return limit_reason(record) !== undefined
29
+ }
30
+
31
+ // A reset the record does not state readably — or one already past — is re-checked `RECHECK_MS` on.
32
+ function or_recheck(reset_ms: number | undefined, now_ms: number): number {
33
+ return reset_ms === undefined || reset_ms <= now_ms ? now_ms + RECHECK_MS : reset_ms
34
+ }
35
+
36
+ // When a run stopped by this record may dispatch again, in epoch milliseconds, or `undefined` when the
37
+ // record is no usage limit. The sentence's wall clock is read from `stopped_ms`, when the record was
38
+ // written: read later, a reset already past would roll to the next day.
39
+ function resume_ms(
40
+ record: ClaudeResultEvent | undefined,
41
+ now_ms: number,
42
+ stopped_ms = now_ms,
43
+ ): number | undefined {
44
+ const reason = limit_reason(record)
45
+
46
+ if (reason === undefined) return undefined
47
+
48
+ return or_recheck(usage_limit_reset.reset_ms(reason, stopped_ms), now_ms)
49
+ }
50
+
51
+ // The same read over a whole stream-json transcript, read only when it ends on an exit record — the
52
+ // lane's log is appended across launches (`api_auth.is_auth_failed_transcript`).
53
+ function transcript_resume_ms(
54
+ log: string | undefined,
55
+ now_ms: number,
56
+ stopped_ms = now_ms,
57
+ ): number | undefined {
58
+ if (log === undefined || !agent_exit_record.ends_on_exit_record(log)) return undefined
59
+
60
+ return resume_ms(agent_exit_record.read_exit_record(log), now_ms, stopped_ms)
61
+ }
62
+
63
+ const api_usage_limit = { RECHECK_MS, is_usage_limit, resume_ms, transcript_resume_ms }
64
+
65
+ export { api_usage_limit }
@@ -12,8 +12,8 @@ const AGENT_COMMAND = 'claude'
12
12
  // **The permission mode is passed, not left to the checkout's `.claude/settings.json`.** Claude Code
13
13
  // ignores a project's `defaultMode: bypassPermissions` (since v2.1.257) and its `permissions.allow` in
14
14
  // a workspace whose trust dialog was never accepted — every fresh clone and every new lane worktree — so
15
- // a headless child stopped on approvals nobody could give. The flag sets the mode that file declares;
16
- // its `deny` list stays in effect (#3796).
15
+ // a headless child stopped on approvals nobody could give, so kit ships no `defaultMode` (#4997) and
16
+ // the flag sets the mode; the file's `deny` list stays in effect (#3796).
17
17
  const PERMISSION_FLAGS: ReadonlyArray<string> = ['--permission-mode', 'bypassPermissions']
18
18
  const AGENT_FLAGS: ReadonlyArray<string> = [
19
19
  '-p',
@@ -37,7 +37,9 @@ const SESSION_ID_FLAG = '--session-id'
37
37
  // tool definition and every user-side claude.ai connector rides on each request's cached preamble, and
38
38
  // across the lanes measured none of Artifact, Workflow or a connector was ever called, while
39
39
  // AskUserQuestion has nobody to answer it in an unattended lane. Narrowing them cut the preamble by
40
- // about 16,000 tokens per request. This list is the one place the set is kept.
40
+ // about 16,000 tokens per request. **No web tool is launched**: no role runs with a person at the keyboard, and a
41
+ // fetched page enters the context with no trust label, past the Issue trust filter (#4664). This list
42
+ // is the one place the set is kept.
41
43
  const LAUNCHED_TOOLS: ReadonlyArray<string> = [
42
44
  'Bash',
43
45
  'Read',
@@ -50,9 +52,11 @@ const LAUNCHED_TOOLS: ReadonlyArray<string> = [
50
52
  'TaskStop',
51
53
  'Monitor',
52
54
  'TodoWrite',
53
- 'WebSearch',
54
- 'WebFetch',
55
55
  ]
56
+ // **A reviewer is the review, not a launcher of one** (joshuafolkken/kit#4715): with `Skill` it ran
57
+ // `/code-review`, which forked a second agent that read the same diff and brief again. Without the two
58
+ // tools that open a nested agent, the review stays in the one session.
59
+ const NESTING_TOOLS: ReadonlySet<string> = new Set(['Agent', 'Skill'])
56
60
  const TOOLS_FLAG = '--tools'
57
61
  // **Only the project's own MCP servers load** — the user's connectors are what the strict flag drops.
58
62
  // A project with no `.mcp.json` gets the strict flag alone, which loads no server at all: that is
@@ -77,16 +81,22 @@ function session_id_flags(session_id: string | undefined): ReadonlyArray<string>
77
81
  return session_id === undefined ? [] : [SESSION_ID_FLAG, session_id]
78
82
  }
79
83
 
84
+ function launched_tools(role: AgentRole): ReadonlyArray<string> {
85
+ if (role !== agent_role_profile.REVIEWER) return LAUNCHED_TOOLS
86
+
87
+ return LAUNCHED_TOOLS.filter((tool) => !NESTING_TOOLS.has(tool))
88
+ }
89
+
80
90
  // The config is named by absolute path, resolved against the directory the child is launched in, so
81
91
  // the flag means the same file whatever the child's own working directory turns out to be. The pair
82
92
  // sits ahead of the model flags: `--mcp-config` takes several values, and the next flag is what ends it.
83
- function tool_flags(cwd: string = process.cwd()): ReadonlyArray<string> {
93
+ function tool_flags(role: AgentRole, cwd: string = process.cwd()): ReadonlyArray<string> {
84
94
  const mcp_config = path.join(cwd, PROJECT_MCP_FILE)
85
95
  const mcp_flags = existsSync(mcp_config)
86
96
  ? [STRICT_MCP_FLAG, MCP_CONFIG_FLAG, mcp_config]
87
97
  : [STRICT_MCP_FLAG]
88
98
 
89
- return [TOOLS_FLAG, LAUNCHED_TOOLS.join(','), ...mcp_flags]
99
+ return [TOOLS_FLAG, launched_tools(role).join(','), ...mcp_flags]
90
100
  }
91
101
 
92
102
  // **A lane child and a review session start from the lane instruction set** (`lane-instructions.ts`);
@@ -107,7 +117,7 @@ function build(
107
117
  command: AGENT_COMMAND,
108
118
  args: [
109
119
  ...AGENT_FLAGS,
110
- ...tool_flags(cwd),
120
+ ...tool_flags(profile.role, cwd),
111
121
  ...instruction_flags(profile, cwd),
112
122
  ...session_id_flags(session_id),
113
123
  MODEL_FLAG,
@@ -132,7 +142,7 @@ function build_resume(
132
142
  command: AGENT_COMMAND,
133
143
  args: [
134
144
  ...AGENT_FLAGS,
135
- ...tool_flags(cwd),
145
+ ...tool_flags(profile.role, cwd),
136
146
  ...instruction_flags(profile, cwd),
137
147
  RESUME_FLAG,
138
148
  session_id,