@joshuafolkken/kit 1.1784.0 → 1.2114.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 +59 -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 +415 -389
  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 +15 -8
  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
@@ -35,10 +35,15 @@ import { run_tail_rule } from './run-tail-rule'
35
35
 
36
36
  // The josh subcommands that run long enough to be backgrounded, as `time_shell` names them — canonical,
37
37
  // so the `ga` / `g` / `fu` aliases are covered by the one spelling.
38
- const SHIP_COMMAND = `${time_shell.JOSH_PREFIX}ship`
38
+ // `ship`, `ship:wait` and `lane:plan` are run in the foreground at the cap rather than refused: a
39
+ // `ship:wait` left at the two-minute default is moved aside mid-chunk and dies with the turn, its verdict
40
+ // unread, and a cut `lane:plan` leaves its plan recorded with the check it gates unanswered.
41
+ const FOREGROUND_COMMANDS: ReadonlySet<string> = new Set(
42
+ ['ship', 'ship:wait', 'lane:plan'].map((name) => `${time_shell.JOSH_PREFIX}${name}`),
43
+ )
39
44
  const LONG_RUNNING_COMMANDS: ReadonlySet<string> = new Set([
40
45
  ...['gate', 'git', 'followup'].map((name) => `${time_shell.JOSH_PREFIX}${name}`),
41
- SHIP_COMMAND,
46
+ ...FOREGROUND_COMMANDS,
42
47
  ])
43
48
 
44
49
  const BACKGROUND_KEY = 'run_in_background'
@@ -57,13 +62,13 @@ function long_commands_of(command: string): Array<string> {
57
62
  return time_shell.josh_commands_of(command).filter((name) => LONG_RUNNING_COMMANDS.has(name))
58
63
  }
59
64
 
60
- // A call whose long-running work is `ship` alone. In a child a foreground `ship` already detaches
61
- // itself after its preflight (`run-ship-cli.ts` → `should_detach`), so the only fault in backgrounding
62
- // it is the flag — and the flag is what the hook rewrites.
65
+ // A call whose long-running work is `ship` or `ship:wait` alone. In a child a foreground `ship` already
66
+ // detaches itself after its preflight (`run-ship-cli.ts` → `should_detach`), so the only fault in
67
+ // backgrounding it is the flag — and the flag is what the hook rewrites.
63
68
  function ships_alone(command: string): boolean {
64
69
  const names = long_commands_of(command)
65
70
 
66
- return names.length > 0 && names.every((name) => name === SHIP_COMMAND)
71
+ return names.length > 0 && names.every((name) => FOREGROUND_COMMANDS.has(name))
67
72
  }
68
73
 
69
74
  function backgrounded_bash_command(call: GuardedCall): string | undefined {
@@ -135,10 +140,10 @@ function foreground_input(
135
140
  }
136
141
 
137
142
  const FOREGROUND_NOTE =
138
- "lane background: a lane child's `josh ship` backgrounded, by its flag or by outrunning the Bash " +
139
- 'timeout, dies with the headless turn before its supervisor exists — so it was run in the ' +
140
- 'foreground at the 600000 ms cap, where it detaches itself after the preflight. End the turn on ' +
141
- '`launched` / `busy`.'
143
+ "lane background: a lane child's `josh ship`, `josh ship:wait` or `josh lane:plan` backgrounded, by its flag or by " +
144
+ 'outrunning the Bash timeout, dies with the headless turn — so it was run in the foreground at the ' +
145
+ '600000 ms cap, where `ship` detaches itself after the preflight. Then follow ' +
146
+ '`chain-rule.md` step 0 (`josh ship:wait` on `launched`).'
142
147
 
143
148
  type LaunchedIds = (block: TranscriptBlock) => ReadonlyArray<string>
144
149
 
@@ -182,11 +187,17 @@ function pending_agent_ids(tail: string): ReadonlyArray<string> {
182
187
  return unfinished_ids(tail, (block) => [block.agent_id])
183
188
  }
184
189
 
190
+ // The backgrounded commands alone — what tells a stop with only subagents left apart from one a
191
+ // command still holds.
192
+ function pending_command_ids(tail: string): ReadonlyArray<string> {
193
+ return unfinished_ids(tail, (block) => [block.background_id])
194
+ }
195
+
185
196
  const LANE_BACKGROUND_REASON =
186
197
  '⛔ lane background: this session is a dispatched lane child (`JOSH_LANE_CHILD`), a headless ' +
187
198
  'process whose background tasks die when the turn ends. Hand over to ' +
188
- '`pnpm josh ship --detach --review "<title> #<N>"`, issued in the foreground, then end the turn on ' +
189
- '`launched` / `busy`. It fires on every occurrence ' +
199
+ '`pnpm josh ship --detach --review "<title> #<N>"`, issued in the foreground, then `josh ship:wait <N>` on ' +
200
+ '`launched` or end the turn. It fires on every occurrence ' +
190
201
  '(`.claude/skills/workflow-commands/chain-rule.md` step 0).'
191
202
 
192
203
  const LANE_BACKGROUND_STOP_REASON =
@@ -194,6 +205,15 @@ const LANE_BACKGROUND_STOP_REASON =
194
205
  'it launched has not finished, and ending this turn kills it. Wait for it in the foreground, or ' +
195
206
  're-issue the work through `pnpm josh ship --detach` — do not notify, stop or repeat your reply.'
196
207
 
208
+ // **Only subagents left: the wait that receives their answer** (joshuafolkken/kit#4803). Their completion
209
+ // notice is delivered only when a tool call ends, so one long hand-written loop holds it back until the
210
+ // loop itself gives up; short foreground calls, one at a time, let it in at the first one to end.
211
+ const LANE_AGENT_STOP_REASON =
212
+ '⛔ lane agent stop: this is a dispatched lane child (`JOSH_LANE_CHILD`) and a subagent it launched ' +
213
+ 'has not finished; ending this turn kills it. Its completion notice arrives only when a tool call ' +
214
+ 'ends: wait with one short foreground call at a time (`sleep 20`) until it arrives — never a loop ' +
215
+ 'over its `.output`. Do not notify, stop or repeat your reply.'
216
+
197
217
  // The row itself, so `delivered-rules.ts` spreads one entry. It fires on every occurrence (`decide`
198
218
  // returns true): a child must never background these, so the route is always the detached ship, never
199
219
  // a reissue. It declares no `keeps`: the detached ship is a different command, not this call made right.
@@ -202,17 +222,24 @@ const ROW = {
202
222
  is_trigger: (call: GuardedCall): boolean => is_background_long_run(call),
203
223
  reason: LANE_BACKGROUND_REASON,
204
224
  decide: (): boolean => true,
225
+ // `pretool-guard.ts` rewrites a lone `josh ship` to the foreground rather than refusing it; this is
226
+ // the note it attaches, so `rule-value.ts` counts that rewrite as this row's delivery.
227
+ rewrite_note: FOREGROUND_NOTE,
228
+ // The Stop hook delivers the same rule at the turn's end, for the background task or subagent the
229
+ // turn would kill.
230
+ stop_reasons: [LANE_BACKGROUND_STOP_REASON, LANE_AGENT_STOP_REASON],
205
231
  about: {
206
232
  title: 'Lane child background push',
207
233
  topic: '`.claude/skills/workflow-commands/background-commands.md`',
208
234
  fires:
209
- 'a dispatched lane child backgrounding `josh gate` / `git` / `followup` / `ship`; it hands over `pnpm josh ship --detach`. Every occurrence',
235
+ 'a dispatched lane child backgrounding `josh gate` / `git` / `followup` / `ship`; it hands over `pnpm josh ship --detach`; the Stop hook also blocks ending a turn with its background task or subagent unfinished. Every occurrence',
210
236
  quiet: 'not a lane child, or the foreground `ship --detach`',
211
237
  },
212
238
  }
213
239
 
214
240
  const lane_background = {
215
241
  FOREGROUND_NOTE,
242
+ LANE_AGENT_STOP_REASON,
216
243
  LANE_BACKGROUND_REASON,
217
244
  LANE_BACKGROUND_STOP_REASON,
218
245
  ROW,
@@ -220,6 +247,7 @@ const lane_background = {
220
247
  is_background_long_run,
221
248
  pending_agent_ids,
222
249
  pending_background_ids,
250
+ pending_command_ids,
223
251
  }
224
252
 
225
253
  export { lane_background }
@@ -1,6 +1,13 @@
1
- import { command_memory } from '#scripts/gate/command-memory'
1
+ import os from 'node:os'
2
+ import { cost_blocks } from '#scripts/cost-runtime/cost-blocks'
3
+ import { command_memory, type ToolCall } from '#scripts/gate/command-memory'
4
+ import { core_weights } from '#scripts/gate/core-weights'
2
5
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
6
+ import { json_value } from '#scripts/lib/json-value'
7
+ import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
8
+ import { time_shell } from '#scripts/time-runtime/time-shell'
3
9
  import { bash_triggers } from './bash-triggers'
10
+ import { timed_rerun } from './timed-rerun'
4
11
 
5
12
  // A dispatched lane child is stopped from running a heavy tool directly. The core budget
6
13
  // (`scripts/gate/core-budget.ts`) counts only what a `josh` command reserves, so an `eslint`, `vitest`,
@@ -20,16 +27,102 @@ import { bash_triggers } from './bash-triggers'
20
27
  //
21
28
  // **Lane children only.** An interactive session outside a lane keeps its direct runs; the overlap this
22
29
  // prevents is between concurrently dispatched lanes.
30
+ //
31
+ // **The commonest direct run is rewritten rather than refused** (joshuafolkken/kit#5147): the refusal's
32
+ // reissue was the same line behind `pnpm josh reserved-run <weight> --`, a round trip the hook can make
33
+ // itself. The weight is the gate's own for that tool — `core_weights.CORE_WEIGHTS`, and for vitest the
34
+ // workers `command_memory.workers_of` reads — so the claim matches what the gate claims. `reserved-run`
35
+ // runs its command as an argv, not a shell line, so only a line that is one command is wrapped: any
36
+ // chain, pipe, redirection, group, substitution, comment, env prefix or timer leaves it to the refusal,
37
+ // as does a multi-worker eslint, which no reservation makes safe. The wrapped line runs in the directory
38
+ // it was typed in (`reserved-run.ts` → `command_directory`).
23
39
 
24
- const HEAVY_TOOLS: ReadonlySet<string> = new Set(['eslint', 'vitest', 'cspell', 'tsc'])
40
+ const ESLINT = 'eslint'
41
+ const VITEST = 'vitest'
42
+ const HEAVY_TOOLS: ReadonlySet<string> = new Set([ESLINT, VITEST, 'cspell', 'tsc'])
43
+ const TOOL_WEIGHTS: Readonly<Partial<Record<string, number>>> = {
44
+ [ESLINT]: core_weights.CORE_WEIGHTS.lint,
45
+ tsc: core_weights.CORE_WEIGHTS.type_check,
46
+ cspell: core_weights.CORE_WEIGHTS.spell_check,
47
+ }
48
+ const SINGLE_CORE = 1
49
+ const RESERVED_RUN = 'pnpm josh reserved-run'
50
+ // Read on the quote-blanked line: a quoted `;` or `|` is text. `2>&1` applies to the wrapper alike.
51
+ const MULTI_COMMAND_SYNTAX = /[;|&<>()`#\n]|\$\(/u
52
+ const KEPT_REDIRECT = /2>&1/gu
53
+ const ENV_ASSIGNMENT = /^[A-Za-z_]\w*=/u
25
54
 
26
- // True when any command on the shell line launches one of the heavy tools outside a `reserved-run`.
27
- // The cut is quote-aware, so a tool name inside a quoted argument (`git commit -m "run eslint"`) is
28
- // never read as a command; a quoted script handed to a shell is.
29
- function runs_heavy_tool(command: string): boolean {
55
+ const RESERVED_NOTE =
56
+ '↻ lane direct tool: a lane child ran a heavy tool directly, so the line was wrapped in ' +
57
+ '`pnpm josh reserved-run <weight> --` to claim its cores beside the other lanes. Prefer ' +
58
+ '`pnpm josh lint:related` / `test:related` / `cspell:dot` — `docs/josh-commands-automation.md`.'
59
+
60
+ // The heavy tools the line launches outside a `reserved-run`. The cut is quote-aware, so a tool name
61
+ // inside a quoted argument (`git commit -m "run eslint"`) is never read as a command; a quoted script
62
+ // handed to a shell is.
63
+ function direct_calls(command: string): Array<ToolCall> {
30
64
  return command_memory
31
65
  .tool_calls_of(command)
32
- .some((call) => !call.is_reserved && HEAVY_TOOLS.has(call.name))
66
+ .filter((call) => !call.is_reserved && HEAVY_TOOLS.has(call.name))
67
+ }
68
+
69
+ // True when any command on the shell line launches one of the heavy tools outside a `reserved-run`.
70
+ function runs_heavy_tool(command: string): boolean {
71
+ return direct_calls(command).length > 0
72
+ }
73
+
74
+ function weight_of(call: ToolCall, cores: number): number {
75
+ if (call.name === VITEST) return command_memory.workers_of(call, cores)
76
+
77
+ return TOOL_WEIGHTS[call.name] ?? SINGLE_CORE
78
+ }
79
+
80
+ // True when the whole line is one command, so a `reserved-run` can carry it as its argv.
81
+ function is_one_command(command: string): boolean {
82
+ const judged = time_shell.blanked(command)
83
+
84
+ if (judged === undefined) return false
85
+
86
+ return (
87
+ !MULTI_COMMAND_SYNTAX.test(judged.replaceAll(KEPT_REDIRECT, ' ')) &&
88
+ !ENV_ASSIGNMENT.test(judged)
89
+ )
90
+ }
91
+
92
+ // A timed line stays as typed: `timed-rerun` reads the timer at the segment start, and a wrapper in front
93
+ // would hide it from that row.
94
+ function can_wrap(line: string, cores: number): boolean {
95
+ if (!is_one_command(line) || timed_rerun.is_timed_run(line)) return false
96
+
97
+ return !command_memory.runs_multi_worker_eslint(line, cores)
98
+ }
99
+
100
+ // The line behind `reserved-run` at its largest tool's weight, or `undefined` where it must be refused.
101
+ function reserved_command(
102
+ command: string,
103
+ cores: number = os.availableParallelism(),
104
+ ): string | undefined {
105
+ const line = command.trim()
106
+ const calls = direct_calls(line)
107
+
108
+ if (!can_wrap(line, cores) || calls.length === 0) return undefined
109
+
110
+ const weight = Math.max(...calls.map((call) => weight_of(call, cores)))
111
+
112
+ return `${RESERVED_RUN} ${String(weight)} -- ${line}`
113
+ }
114
+
115
+ function is_lane_bash(call: GuardedCall): boolean {
116
+ return call.name === cost_blocks.BASH_TOOL && lane_child_marker.is_child_of(process.cwd())
117
+ }
118
+
119
+ // The call's input with its line wrapped, for a lane child alone; `undefined` where nothing is rewritten.
120
+ function reserved_input(call: GuardedCall): Record<string, unknown> | undefined {
121
+ if (!is_lane_bash(call) || !json_value.is_record(call.input)) return undefined
122
+
123
+ const command = reserved_command(time_shell.bash_command(call.input))
124
+
125
+ return command === undefined ? undefined : { ...call.input, command }
33
126
  }
34
127
 
35
128
  // True when this session is a dispatched lane child launching a heavy tool directly, or eslint with
@@ -47,7 +140,7 @@ const LANE_DIRECT_TOOL_REASON =
47
140
  '⛔ lane child running `eslint` / `vitest` / `cspell` / `tsc` directly, or multi-worker eslint: ' +
48
141
  'it overlaps the other lanes. Run `pnpm josh lint:related`, `pnpm josh test:related`, ' +
49
142
  '`pnpm josh cspell:dot` or `pnpm josh reserved-run <weight> -- <command>`, eslint at ' +
50
- '`--concurrency off`; measure concurrency outside a lane. Refused on every occurrence.'
143
+ '`--concurrency off`. Only a one-command line is wrapped for you. Refused on every occurrence.'
51
144
 
52
145
  // The row itself, so `delivered-rules.ts` spreads one entry; the shape is `lane-switch-main.ts`'s.
53
146
  const ROW = {
@@ -55,19 +148,24 @@ const ROW = {
55
148
  is_trigger: bash_triggers.on_bash_command(is_lane_direct_tool),
56
149
  reason: LANE_DIRECT_TOOL_REASON,
57
150
  decide: (): boolean => true,
151
+ rewrite: reserved_input,
152
+ rewrite_note: RESERVED_NOTE,
58
153
  about: {
59
154
  title: 'Lane child running a heavy tool directly',
60
155
  topic: '`docs/josh-commands-automation.md` → `josh reserved-run`',
61
156
  fires:
62
- 'a dispatched lane child launching `eslint` / `vitest` / `cspell` / `tsc` (bare, `pnpm exec`, `npx`, inside `sh -c`), or eslint with `--concurrency` other than `off` / `1` by any path, `reserved-run` included. Every occurrence',
157
+ "a dispatched lane child launching `eslint` / `vitest` / `cspell` / `tsc` (bare, `pnpm exec`, `npx`, inside `sh -c`), or eslint with `--concurrency` other than `off` / `1` by any path, `reserved-run` included. A one-command line is rewritten behind `pnpm josh reserved-run <weight> --` at the gate's weight; a chained, piped, redirected or env-prefixed line and a multi-worker eslint are refused, every occurrence",
63
158
  quiet: 'not a lane child, or the run goes through `pnpm josh` with single-worker eslint',
64
159
  },
65
160
  }
66
161
 
67
162
  const lane_direct_tool = {
68
163
  LANE_DIRECT_TOOL_REASON,
164
+ RESERVED_NOTE,
69
165
  ROW,
70
166
  is_lane_direct_tool,
167
+ reserved_command,
168
+ reserved_input,
71
169
  runs_heavy_tool,
72
170
  }
73
171
 
@@ -1,6 +1,7 @@
1
1
  import { interactive_ask } from '#scripts/agent/interactive-ask'
2
2
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
3
3
  import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
4
+ import { stop_rules } from './stop-rules'
4
5
 
5
6
  // A dispatched lane child's interactive ask is refused and routed to the park procedure, delivered at
6
7
  // the call it binds on.
@@ -55,12 +56,14 @@ const ROW = {
55
56
  is_trigger: is_interactive_ask,
56
57
  reason: LANE_INTERACTIVE_ASK_REASON,
57
58
  decide: (): boolean => true,
59
+ // A reply asking a person for the git index is the same ask, delivered by the Stop hook.
60
+ stop_reasons: [stop_rules.LANE_INDEX_REASON],
58
61
  about: {
59
62
  title: 'Lane child interactive ask',
60
63
  topic:
61
64
  '`.claude/skills/workflow-commands/pre-gate-cut.md` → "The interactive ask is refused one call earlier"',
62
65
  fires:
63
- "a dispatched lane child's `AskUserQuestion`; it hands over the park procedure. Every occurrence",
66
+ "a dispatched lane child's `AskUserQuestion`; it hands over the park procedure; the Stop hook also blocks a reply asking a person for the git index. Every occurrence",
64
67
  quiet: 'not a lane child, or not an interactive tool',
65
68
  },
66
69
  }
@@ -122,14 +122,16 @@ function records_the_park(command: string): boolean {
122
122
  }
123
123
 
124
124
  // The instruction in the shape a refusal can carry: what the stop must leave behind, how to record it,
125
- // and the reissue sentence every delivery needs. **The park procedure is named, not restated** — the
125
+ // and that the park is the stop itself — no notify follows it, since the `Stop` hook sends one still owed
126
+ // on the hold (`stop-rules.ts` → `needs_notify`). **The park procedure is named, not restated** — the
126
127
  // single source is `backlogrun-park.md` → "park and continue", and a second copy here would be the
127
128
  // clone `CLAUDE.md` prohibits.
128
129
  const LANE_PARK_REASON =
129
130
  '⛔ lane child park: this session is a dispatched lane child, so a stop for a person parks first: ' +
130
131
  '`pnpm josh run:park <N> --body-file <path>` (question, options, stash — it applies ' +
131
132
  '`needs-decision`); a ' +
132
- '`needs-human-review` / `already-done` stop already is. Reissue this notify, once per run ' +
133
+ '`needs-human-review` / `already-done` stop already is. The park is the stop: no notify ' +
134
+ 'after it. Refused once per run ' +
133
135
  '(`.claude/skills/workflow-commands/pre-gate-cut.md`).'
134
136
 
135
137
  // The row itself, so `delivered-rules.ts` spreads one entry. **Once per run rather than `decide`.** The
@@ -0,0 +1,90 @@
1
+ import { lane_child_marker } from '#scripts/lane/lane-child-marker'
2
+ import { json_value } from '#scripts/lib/json-value'
3
+ import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
4
+
5
+ // A dispatched lane child's whole `Read` of a spilled Bash result is refused and pointed at a narrowed
6
+ // read (joshuafolkken/kit#5040).
7
+ //
8
+ // **The spill is the largest single result a cut session carries.** A Bash result over the harness cap
9
+ // is saved to `tool-results/<id>.txt` and previewed; reading that file back whole put 10,000–18,000
10
+ // characters into the context in one call, 10–40% of a cut session's tool results. A `grep` or
11
+ // `sed -n` over the same file reads only the lines the run needs.
12
+ //
13
+ // **Lane children only, every occurrence.** The cut that the context growth triggers is a lane
14
+ // child's; a person in an interactive session keeps the whole read. A paginated `Read` (an `offset` or
15
+ // a `limit`) is already narrowed and passes.
16
+
17
+ const SPILLED_RESULT = /\/tool-results\/[^/]+\.txt$/u
18
+
19
+ function read_input(call: GuardedCall): Record<string, unknown> | undefined {
20
+ if (call.name !== 'Read' || !json_value.is_record(call.input)) return undefined
21
+
22
+ return call.input
23
+ }
24
+
25
+ function reads_spilled_result(input: Record<string, unknown>): boolean {
26
+ const { file_path } = input
27
+
28
+ return typeof file_path === 'string' && SPILLED_RESULT.test(file_path)
29
+ }
30
+
31
+ function is_paginated(input: Record<string, unknown>): boolean {
32
+ return input['offset'] !== undefined || input['limit'] !== undefined
33
+ }
34
+
35
+ // The occasion the rule governs: any `Read` of a spilled result, whole or narrowed.
36
+ function reaches_spilled_result(call: GuardedCall): boolean {
37
+ const input = read_input(call)
38
+
39
+ return input !== undefined && reads_spilled_result(input)
40
+ }
41
+
42
+ // Keeping the rule: the spilled result read with a page, never whole.
43
+ function keeps_narrowed_read(call: GuardedCall): boolean {
44
+ const input = read_input(call)
45
+
46
+ return input !== undefined && reads_spilled_result(input) && is_paginated(input)
47
+ }
48
+
49
+ function is_whole_spilled_read(
50
+ call: GuardedCall,
51
+ is_lane_child: boolean = lane_child_marker.is_child_of(process.cwd()),
52
+ ): boolean {
53
+ if (!reaches_spilled_result(call) || keeps_narrowed_read(call)) return false
54
+
55
+ return is_lane_child
56
+ }
57
+
58
+ const LANE_SPILLED_READ_REASON =
59
+ '⛔ lane child reading a spilled Bash result whole: `tool-results/<id>.txt` is the output that ' +
60
+ 'overflowed the cap, and reading it back whole fills the context the cut is measured on. Read only ' +
61
+ 'the lines you need: `grep -n <pattern> <path>` or `sed -n <from>,<to>p <path>`. ' +
62
+ 'Refused on every occurrence.'
63
+
64
+ // The row itself, so `delivered-rules.ts` spreads one entry; the shape is `lane-direct-tool.ts`'s, with
65
+ // the narrowed read as its compliance call.
66
+ const ROW = {
67
+ id: 'lane-spilled-read',
68
+ is_trigger: is_whole_spilled_read,
69
+ reason: LANE_SPILLED_READ_REASON,
70
+ decide: (): boolean => true,
71
+ keeps: keeps_narrowed_read,
72
+ reaches: reaches_spilled_result,
73
+ about: {
74
+ title: 'Lane child reading a spilled Bash result whole',
75
+ topic: '`prompts/collaboration-workflow/output-bounds.md`',
76
+ fires:
77
+ "a dispatched lane child's `Read` of a `tool-results/<id>.txt` file with no `offset` or `limit`. Every occurrence",
78
+ quiet: 'not a lane child, another file, or a paginated `Read`',
79
+ },
80
+ }
81
+
82
+ const lane_spilled_read = {
83
+ LANE_SPILLED_READ_REASON,
84
+ ROW,
85
+ is_whole_spilled_read,
86
+ keeps_narrowed_read,
87
+ reaches_spilled_result,
88
+ }
89
+
90
+ export { lane_spilled_read }
@@ -17,7 +17,7 @@ import { tail_commands } from './tail-commands'
17
17
  // carries `epic` as a split (`run-merge.ts`), so the label is never what tells it.
18
18
  //
19
19
  // **The material is the run's own calls.** The promotion is a `josh epic --promote <N>` this run issued,
20
- // read off the transcript tail as `filing-cap.ts` reads its filings — a tool call, never prose, so a
20
+ // read off the transcript tail as `turn-filings.ts` reads its filings — a tool call, never prose, so a
21
21
  // child that merely read a document quoting the command is not mistaken for one that ran it. Only a
22
22
  // promotion of the dispatched issue counts: the epic a mid-run split promotes is the child's own Issue.
23
23
 
@@ -19,8 +19,8 @@ import { shell_segments } from './shell-segments'
19
19
  //
20
20
  // **It refuses rather than rewrites, because a `PreToolUse` guard can only `allow` / `deny` a command,
21
21
  // never substitute a different one**. So the refusal hands back the next command: the lane is already on its own issue
22
- // branch, branched from a fresh default before it opened, and the latest default is brought in during the
23
- // gate by `pnpm josh main:merge` — so skip the step and keep implementing on the current branch.
22
+ // branch, branched from a fresh default before it opened, and the latest default is brought in before the
23
+ // gate by `josh ship`'s sync — so skip the step and keep implementing on the current branch.
24
24
  //
25
25
  // **The branch is judged against the lane's own, not the name `main`.** `already used by worktree` is a
26
26
  // property of any branch the primary work tree holds, not of the literal `main`, and the default branch
@@ -108,8 +108,8 @@ function is_switch_away_from_lane(
108
108
  const LANE_SWITCH_MAIN_REASON =
109
109
  '⛔ lane child on `git switch main`: this session is a dispatched lane child, and switching to the ' +
110
110
  'default branch here always fails (`already used by worktree`: the primary checkout holds it). Skip ' +
111
- 'this step and keep implementing on the current branch; `pnpm josh main:merge` brings the default ' +
112
- 'in during the gate. Refused on every occurrence (`backlogrun-lanes.md`, `backlogrun-child.md`).'
111
+ "this step and keep implementing on the current branch; `pnpm josh ship`'s sync brings the default " +
112
+ 'in before its gate. Refused on every occurrence (`backlogrun-lanes.md`, `backlogrun-child.md`).'
113
113
 
114
114
  // The row itself, so `delivered-rules.ts` spreads one entry. `is_trigger` reads the input through
115
115
  // `on_bash_command` — the `Bash` tool-name gate every command row shares — and `decide` returns true so
@@ -1,32 +1,18 @@
1
1
  import { json_value } from '#scripts/lib/json-value'
2
2
  import { time_reported_failure } from '#scripts/time-runtime/time-reported-failure'
3
3
  import { z } from 'zod'
4
- import { filing_cap } from './filing-cap'
4
+ import { turn_filings } from './turn-filings'
5
5
 
6
- // The text of the person's last prompt on a transcript tail — what the stop guard's citation row
7
- // reads to tell a `#N` the person quoted from one the run brought in itself.
6
+ // The person's prompts on a transcript tail — what the stop guard reads to tell a question it answers
7
+ // and the pause a recorded notify belongs to.
8
8
  //
9
- // **A prompt is `filing_cap`'s prompt line, minus what the harness wrote there.** A skill's body is a
9
+ // **A prompt is `turn_filings`' prompt line, minus what the harness wrote there.** A skill's body is a
10
10
  // `user` line with no tool result too, but it carries `isMeta`; a background task's completion notice
11
11
  // and a subagent's hand-back carry an `origin` whose `kind` is not `human`. Each is the harness
12
- // speaking, not the person — and a notice can name the very Issue the run filed — so only a line with
13
- // no `origin` (an SDK prompt) or a `human` one is read.
14
- //
15
- // **A workflow invocation quotes nothing.** `fullrun #2819` names this repository's own Issue, so a
16
- // bare `#2819` in that run's report is a citation slip like any other, and the prompt yields no text —
17
- // a resumed lane child's prompt included, since it ends on the same invocation.
18
-
19
- const WORKFLOW_KEYWORDS: ReadonlySet<string> = new Set([
20
- 'kickoff',
21
- 'fullrun',
22
- 'halfrun',
23
- 'prrun',
24
- 'backlogrun',
25
- ])
12
+ // speaking, not the person, so only a line with no `origin` (an SDK prompt) or a `human` one is read.
13
+
26
14
  const NO_PROMPT = ''
27
15
  const HUMAN_ORIGIN = 'human'
28
- // The word before the prompt's last one — where a trailing `fullrun #N` puts its keyword.
29
- const KEYWORD_BEFORE_ARGUMENT = -2
30
16
 
31
17
  const PROMPT_LINE_SCHEMA = z.object({
32
18
  isMeta: z.boolean().nullish(),
@@ -61,45 +47,32 @@ function person_text(line: string): string | undefined {
61
47
  return time_reported_failure.result_text(person.message.content)
62
48
  }
63
49
 
64
- // A keyword opening the prompt is what a person types; a keyword before its one trailing argument is a
65
- // lane child's resume prompt, whose preamble ends on `fullrun #N` (`lane-child-invocation.ts`).
66
- function is_invocation(prompt: string): boolean {
67
- const words = prompt.trim().split(/\s+/u)
68
-
69
- return [words.at(0), words.at(KEYWORD_BEFORE_ARGUMENT)].some((word) =>
70
- WORKFLOW_KEYWORDS.has(word ?? NO_PROMPT),
71
- )
72
- }
73
-
74
- function prompt_line_text(line: string): string | undefined {
75
- return filing_cap.is_prompt_line(line) ? person_text(line) : undefined
76
- }
77
-
78
- // The last person prompt on the tail; '' when none is on it or it is an invocation.
79
- function prompt_text(tail: string): string {
80
- const text = tail
81
- .split('\n')
82
- .map((line) => prompt_line_text(line))
83
- .findLast((one) => one !== undefined)
84
-
85
- return text === undefined || is_invocation(text) ? NO_PROMPT : text
86
- }
87
-
88
50
  // **The prompt that opened this turn, when a person typed it** — '' when the harness opened it (a task
89
51
  // notification, a subagent's hand-back), so a question asked turns ago does not answer for a stop the
90
52
  // run reached on its own since (`stop-decision.ts` → `is_question`).
91
53
  function turn_prompt(tail: string): string {
92
- const opener = tail.split('\n').findLast((line) => filing_cap.is_prompt_line(line))
54
+ const opener = tail.split('\n').findLast((line) => turn_filings.is_prompt_line(line))
93
55
  if (opener === undefined) return NO_PROMPT
94
56
 
95
57
  return person_text(opener) ?? NO_PROMPT
96
58
  }
97
59
 
60
+ // **The person's last prompt on the tail**, past what the harness wrote after it (a skill body, a task
61
+ // notification) — `undefined` when no prompt of theirs is on it, so an unread prompt is told apart
62
+ // from one that asked nothing.
63
+ function person_prompt(tail: string): string | undefined {
64
+ return tail
65
+ .split('\n')
66
+ .filter((line) => turn_filings.is_prompt_line(line))
67
+ .map((line) => person_text(line))
68
+ .findLast((text) => text !== undefined)
69
+ }
70
+
98
71
  // When the person last prompted on the tail, or `undefined` when no prompt of theirs is on it.
99
72
  function prompt_time(tail: string): string | undefined {
100
73
  return tail
101
74
  .split('\n')
102
- .filter((line) => filing_cap.is_prompt_line(line))
75
+ .filter((line) => turn_filings.is_prompt_line(line))
103
76
  .map((line) => person_line(line)?.timestamp ?? undefined)
104
77
  .findLast((time) => time !== undefined)
105
78
  }
@@ -120,6 +93,6 @@ function pause_start(tail: string): string | undefined {
120
93
  return prompt_time(tail) ?? tail_time(tail)
121
94
  }
122
95
 
123
- const last_prompt = { pause_start, prompt_text, turn_prompt }
96
+ const last_prompt = { pause_start, person_prompt, turn_prompt }
124
97
 
125
98
  export { last_prompt }
@@ -80,7 +80,7 @@ function row_for(oracle: Oracle, firing_point: FiringPoint): DeliveredRule {
80
80
 
81
81
  // One row per oracle that declared a firing point, in registry order. Spread into `DELIVERED_RULES`
82
82
  // after the filing rows, so a firing point that overlaps a filing (`issue:lint`) delivers on the
83
- // reissue rather than ahead of `filing-cap`.
83
+ // reissue rather than ahead of the filing rows.
84
84
  const ROWS: ReadonlyArray<DeliveredRule> = oracle_firing
85
85
  .firing_oracles()
86
86
  .map(({ oracle, firing_point }) => row_for(oracle, firing_point))
@@ -3,6 +3,7 @@ import { direct_pr_create } from './direct-pr-create'
3
3
  import { index_guard } from './index-guard'
4
4
  import { pr_merge } from './pr-merge'
5
5
  import { protected_files } from './protected-files'
6
+ import { repo_admin } from './repo-admin'
6
7
 
7
8
  // The three rows that close the deny-list bypasses, gathered so
8
9
  // `delivered-rules.ts` spreads one entry. Each reads argv or a file path rather than a glob: an index
@@ -11,13 +12,16 @@ import { protected_files } from './protected-files'
11
12
  // other row's — `git restore` is split with `worktree-mutation` by `--staged` alone. The fourth row,
12
13
  // `direct-pr-create`, closes the same kind of gap for `gh pr create`, which
13
14
  // the deny list never listed: it claims `gh pr create` and a `gh api` write to the pulls collection.
14
- // The fifth, `pr-merge`, claims a merge in every spelling the `gh pr merge*` glob misses.
15
+ // The fifth, `pr-merge`, claims a merge in every spelling the `gh pr merge*` glob misses. The sixth,
16
+ // `repo-admin`, claims a non-`DELETE` write to the repository's administration, which
17
+ // `destructive-command` leaves open.
15
18
  const ROWS = [
16
19
  index_guard.ROW,
17
20
  destructive_command.ROW,
18
21
  protected_files.ROW,
19
22
  direct_pr_create.ROW,
20
23
  pr_merge.ROW,
24
+ repo_admin.ROW,
21
25
  ] as const
22
26
 
23
27
  const permission_guards = { ROWS }