@joshuafolkken/kit 1.1229.0 → 1.1370.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 (939) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +24 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +27 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +18 -29
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.github/workflows/publish.yml +2 -0
  42. package/.vscode/tasks.json +14 -0
  43. package/CLAUDE.md +10 -61
  44. package/README.md +38 -57
  45. package/SECURITY.md +1 -1
  46. package/dist/CLAUDE.md +10 -61
  47. package/dist/commands/document-section-cli.js +42 -10
  48. package/dist/config-merge/index.js +11 -2
  49. package/dist/hooks/audit-provision.js +2 -2
  50. package/dist/hooks/batch-guard.js +7 -7
  51. package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
  52. package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
  53. package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
  54. package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
  55. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  56. package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
  57. package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
  58. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  59. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  60. package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
  61. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  62. package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
  63. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  64. package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
  65. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  66. package/dist/hooks/codex-hook-adapter.js +26 -21
  67. package/dist/hooks/duplicate-read-guard.js +8 -8
  68. package/dist/hooks/format-edited.js +4 -4
  69. package/dist/hooks/inputs.json +213 -197
  70. package/dist/hooks/investigation-guard.js +8 -8
  71. package/dist/hooks/pretool-guard.js +15 -15
  72. package/dist/hooks/session-lang.js +406 -8
  73. package/dist/hooks/stop-guard.js +122 -201
  74. package/dist/josh.js +540 -137
  75. package/dist/version/index.js +15 -13
  76. package/eslint/base.js +43 -5
  77. package/eslint/rules/english-only-prose.js +3 -3
  78. package/eslint/rules/import.js +12 -0
  79. package/eslint/rules/namespace-object-export.js +2 -2
  80. package/package.json +16 -10
  81. package/pnpm-workspace.yaml +2 -4
  82. package/prompts/coding-standards.md +14 -48
  83. package/prompts/collaboration-workflow/file-edits.md +1 -1
  84. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  85. package/prompts/collaboration-workflow/issue-template.md +4 -10
  86. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  87. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  88. package/prompts/collaboration-workflow/overview.md +1 -1
  89. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  90. package/prompts/collaboration-workflow/principles.md +21 -3
  91. package/prompts/collaboration-workflow/report-format.md +16 -29
  92. package/prompts/collaboration-workflow/residency.md +1 -1
  93. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  94. package/prompts/collaboration-workflow/shell-body.md +3 -23
  95. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  96. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  97. package/prompts/refactoring.md +1 -1
  98. package/prompts/review-rubric.md +3 -22
  99. package/prompts/review.md +15 -38
  100. package/prompts/testing-guide.md +2 -4
  101. package/scripts/adopt/adopt-logic.ts +5 -5
  102. package/scripts/adopt/adopt-toolkits.ts +4 -5
  103. package/scripts/adopt/adopt.ts +2 -3
  104. package/scripts/agent/agent-argv.ts +7 -7
  105. package/scripts/agent/agent-diagnostics.ts +2 -2
  106. package/scripts/agent/agent-exit-record.ts +1 -1
  107. package/scripts/agent/agent-headless.ts +1 -1
  108. package/scripts/agent/agent-launch-environment.ts +6 -1
  109. package/scripts/agent/agent-role-profile.ts +49 -22
  110. package/scripts/agent/agent-session-role.ts +32 -0
  111. package/scripts/agent/api-outage.ts +1 -1
  112. package/scripts/agent/claude-agent-argv.ts +4 -4
  113. package/scripts/agent/claude-result-event.ts +4 -4
  114. package/scripts/agent/codex-hooks.ts +2 -2
  115. package/scripts/agent/interactive-ask.ts +3 -6
  116. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  117. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  118. package/scripts/backlog/backlog-arrival.ts +54 -17
  119. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  120. package/scripts/backlog/backlog-budget.ts +17 -24
  121. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  122. package/scripts/backlog/backlog-drive-args.ts +5 -4
  123. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  124. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  125. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  126. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  127. package/scripts/backlog/backlog-drive-named.ts +39 -9
  128. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  129. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  130. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  131. package/scripts/backlog/backlog-drive.ts +43 -28
  132. package/scripts/backlog/backlog-idle.ts +88 -0
  133. package/scripts/backlog/backlog-named.ts +11 -15
  134. package/scripts/backlog/backlog-next.ts +26 -30
  135. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  136. package/scripts/backlog/backlog-offer.ts +7 -7
  137. package/scripts/backlog/backlog-overlap.ts +178 -0
  138. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  139. package/scripts/backlog/backlog-plan-read.ts +111 -0
  140. package/scripts/backlog/backlog-plan.ts +11 -10
  141. package/scripts/backlog/backlog-pool.ts +13 -14
  142. package/scripts/backlog/backlog-rank.ts +11 -11
  143. package/scripts/backlog/backlog-ready.ts +15 -10
  144. package/scripts/backlog/backlog-scope.ts +14 -15
  145. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  146. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  147. package/scripts/backlog/backlog-stalled.ts +5 -6
  148. package/scripts/backlog/backlog-waves.ts +4 -4
  149. package/scripts/backlog/backlogrun-args.ts +74 -0
  150. package/scripts/backlog/backlogrun-cli.ts +113 -0
  151. package/scripts/backlog/backlogrun-launch.ts +178 -0
  152. package/scripts/behavior/behavior-assertion.ts +6 -8
  153. package/scripts/behavior/behavior-cli.ts +1 -1
  154. package/scripts/behavior/behavior-rules.ts +3 -3
  155. package/scripts/build/build-claude-md.ts +4 -4
  156. package/scripts/build/build-codex-hooks.ts +2 -2
  157. package/scripts/build/build-commands.ts +1 -1
  158. package/scripts/build/build-hooks.ts +5 -5
  159. package/scripts/build/build.ts +1 -1
  160. package/scripts/build/hook-bundle-stamp.ts +109 -7
  161. package/scripts/build/local-bin.ts +2 -2
  162. package/scripts/cases/cases-cli.ts +1 -1
  163. package/scripts/cases/cases-logic.ts +2 -2
  164. package/scripts/ci/composite-actions.ts +1 -2
  165. package/scripts/ci/pr-classification.ts +2 -2
  166. package/scripts/claude/workflow-destination.ts +1 -1
  167. package/scripts/clone/clone-aggregate.ts +1 -1
  168. package/scripts/clone/clone-fingerprint.ts +1 -1
  169. package/scripts/clone/clone-scan-cli.ts +1 -1
  170. package/scripts/clone/clone-scan.ts +1 -1
  171. package/scripts/config-merge/index.ts +1 -1
  172. package/scripts/config-merge/json-format.ts +1 -3
  173. package/scripts/config-merge/patch-json-array.ts +90 -0
  174. package/scripts/config-merge/patch-json-key.ts +6 -3
  175. package/scripts/config-merge/patch-json-list.ts +1 -1
  176. package/scripts/cost-runtime/codex-usage.ts +1 -1
  177. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  178. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  179. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  180. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  181. package/scripts/cost-runtime/cost-cli.ts +14 -11
  182. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  183. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  184. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  185. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  186. package/scripts/cost-runtime/cost-usage.ts +6 -7
  187. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  188. package/scripts/cost-runtime/own-session.ts +1 -1
  189. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  190. package/scripts/delegation/delegation-cli.ts +4 -4
  191. package/scripts/delegation/delegation-policy.ts +13 -15
  192. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  193. package/scripts/delegation/fanout-cli.ts +1 -1
  194. package/scripts/delegation/fanout.ts +1 -1
  195. package/scripts/delegation/investigation-guard.ts +18 -22
  196. package/scripts/delegation/investigation-reads.ts +48 -238
  197. package/scripts/discovery/repo-discovery.ts +1 -1
  198. package/scripts/discovery/repo-map-logic.ts +1 -2
  199. package/scripts/discovery/repo-origin.ts +3 -3
  200. package/scripts/discovery/repo-party-cli.ts +2 -2
  201. package/scripts/discovery/repo-party.ts +2 -2
  202. package/scripts/doctor/doctor-consumer.ts +1 -1
  203. package/scripts/doctor/doctor-io.ts +6 -7
  204. package/scripts/doctor/doctor-logic.ts +1 -1
  205. package/scripts/doctor/doctor-ports.ts +1 -1
  206. package/scripts/doctor/doctor.ts +8 -9
  207. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  208. package/scripts/document/bash-output-cap.ts +5 -7
  209. package/scripts/document/capped-print-part.ts +1 -1
  210. package/scripts/document/capped-print.ts +1 -1
  211. package/scripts/document/document-byte-budget.ts +33 -64
  212. package/scripts/document/document-byte-check.ts +4 -4
  213. package/scripts/document/document-reachability.ts +7 -8
  214. package/scripts/document/document-read-cli.ts +2 -2
  215. package/scripts/document/document-scan.ts +26 -2
  216. package/scripts/document/document-section-cli.ts +6 -8
  217. package/scripts/document/document-section.ts +8 -12
  218. package/scripts/document/edit-files-cli.ts +3 -4
  219. package/scripts/document/entry-read-budget.ts +8 -70
  220. package/scripts/document/entry-read-set.ts +51 -34
  221. package/scripts/document/lane-child-read-set.ts +9 -9
  222. package/scripts/document/read-files-cli.ts +1 -2
  223. package/scripts/document/read-set-cli.ts +16 -19
  224. package/scripts/document/read-set-cost.ts +4 -4
  225. package/scripts/document/read-set-point-of-use.ts +28 -38
  226. package/scripts/document/read-set-pricing.ts +1 -1
  227. package/scripts/document/read-set-trim.ts +3 -3
  228. package/scripts/document/resident-budget.ts +8 -10
  229. package/scripts/epic/epic-add-body.ts +15 -18
  230. package/scripts/epic/epic-add-plan.ts +26 -28
  231. package/scripts/epic/epic-add.ts +32 -25
  232. package/scripts/epic/epic-audit-checks.ts +27 -37
  233. package/scripts/epic/epic-audit-cli.ts +21 -22
  234. package/scripts/epic/epic-audit-orphans.ts +16 -17
  235. package/scripts/epic/epic-audit-rationale.ts +10 -15
  236. package/scripts/epic/epic-audit-report.ts +2 -5
  237. package/scripts/epic/epic-audit.ts +18 -14
  238. package/scripts/epic/epic-body.ts +10 -10
  239. package/scripts/epic/epic-bundle-cli.ts +36 -34
  240. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  241. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  242. package/scripts/epic/epic-bundle-poll.ts +1 -1
  243. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  244. package/scripts/epic/epic-bundle.ts +19 -20
  245. package/scripts/epic/epic-busy.ts +44 -21
  246. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  247. package/scripts/epic/epic-chains.ts +18 -23
  248. package/scripts/epic/epic-classify.ts +11 -12
  249. package/scripts/epic/epic-cli-argv.ts +5 -6
  250. package/scripts/epic/epic-cli-remove.ts +9 -4
  251. package/scripts/epic/epic-cli.ts +38 -26
  252. package/scripts/epic/epic-close-comment.ts +14 -15
  253. package/scripts/epic/epic-close.ts +25 -29
  254. package/scripts/epic/epic-cross-repo.ts +18 -21
  255. package/scripts/epic/epic-decision.ts +14 -18
  256. package/scripts/epic/epic-fetch.ts +25 -31
  257. package/scripts/epic/epic-graph.ts +15 -17
  258. package/scripts/epic/epic-index.ts +14 -16
  259. package/scripts/epic/epic-issue.ts +9 -11
  260. package/scripts/epic/epic-label-age.ts +74 -0
  261. package/scripts/epic/epic-lane-offer.ts +35 -24
  262. package/scripts/epic/epic-nested.ts +1 -1
  263. package/scripts/epic/epic-next-read.ts +8 -8
  264. package/scripts/epic/epic-next-views.ts +12 -12
  265. package/scripts/epic/epic-next.ts +29 -33
  266. package/scripts/epic/epic-outside-blocker.ts +11 -10
  267. package/scripts/epic/epic-parse.ts +22 -24
  268. package/scripts/epic/epic-promote.ts +3 -2
  269. package/scripts/epic/epic-rank.ts +1 -1
  270. package/scripts/epic/epic-read.ts +10 -8
  271. package/scripts/epic/epic-reconcile.ts +8 -6
  272. package/scripts/epic/epic-reference.ts +5 -4
  273. package/scripts/epic/epic-relation-recheck.ts +10 -11
  274. package/scripts/epic/epic-relations.ts +9 -8
  275. package/scripts/epic/epic-remove-plan.ts +4 -5
  276. package/scripts/epic/epic-remove.ts +7 -5
  277. package/scripts/epic/epic-report.ts +18 -20
  278. package/scripts/epic/epic-run.ts +6 -5
  279. package/scripts/epic/epic-sections.ts +2 -2
  280. package/scripts/epic/epic-shape.ts +3 -3
  281. package/scripts/epic/epic-solo-stale.ts +3 -2
  282. package/scripts/epic/epic-solo.ts +8 -8
  283. package/scripts/epic/epic-triage.ts +5 -4
  284. package/scripts/epic/epic-validate.ts +8 -7
  285. package/scripts/epic/epic.ts +5 -5
  286. package/scripts/exports/unused-members-cli.ts +1 -1
  287. package/scripts/followup/followup-issue-number.ts +1 -2
  288. package/scripts/followup/git-followup-cleanup.ts +6 -7
  289. package/scripts/followup/git-followup-finish.ts +11 -13
  290. package/scripts/followup/git-followup-flush.ts +11 -7
  291. package/scripts/followup/git-followup-issue-close.ts +16 -13
  292. package/scripts/followup/git-followup-label.ts +9 -6
  293. package/scripts/followup/git-followup-merged.ts +1 -1
  294. package/scripts/followup/git-followup-pending.ts +7 -9
  295. package/scripts/followup/git-followup-stages.ts +28 -17
  296. package/scripts/followup/git-followup-workflow.ts +19 -21
  297. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  298. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  299. package/scripts/followup/git-pr-followup.ts +18 -17
  300. package/scripts/gate/core-admission.ts +162 -0
  301. package/scripts/gate/core-budget.ts +134 -91
  302. package/scripts/gate/gate-ledger.ts +114 -0
  303. package/scripts/gate/gate-log.ts +7 -9
  304. package/scripts/gate/gate-plan.ts +103 -35
  305. package/scripts/gate/gate-report.ts +39 -21
  306. package/scripts/gate/gate-skip.ts +11 -13
  307. package/scripts/gate/gate-steps.ts +5 -1
  308. package/scripts/gate/gate-tree.ts +3 -4
  309. package/scripts/gate/hook-gate-reuse.ts +9 -9
  310. package/scripts/gate/machine-capacity.ts +313 -0
  311. package/scripts/gate/pre-commit-type-check.ts +4 -4
  312. package/scripts/gate/project-checks.ts +12 -4
  313. package/scripts/gate/scoped-green.ts +11 -18
  314. package/scripts/gate/type-check-command.ts +2 -2
  315. package/scripts/gate/type-check-step.ts +4 -4
  316. package/scripts/gate/verification-gate.ts +60 -53
  317. package/scripts/gh/gh-spawn.ts +2 -2
  318. package/scripts/gh/git-ai-review-scan.ts +3 -2
  319. package/scripts/gh/git-gh-api-path.ts +10 -11
  320. package/scripts/gh/git-gh-exec.ts +43 -48
  321. package/scripts/gh/git-gh-failure.ts +6 -9
  322. package/scripts/gh/git-gh-helpers.ts +1 -1
  323. package/scripts/gh/git-gh-issue-list.ts +15 -19
  324. package/scripts/gh/git-gh-issue-read.ts +43 -60
  325. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  326. package/scripts/gh/git-gh-issue-write.ts +52 -40
  327. package/scripts/gh/git-gh-issue.ts +23 -24
  328. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  329. package/scripts/gh/git-gh-pr-read.ts +46 -50
  330. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  331. package/scripts/gh/git-gh-pr-review.ts +2 -2
  332. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  333. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  334. package/scripts/gh/git-gh-pr.ts +16 -16
  335. package/scripts/gh/git-gh-reachability.ts +11 -12
  336. package/scripts/gh/git-gh-repo.ts +2 -3
  337. package/scripts/gh/git-gh-rest-state.ts +1 -1
  338. package/scripts/gh/git-pr-ai-review.ts +6 -5
  339. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  340. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  341. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  342. package/scripts/gh/git-pr-checks.ts +20 -23
  343. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  344. package/scripts/gh/git-pr-confirmation.ts +5 -5
  345. package/scripts/gh/git-pr-managed-config.ts +7 -9
  346. package/scripts/gh/git-pr-messages.ts +1 -1
  347. package/scripts/gh/git-pr.ts +15 -16
  348. package/scripts/gh/github-issue-url.ts +8 -9
  349. package/scripts/git/base-tree.ts +66 -0
  350. package/scripts/git/change-base.ts +42 -2
  351. package/scripts/git/changed-file-scope.ts +5 -5
  352. package/scripts/git/changed-paths.ts +1 -2
  353. package/scripts/git/constants.ts +2 -2
  354. package/scripts/git/git-branch.ts +1 -1
  355. package/scripts/git/git-closes-keyword.ts +3 -3
  356. package/scripts/git/git-command.ts +53 -41
  357. package/scripts/git/git-common-directory.ts +3 -3
  358. package/scripts/git/git-diff-reads.ts +14 -15
  359. package/scripts/git/git-error.ts +1 -1
  360. package/scripts/git/git-execa-error.ts +1 -2
  361. package/scripts/git/git-issue.ts +10 -8
  362. package/scripts/git/git-location-environment.ts +3 -4
  363. package/scripts/git/git-ls-remote.ts +6 -8
  364. package/scripts/git/git-pre-push-hook.ts +11 -10
  365. package/scripts/git/git-preflight.ts +5 -5
  366. package/scripts/git/git-push-transport.ts +2 -2
  367. package/scripts/git/git-remote-branch.ts +1 -2
  368. package/scripts/git/git-schemas.ts +16 -23
  369. package/scripts/git/git-spawn-sync.ts +1 -1
  370. package/scripts/git/git-spawn.ts +37 -14
  371. package/scripts/git/git-ssh-keepalive.ts +12 -5
  372. package/scripts/git/git-staging.ts +7 -8
  373. package/scripts/git/git-workflow.ts +1 -1
  374. package/scripts/git/git-worktree.ts +35 -27
  375. package/scripts/git/gone-branch.ts +2 -2
  376. package/scripts/git/listing-cutoff.ts +1 -2
  377. package/scripts/git/lockfile-sync.ts +65 -0
  378. package/scripts/git/main-merge-guard.ts +1 -2
  379. package/scripts/git/main-merge.ts +7 -7
  380. package/scripts/git/main-sync.ts +23 -8
  381. package/scripts/git/parse-json-array.ts +18 -23
  382. package/scripts/git/repository-lock.ts +34 -2
  383. package/scripts/git/stash/git-stash.ts +4 -5
  384. package/scripts/git/stash/stash-orphans.ts +5 -3
  385. package/scripts/git/stash/stash-pop-args.ts +1 -1
  386. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  387. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  388. package/scripts/hooks/batch-guard.ts +11 -13
  389. package/scripts/hooks/check-commit-message.ts +12 -9
  390. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  391. package/scripts/hooks/edited-cspell.ts +3 -4
  392. package/scripts/hooks/format-edited-cli.ts +1 -1
  393. package/scripts/hooks/format-edited-file.ts +11 -17
  394. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  395. package/scripts/hooks/pre-push-unit.ts +10 -14
  396. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  397. package/scripts/hooks/pretool-guard.ts +93 -18
  398. package/scripts/hooks/reserved-run.ts +2 -2
  399. package/scripts/hooks/step-zero-notice.ts +1 -1
  400. package/scripts/hooks/stop-guard.ts +21 -10
  401. package/scripts/init/basic-path-migration.ts +2 -2
  402. package/scripts/init/claude-kit-only-settings.ts +2 -2
  403. package/scripts/init/claude-plugin-config.ts +2 -2
  404. package/scripts/init/distributed-paths.ts +4 -4
  405. package/scripts/init/hook-command-rewrite.ts +3 -3
  406. package/scripts/init/hook-launch.ts +5 -5
  407. package/scripts/init/init-actions.ts +13 -0
  408. package/scripts/init/init-ai-copy.ts +11 -11
  409. package/scripts/init/init-bootstrap.ts +3 -3
  410. package/scripts/init/init-copy-content.ts +4 -4
  411. package/scripts/init/init-logic-json-merge.ts +7 -9
  412. package/scripts/init/init-logic-migrate.ts +1 -1
  413. package/scripts/init/init-logic-templates.ts +1 -1
  414. package/scripts/init/init-logic-workspace.ts +4 -4
  415. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  416. package/scripts/init/init-logic.ts +19 -22
  417. package/scripts/init/init.ts +12 -8
  418. package/scripts/init/kit-base-preset.ts +1 -1
  419. package/scripts/init/kit-setup-state.ts +1 -1
  420. package/scripts/init/kit-written-paths.ts +1 -2
  421. package/scripts/init/package-manager-pin.ts +35 -0
  422. package/scripts/init/project-profile-cli.ts +1 -1
  423. package/scripts/init/project-profile.ts +3 -3
  424. package/scripts/init/session-language-environment.ts +1 -1
  425. package/scripts/init/start-exec.ts +3 -4
  426. package/scripts/init/start-plan.ts +2 -2
  427. package/scripts/init/start-setup-pr.ts +3 -2
  428. package/scripts/init/start-steps.ts +2 -2
  429. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  430. package/scripts/init/vscode-tasks.ts +62 -0
  431. package/scripts/issue/baseline-measure.ts +2 -2
  432. package/scripts/issue/behavior-change-lint.ts +2 -2
  433. package/scripts/issue/defect-rate-cli.ts +6 -7
  434. package/scripts/issue/defect-rate.ts +37 -27
  435. package/scripts/issue/git-next-issues.ts +9 -8
  436. package/scripts/issue/issue-auto-ok.ts +49 -11
  437. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  438. package/scripts/issue/issue-backlinks.ts +6 -6
  439. package/scripts/issue/issue-cite-cli.ts +20 -18
  440. package/scripts/issue/issue-cite.ts +18 -8
  441. package/scripts/issue/issue-closing-pr.ts +4 -4
  442. package/scripts/issue/issue-comment-cli.ts +6 -4
  443. package/scripts/issue/issue-file-cli.ts +75 -15
  444. package/scripts/issue/issue-file-fold.ts +155 -0
  445. package/scripts/issue/issue-file.ts +14 -6
  446. package/scripts/issue/issue-fold-cli.ts +14 -9
  447. package/scripts/issue/issue-fold.ts +23 -8
  448. package/scripts/issue/issue-labels.ts +46 -37
  449. package/scripts/issue/issue-lint-cli.ts +2 -2
  450. package/scripts/issue/issue-lint.ts +1 -1
  451. package/scripts/issue/issue-merged.ts +10 -4
  452. package/scripts/issue/issue-number-shape.ts +27 -0
  453. package/scripts/issue/issue-rank.ts +1 -1
  454. package/scripts/issue/issue-read-cli.ts +4 -5
  455. package/scripts/issue/issue-read.ts +4 -5
  456. package/scripts/issue/issue-reference.ts +5 -5
  457. package/scripts/issue/issue-release-cli.ts +165 -0
  458. package/scripts/issue/issue-release.ts +58 -0
  459. package/scripts/issue/issue-report-failures.ts +7 -4
  460. package/scripts/issue/issue-scout-cli.ts +11 -11
  461. package/scripts/issue/issue-scout-closed.ts +4 -4
  462. package/scripts/issue/issue-scout.ts +4 -5
  463. package/scripts/issue/issue-state-cli.ts +17 -10
  464. package/scripts/issue/issue-state.ts +12 -13
  465. package/scripts/issue/issue-wip.ts +7 -7
  466. package/scripts/issue/markdown-section.ts +3 -3
  467. package/scripts/issue/measure-rerun-cli.ts +10 -9
  468. package/scripts/issue/reproduction-measure.ts +3 -3
  469. package/scripts/issue/session-cite.ts +56 -0
  470. package/scripts/josh/agent-session-environment.ts +10 -8
  471. package/scripts/josh/cli-body.ts +2 -2
  472. package/scripts/josh/command-suggest.ts +1 -1
  473. package/scripts/josh/file-map-stamp.ts +20 -23
  474. package/scripts/josh/hook-decision.ts +24 -28
  475. package/scripts/josh/josh-command-map.ts +4 -1
  476. package/scripts/josh/josh-command-types.ts +32 -34
  477. package/scripts/josh/josh-commands-ai.ts +6 -6
  478. package/scripts/josh/josh-commands-backlog.ts +15 -3
  479. package/scripts/josh/josh-commands-clone.ts +1 -1
  480. package/scripts/josh/josh-commands-development.ts +33 -4
  481. package/scripts/josh/josh-commands-document.ts +3 -3
  482. package/scripts/josh/josh-commands-guard.ts +3 -3
  483. package/scripts/josh/josh-commands-issue.ts +11 -5
  484. package/scripts/josh/josh-commands-lane.ts +16 -5
  485. package/scripts/josh/josh-commands-lint.ts +1 -1
  486. package/scripts/josh/josh-commands-maintenance.ts +2 -2
  487. package/scripts/josh/josh-commands-run.ts +20 -6
  488. package/scripts/josh/josh-commands-split.ts +1 -2
  489. package/scripts/josh/josh-commands-versioning.ts +5 -5
  490. package/scripts/josh/josh-commands-workflow.ts +30 -22
  491. package/scripts/josh/josh-environment-file.ts +1 -1
  492. package/scripts/josh/josh-in-process.ts +3 -3
  493. package/scripts/josh/josh-logic.ts +10 -10
  494. package/scripts/josh/josh-run.ts +3 -3
  495. package/scripts/josh/josh-verdict.ts +9 -12
  496. package/scripts/josh/josh.ts +3 -3
  497. package/scripts/josh/kit-only.ts +2 -2
  498. package/scripts/josh/path-decision.ts +3 -3
  499. package/scripts/josh/platform-temporary.ts +7 -5
  500. package/scripts/josh/process-identity.ts +24 -6
  501. package/scripts/josh/process-owner.ts +4 -4
  502. package/scripts/josh/session-language-cli.ts +53 -11
  503. package/scripts/josh/session-language.ts +1 -1
  504. package/scripts/josh/stamp-file.ts +48 -29
  505. package/scripts/josh/stamp-record.ts +57 -0
  506. package/scripts/lane/lane-await.ts +35 -11
  507. package/scripts/lane/lane-cache.ts +6 -6
  508. package/scripts/lane/lane-capacity.ts +32 -17
  509. package/scripts/lane/lane-child-invocation.ts +17 -15
  510. package/scripts/lane/lane-child-marker.ts +12 -12
  511. package/scripts/lane/lane-cli.ts +20 -13
  512. package/scripts/lane/lane-close.ts +6 -6
  513. package/scripts/lane/lane-dispatch.ts +61 -72
  514. package/scripts/lane/lane-environment.ts +5 -5
  515. package/scripts/lane/lane-guard-policy.ts +7 -21
  516. package/scripts/lane/lane-handoff.ts +2 -2
  517. package/scripts/lane/lane-install.ts +9 -10
  518. package/scripts/lane/lane-launch-cli.ts +13 -8
  519. package/scripts/lane/lane-ledger.ts +73 -11
  520. package/scripts/lane/lane-leftover.ts +44 -30
  521. package/scripts/lane/lane-limit-cli.ts +160 -0
  522. package/scripts/lane/lane-limit-override.ts +74 -0
  523. package/scripts/lane/lane-load.ts +19 -68
  524. package/scripts/lane/lane-measure-cli.ts +15 -25
  525. package/scripts/lane/lane-occupancy.ts +6 -4
  526. package/scripts/lane/lane-open.ts +25 -24
  527. package/scripts/lane/lane-output.ts +4 -3
  528. package/scripts/lane/lane-paths.ts +22 -8
  529. package/scripts/lane/lane-phase.ts +33 -0
  530. package/scripts/lane/lane-reap.ts +2 -2
  531. package/scripts/lane/lane-registry.ts +27 -15
  532. package/scripts/lane/lane-relaunch.ts +9 -9
  533. package/scripts/lane/lane-report.ts +5 -4
  534. package/scripts/lane/lane-resume.ts +2 -2
  535. package/scripts/lane/lane-sampler.ts +55 -0
  536. package/scripts/lane/lane-seed.ts +7 -7
  537. package/scripts/lane/lane-stage-stats.ts +135 -0
  538. package/scripts/lane/lane-start-point.ts +8 -11
  539. package/scripts/lane/lane-stats.ts +60 -15
  540. package/scripts/lane/lane-stray.ts +140 -0
  541. package/scripts/lane/lane-vacant.ts +1 -1
  542. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  543. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  544. package/scripts/lane/openai-review-broker.ts +2 -4
  545. package/scripts/lib/ancestor-directories.ts +1 -1
  546. package/scripts/lib/bounded-pool.ts +2 -2
  547. package/scripts/lib/buffered-process.ts +4 -6
  548. package/scripts/lib/caddy-logs.sh +0 -0
  549. package/scripts/lib/cli-flags.ts +39 -6
  550. package/scripts/lib/error-message.ts +1 -1
  551. package/scripts/lib/json-value.ts +17 -3
  552. package/scripts/lib/poll.ts +1 -1
  553. package/scripts/lib/status-icons.ts +3 -3
  554. package/scripts/lib/timed-fetch.ts +1 -1
  555. package/scripts/lib/timeouts.ts +1 -1
  556. package/scripts/lines/bytes-command.ts +3 -4
  557. package/scripts/lines/effective-limit.ts +25 -12
  558. package/scripts/lines/line-budget.ts +47 -55
  559. package/scripts/lines/line-targets.ts +6 -2
  560. package/scripts/lines/lines-command.ts +3 -3
  561. package/scripts/lint/cspell-cached.ts +1 -1
  562. package/scripts/lint/cycle-recheck.ts +122 -0
  563. package/scripts/lint/format.ts +1 -2
  564. package/scripts/lint/lint-parallel.ts +34 -19
  565. package/scripts/lint/lint-related-scope.ts +25 -15
  566. package/scripts/lint/lint-related.ts +6 -7
  567. package/scripts/managed-marker/index.ts +1 -1
  568. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  569. package/scripts/notify/git-notify.ts +9 -7
  570. package/scripts/notify/telegram-notify.ts +53 -37
  571. package/scripts/notify/telegram-test-logic.ts +3 -3
  572. package/scripts/notify/telegram-test.ts +45 -30
  573. package/scripts/observations/observation-ledger-home.ts +14 -8
  574. package/scripts/observations/observation-ledger-line.ts +3 -2
  575. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  576. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  577. package/scripts/observations/observation-ledger.ts +14 -15
  578. package/scripts/observations/observation-record-cli.ts +83 -0
  579. package/scripts/observations/observation-record.ts +91 -0
  580. package/scripts/observations/observations-flush-cli.ts +1 -1
  581. package/scripts/observations/observations-flush-landing.ts +7 -6
  582. package/scripts/observations/observations-flush.ts +26 -27
  583. package/scripts/overrides/overrides-check.ts +18 -8
  584. package/scripts/package/package-scout-cli.ts +1 -1
  585. package/scripts/package/package-scout-format.ts +2 -2
  586. package/scripts/package/package-scout.ts +1 -1
  587. package/scripts/propagate/propagate-git-failure.ts +1 -1
  588. package/scripts/propagate/propagate-git.ts +7 -7
  589. package/scripts/propagate/propagate-plan.ts +2 -2
  590. package/scripts/propagate/propagate-publish.ts +2 -3
  591. package/scripts/propagate/propagate-run.ts +5 -7
  592. package/scripts/propagate/propagate-select.ts +1 -1
  593. package/scripts/propagate/propagate-steps.ts +19 -20
  594. package/scripts/propagate/propagate-targets.ts +6 -10
  595. package/scripts/propagate/propagate.ts +5 -5
  596. package/scripts/refactor/import-graph.ts +1 -1
  597. package/scripts/refactor/refactor-lint.ts +4 -10
  598. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  599. package/scripts/refactor/refactor-scan.ts +2 -2
  600. package/scripts/refactor/refactor-targets.ts +1 -1
  601. package/scripts/release/github-release-cli.ts +25 -3
  602. package/scripts/release/github-release-environment.ts +1 -0
  603. package/scripts/release/github-release-runs.ts +115 -0
  604. package/scripts/release/github-release.ts +13 -67
  605. package/scripts/release/release-cli.ts +21 -4
  606. package/scripts/release/release-history.ts +6 -10
  607. package/scripts/release/release-plan.ts +3 -3
  608. package/scripts/release/release-progress.ts +3 -4
  609. package/scripts/release/release-publish.ts +8 -9
  610. package/scripts/release/release-scope-cli.ts +8 -10
  611. package/scripts/release/release-tag.ts +6 -8
  612. package/scripts/release/release-worktree.ts +5 -5
  613. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  614. package/scripts/repo/auto-merge-setting.ts +1 -1
  615. package/scripts/repo/repo-setting.ts +4 -4
  616. package/scripts/repo/repository-labels.ts +1 -1
  617. package/scripts/repo/required-checks-logic.ts +3 -3
  618. package/scripts/repo/required-checks-report.ts +1 -1
  619. package/scripts/repo/ruleset-check-cli.ts +1 -1
  620. package/scripts/repo/ruleset-check.ts +1 -1
  621. package/scripts/report/report-format-reference.ts +26 -0
  622. package/scripts/report/report-lint-cli.ts +2 -2
  623. package/scripts/report/report-lint.ts +16 -2
  624. package/scripts/review/disposition-cli.ts +2 -2
  625. package/scripts/review/disposition-logic.ts +1 -1
  626. package/scripts/review/live-evidence.ts +9 -6
  627. package/scripts/review/review-attest-cli.ts +1 -2
  628. package/scripts/review/review-attest.ts +3 -3
  629. package/scripts/review/review-brief-cli.ts +19 -20
  630. package/scripts/review/review-brief.ts +29 -32
  631. package/scripts/review/review-checkout.ts +2 -2
  632. package/scripts/review/review-diff-parts.ts +3 -5
  633. package/scripts/review/review-diff-write.ts +1 -1
  634. package/scripts/review/review-finding-ledger.ts +7 -4
  635. package/scripts/review/review-findings-cli.ts +2 -2
  636. package/scripts/review/review-level.ts +4 -7
  637. package/scripts/review/review-record-cli.ts +73 -16
  638. package/scripts/review/review-record.ts +5 -4
  639. package/scripts/review/review-round2-cli.ts +2 -3
  640. package/scripts/review/review-round2.ts +13 -21
  641. package/scripts/review/review-stamps.ts +9 -71
  642. package/scripts/review/review-tree.ts +4 -5
  643. package/scripts/rules/bash-triggers.ts +4 -4
  644. package/scripts/rules/decision-oracle-batch.ts +5 -6
  645. package/scripts/rules/decision-oracle-stage.ts +1 -1
  646. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  647. package/scripts/rules/decision-oracle.ts +2 -2
  648. package/scripts/rules/delivered-rules.ts +61 -406
  649. package/scripts/rules/destructive-command.ts +2 -2
  650. package/scripts/rules/direct-filing.ts +4 -4
  651. package/scripts/rules/direct-pr-create.ts +2 -2
  652. package/scripts/rules/early-heartbeat.ts +15 -19
  653. package/scripts/rules/file-body.ts +5 -6
  654. package/scripts/rules/filing-cap.ts +6 -7
  655. package/scripts/rules/filing-offer.ts +1 -1
  656. package/scripts/rules/firing-point.ts +6 -6
  657. package/scripts/rules/gh-api.ts +2 -2
  658. package/scripts/rules/git-argv.ts +3 -3
  659. package/scripts/rules/git-force.ts +2 -2
  660. package/scripts/rules/hook-context-line.ts +31 -0
  661. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  662. package/scripts/rules/implementation-cut.ts +35 -32
  663. package/scripts/rules/index-guard.ts +2 -2
  664. package/scripts/rules/issue-citation.ts +7 -7
  665. package/scripts/rules/issue-comments.ts +21 -13
  666. package/scripts/rules/josh-git-bare.ts +2 -2
  667. package/scripts/rules/lane-background.ts +14 -16
  668. package/scripts/rules/lane-carry-conflict.ts +41 -5
  669. package/scripts/rules/lane-interactive-ask.ts +6 -9
  670. package/scripts/rules/lane-park.ts +12 -16
  671. package/scripts/rules/lane-split-park.ts +1 -2
  672. package/scripts/rules/lane-switch-main.ts +10 -13
  673. package/scripts/rules/last-prompt.ts +1 -1
  674. package/scripts/rules/oracle-consulted.ts +5 -5
  675. package/scripts/rules/oracle-firing.ts +6 -9
  676. package/scripts/rules/oracle-list-cli.ts +2 -2
  677. package/scripts/rules/permission-guards.ts +2 -2
  678. package/scripts/rules/piped-verification.ts +79 -9
  679. package/scripts/rules/poll-loop.ts +9 -11
  680. package/scripts/rules/pre-gate-cut.ts +33 -30
  681. package/scripts/rules/prior-comment-read.ts +3 -3
  682. package/scripts/rules/protected-files.ts +25 -13
  683. package/scripts/rules/raw-field-body.ts +3 -4
  684. package/scripts/rules/reply-language.ts +1 -1
  685. package/scripts/rules/rule-body-guard.ts +10 -12
  686. package/scripts/rules/rule-guard.ts +1 -1
  687. package/scripts/rules/rule-list.ts +51 -0
  688. package/scripts/rules/rule-registry-rows.ts +282 -0
  689. package/scripts/rules/rule-registry.ts +109 -0
  690. package/scripts/rules/rule-value-cache.ts +2 -2
  691. package/scripts/rules/rule-value-cli.ts +6 -4
  692. package/scripts/rules/rule-value.ts +61 -22
  693. package/scripts/rules/run-tail-rule.ts +11 -15
  694. package/scripts/rules/shell-body-trigger.ts +7 -7
  695. package/scripts/rules/shell-segments.ts +2 -4
  696. package/scripts/rules/stop-rules.ts +54 -41
  697. package/scripts/rules/tail-commands.ts +1 -1
  698. package/scripts/rules/test-declared-commit.ts +2 -2
  699. package/scripts/rules/third-party-write.ts +3 -3
  700. package/scripts/rules/worktree-guard.ts +12 -5
  701. package/scripts/run/add/run-add-cli.ts +165 -0
  702. package/scripts/run/add/run-add.ts +124 -0
  703. package/scripts/run/board/run-board-cli.ts +207 -0
  704. package/scripts/run/board/run-board-closed.ts +95 -0
  705. package/scripts/run/board/run-board-every.ts +60 -0
  706. package/scripts/run/board/run-board-fetch.ts +38 -0
  707. package/scripts/run/board/run-board-fit.ts +219 -0
  708. package/scripts/run/board/run-board-github.ts +162 -0
  709. package/scripts/run/board/run-board-header.ts +275 -0
  710. package/scripts/run/board/run-board-kind.ts +35 -0
  711. package/scripts/run/board/run-board-labels.ts +299 -0
  712. package/scripts/run/board/run-board-layout.ts +222 -0
  713. package/scripts/run/board/run-board-link.ts +31 -0
  714. package/scripts/run/board/run-board-machine.ts +198 -0
  715. package/scripts/run/board/run-board-notes.ts +103 -0
  716. package/scripts/run/board/run-board-phase.ts +136 -0
  717. package/scripts/run/board/run-board-plan.ts +129 -0
  718. package/scripts/run/board/run-board-read.ts +62 -0
  719. package/scripts/run/board/run-board-render-legend.ts +82 -0
  720. package/scripts/run/board/run-board-render-notes.ts +77 -0
  721. package/scripts/run/board/run-board-render-slot.ts +50 -0
  722. package/scripts/run/board/run-board-render.ts +407 -0
  723. package/scripts/run/board/run-board-scope.ts +17 -0
  724. package/scripts/run/board/run-board-screen.ts +43 -0
  725. package/scripts/run/board/run-board-span.ts +66 -0
  726. package/scripts/run/board/run-board-spin.ts +115 -0
  727. package/scripts/run/board/run-board-state.ts +113 -0
  728. package/scripts/run/board/run-board-status.ts +279 -0
  729. package/scripts/run/board/run-board-tick.ts +210 -0
  730. package/scripts/run/board/run-board-track.ts +22 -0
  731. package/scripts/run/board/run-board-usage-read.ts +255 -0
  732. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  733. package/scripts/run/board/run-board-usage-text.ts +80 -0
  734. package/scripts/run/board/run-board-usage.ts +165 -0
  735. package/scripts/run/carry/run-carry-added.ts +62 -0
  736. package/scripts/run/carry/run-carry-args.ts +25 -22
  737. package/scripts/run/carry/run-carry-change.ts +1 -1
  738. package/scripts/run/carry/run-carry-cli.ts +71 -48
  739. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  740. package/scripts/run/carry/run-carry-ended.ts +85 -0
  741. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  742. package/scripts/run/carry/run-carry-stash.ts +3 -2
  743. package/scripts/run/carry/run-carry-streak.ts +8 -10
  744. package/scripts/run/carry/run-carry.ts +85 -89
  745. package/scripts/run/cut/run-cut-args.ts +7 -7
  746. package/scripts/run/cut/run-cut-cli.ts +68 -37
  747. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  748. package/scripts/run/cut/run-cut-report.ts +37 -16
  749. package/scripts/run/cut/run-cut.ts +63 -77
  750. package/scripts/run/detached-launch.ts +35 -50
  751. package/scripts/run/entry/run-entry-cli.ts +48 -27
  752. package/scripts/run/entry/run-entry-stop.ts +7 -9
  753. package/scripts/run/entry/run-entry.ts +5 -6
  754. package/scripts/run/event/run-event-cli.ts +5 -6
  755. package/scripts/run/event/run-event-filed.ts +69 -0
  756. package/scripts/run/event/run-event-follow.ts +3 -3
  757. package/scripts/run/event/run-event-plan.ts +38 -0
  758. package/scripts/run/event/run-event-render.ts +10 -4
  759. package/scripts/run/event/run-event-scope.ts +47 -18
  760. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  761. package/scripts/run/event/run-event-stream.ts +172 -43
  762. package/scripts/run/event/run-event-watch.ts +4 -6
  763. package/scripts/run/hold/run-hold-cli.ts +65 -62
  764. package/scripts/run/hold/run-hold.ts +88 -46
  765. package/scripts/run/merge/run-merge-cli.ts +116 -77
  766. package/scripts/run/merge/run-merge-collect.ts +107 -0
  767. package/scripts/run/merge/run-merge-steps.ts +112 -65
  768. package/scripts/run/merge/run-merge-token.ts +30 -0
  769. package/scripts/run/merge/run-merge.ts +31 -22
  770. package/scripts/run/progress/run-progress-args.ts +4 -4
  771. package/scripts/run/progress/run-progress-cli.ts +39 -50
  772. package/scripts/run/progress/run-progress-clock.ts +25 -32
  773. package/scripts/run/progress/run-progress-config.ts +6 -9
  774. package/scripts/run/progress/run-progress-read.ts +9 -10
  775. package/scripts/run/progress/run-progress.ts +48 -53
  776. package/scripts/run/review/run-review-cli.ts +6 -6
  777. package/scripts/run/review/run-review-steps.ts +6 -6
  778. package/scripts/run/review/run-review.ts +9 -11
  779. package/scripts/run/run-cli-fault.ts +29 -0
  780. package/scripts/run/run-ending-cli.ts +3 -3
  781. package/scripts/run/run-ending.ts +10 -14
  782. package/scripts/run/run-halfrun-resume.ts +6 -8
  783. package/scripts/run/run-headless.ts +25 -12
  784. package/scripts/run/run-invocation.ts +17 -22
  785. package/scripts/run/run-label.ts +7 -5
  786. package/scripts/run/run-liveness-cli.ts +19 -6
  787. package/scripts/run/run-liveness.ts +27 -38
  788. package/scripts/run/run-next-cli.ts +5 -9
  789. package/scripts/run/run-next.ts +4 -5
  790. package/scripts/run/run-parent-cut-hook.ts +10 -12
  791. package/scripts/run/run-preflight.ts +25 -29
  792. package/scripts/run/run-prep-cli.ts +17 -13
  793. package/scripts/run/run-prep-locate.ts +4 -5
  794. package/scripts/run/run-prep.ts +7 -10
  795. package/scripts/run/run-prrun-resume.ts +2 -2
  796. package/scripts/run/run-report-cli.ts +4 -4
  797. package/scripts/run/run-report.ts +9 -14
  798. package/scripts/run/run-retrospective.ts +3 -3
  799. package/scripts/run/run-section.ts +42 -0
  800. package/scripts/run/run-stage-read.ts +2 -2
  801. package/scripts/run/run-stage.ts +6 -4
  802. package/scripts/run/run-status-cli.ts +7 -5
  803. package/scripts/run/run-status.ts +6 -7
  804. package/scripts/run/run-step-cli.ts +13 -15
  805. package/scripts/run/run-step.ts +62 -48
  806. package/scripts/run/run-stop-notify.ts +7 -8
  807. package/scripts/run/run-stranded-cli.ts +1 -1
  808. package/scripts/run/run-stranded-detect.ts +4 -4
  809. package/scripts/run/run-stranded.ts +11 -13
  810. package/scripts/run/run-tail-cli.ts +15 -16
  811. package/scripts/run/run-tail.ts +14 -33
  812. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  813. package/scripts/run/run-watcher-guard.ts +11 -12
  814. package/scripts/run/run-watcher-hook.ts +6 -12
  815. package/scripts/run/ship/run-ship-cli.ts +67 -33
  816. package/scripts/run/ship/run-ship-detach.ts +15 -13
  817. package/scripts/run/ship/run-ship-lock.ts +1 -1
  818. package/scripts/run/ship/run-ship-next.ts +7 -8
  819. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  820. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  821. package/scripts/run/ship/run-ship-probe.ts +4 -4
  822. package/scripts/run/ship/run-ship-return.ts +1 -1
  823. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  824. package/scripts/run/ship/run-ship-review.ts +12 -14
  825. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  826. package/scripts/run/ship/run-ship-stage.ts +80 -26
  827. package/scripts/run/ship/run-ship-steps.ts +26 -16
  828. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  829. package/scripts/run/ship/run-ship-sync.ts +9 -8
  830. package/scripts/run/ship/run-ship.ts +17 -32
  831. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  832. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  833. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  834. package/scripts/run/tidy/run-tidy.ts +4 -3
  835. package/scripts/run/wake/run-wake-cli.ts +27 -33
  836. package/scripts/run/wake/run-wake-describe.ts +76 -29
  837. package/scripts/run/wake/run-wake-driver.ts +14 -14
  838. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  839. package/scripts/run/wake/run-wake-loop.ts +13 -21
  840. package/scripts/run/wake/run-wake-restart.ts +4 -5
  841. package/scripts/run/wake/run-wake-session.ts +23 -27
  842. package/scripts/run/wake/run-wake.ts +57 -328
  843. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  844. package/scripts/safe-chain/pack-hook.ts +2 -2
  845. package/scripts/safe-chain/preinstall-command.ts +2 -2
  846. package/scripts/security/security-audit-logic.ts +1 -1
  847. package/scripts/security/security-audit-provision-logic.ts +1 -1
  848. package/scripts/security/security-audit-provision.ts +2 -2
  849. package/scripts/security/security-audit.ts +5 -5
  850. package/scripts/security/security-updates-logic.ts +2 -3
  851. package/scripts/security/security-updates.ts +2 -4
  852. package/scripts/self-sync-guard/index.ts +1 -1
  853. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  854. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  855. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  856. package/scripts/sonar/sonar-hotspots.ts +1 -1
  857. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  858. package/scripts/sonar/sonar-new-code.ts +1 -1
  859. package/scripts/sonar/sonar-project.ts +1 -1
  860. package/scripts/split/split-assess-cli.ts +1 -1
  861. package/scripts/split/split-assess.ts +3 -3
  862. package/scripts/sync/directory-copy-guard.ts +2 -3
  863. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  864. package/scripts/sync/managed-config-scope.ts +4 -4
  865. package/scripts/sync/plugin-skill-directories.ts +2 -2
  866. package/scripts/sync/reconcile-templates.ts +17 -8
  867. package/scripts/sync/removed-skill-manifest.ts +2 -3
  868. package/scripts/sync/sync-ai-files.ts +7 -7
  869. package/scripts/sync/sync-configs.ts +30 -3
  870. package/scripts/sync/sync-hook-safety.ts +2 -2
  871. package/scripts/sync/sync.ts +23 -10
  872. package/scripts/sync/synced-paths.ts +2 -1
  873. package/scripts/sync/workflow-pin-logic.ts +1 -1
  874. package/scripts/test/test-declared-changed.ts +4 -4
  875. package/scripts/test/test-declared-logic.ts +2 -3
  876. package/scripts/test/test-declared-match.ts +25 -4
  877. package/scripts/test/test-declared.ts +26 -9
  878. package/scripts/test/test-red-commit.ts +3 -2
  879. package/scripts/test/test-red-logic.ts +7 -14
  880. package/scripts/test/test-red.ts +12 -47
  881. package/scripts/test/test-related-scope.ts +2 -3
  882. package/scripts/test/test-related.ts +3 -3
  883. package/scripts/test/test-type-logic.ts +1 -2
  884. package/scripts/test/test-unit-guard.ts +13 -17
  885. package/scripts/test/unit-worker-share.ts +7 -8
  886. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  887. package/scripts/time-runtime/time-background.ts +17 -21
  888. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  889. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  890. package/scripts/time-runtime/time-bundles.ts +11 -12
  891. package/scripts/time-runtime/time-call-identity.ts +1 -1
  892. package/scripts/time-runtime/time-command-key.ts +2 -2
  893. package/scripts/time-runtime/time-density-hook.ts +8 -11
  894. package/scripts/time-runtime/time-density.ts +5 -5
  895. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  896. package/scripts/time-runtime/time-format.ts +5 -5
  897. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  898. package/scripts/time-runtime/time-instant.ts +1 -1
  899. package/scripts/time-runtime/time-markers.ts +15 -19
  900. package/scripts/time-runtime/time-phase-names.ts +3 -3
  901. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  902. package/scripts/time-runtime/time-round-trips.ts +20 -23
  903. package/scripts/time-runtime/time-shell.ts +8 -8
  904. package/scripts/time-runtime/time-single-check.ts +1 -2
  905. package/scripts/time-runtime/time-spans.ts +35 -40
  906. package/scripts/time-runtime/time-tool-call.ts +15 -16
  907. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  908. package/scripts/time-runtime/time-writes.ts +5 -5
  909. package/scripts/ui/ui-routes-cli.ts +1 -2
  910. package/scripts/ui/ui-routes.ts +1 -2
  911. package/scripts/version/bump-version.ts +1 -1
  912. package/scripts/version/fresh-metadata-cache.ts +2 -2
  913. package/scripts/version/latest-corepack.ts +129 -98
  914. package/scripts/version/latest-lane-guard.ts +1 -1
  915. package/scripts/version/latest-scope-cli.ts +2 -2
  916. package/scripts/version/latest-stamp.ts +1 -2
  917. package/scripts/version/latest-update.ts +2 -2
  918. package/scripts/version/npm-registry.ts +2 -2
  919. package/scripts/version/package-manager-version.ts +18 -0
  920. package/scripts/version/publishable-range-check.ts +2 -1
  921. package/scripts/version/publishable-range.ts +1 -1
  922. package/scripts/version/release-age.ts +11 -11
  923. package/scripts/version/release-hold.ts +2 -2
  924. package/scripts/version/safe-chain-version-update.ts +3 -3
  925. package/scripts/version/version-check-logic.ts +2 -3
  926. package/scripts/version/version-check.ts +1 -2
  927. package/scripts/version/version-command-config.ts +2 -2
  928. package/scripts/version/version-commands.ts +3 -3
  929. package/scripts/version/version-remote.ts +4 -4
  930. package/scripts/version/version-targets.ts +2 -2
  931. package/templates/gitignore +7 -0
  932. package/templates/workflows/github-release.yml +4 -0
  933. package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
  934. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  935. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  936. package/scripts/backlog/backlog-restructure.ts +0 -152
  937. package/scripts/rules/issue-fold-rule.ts +0 -72
  938. package/scripts/rules/wip-cap.ts +0 -63
  939. package/scripts/run/run-issue-number.ts +0 -19
@@ -4,316 +4,111 @@ import { time_call_identity } from './time-call-identity'
4
4
  import { time_spans, type Span } from './time-spans'
5
5
  import { time_transcript_line } from './time-transcript-line'
6
6
 
7
- // Whether the call about to go out should be refused because the run has stopped batching
8
- // (joshuafolkken/kit#1390).
7
+ // Whether the call about to go out should be refused because the run has stopped batching. What a
8
+ // call is and what a single-call sequence is are `time-bundle-call.ts`'s and `time-bundles.ts`'s
9
+ // answers — the same modules the end-of-run report uses — so the guard never disagrees with it.
9
10
  //
10
- // Two mechanisms already exist and neither moved the number. joshuafolkken/kit#1304 distributed the
11
- // norm as prose; joshuafolkken/kit#1329 and joshuafolkken/kit#1337 put the density in front of the run
12
- // while it was still going. Three consecutive runs measured 1.10–1.12 calls per round trip against a
13
- // 1.50 floor, with 14–27 of every hundred round trips recoverable (joshuafolkken/kit#1344). What is
14
- // left is not another way to *say* it: it is intervening in the decision itself.
11
+ // A `PreToolUse` hook cannot see the size of the turn it interrupts (later `tool_use` lines arrive
12
+ // seconds afterwards), so it decides on closed history alone; a refusal of a turn that was going to
13
+ // batch is a false positive costing one round trip.
15
14
  //
16
- // **The judgement is `time-bundle-call.ts`'s and `time-bundles.ts`'s, not a second one.** Whether a
17
- // call is bundleable, what it names, and what counts as a run of single-call turns are already
18
- // decided — by the very modules the end-of-run report is computed from. A guard with an opinion of its
19
- // own would refuse calls the report then says were fine, and the Issue's own verification step reads
20
- // that report.
21
- //
22
- // ## What it cannot know: the size of the turn it is interrupting
23
- //
24
- // **A `PreToolUse` hook cannot tell a batched turn from a single-call one, and no field in the
25
- // transcript can be made to say.** Claude Code writes one line per content block and starts the first
26
- // tool as soon as that block parses — measured on a live session, the later `tool_use` lines of one
27
- // message arrive **1.4 to 15 seconds afterwards**. So at the instant the first call of a turn is
28
- // judged, the turn looks single-call whatever it will turn out to be. `stop_reason` is no help: every
29
- // line of a message carries the finished message's value, including the `thinking` line written before
30
- // any tool ran, so it says nothing about how much of the message exists yet.
31
- //
32
- // **The guard therefore decides on closed history alone** — the run of single-call turns already
33
- // behind it — and the refusal lands on the first call of the turn that follows. Where that turn was
34
- // going to batch, the refusal is a false positive costing one round trip, which is the price
35
- // joshuafolkken/kit#1390 named and accepted before this was built.
36
- //
37
- // **Reading the count anyway would have been worse than not reading it.** `time_density.last_turn_calls`
38
- // answers exactly this question after the fact, and calling it here returns `1` for every turn — so a
39
- // guard written against it would refuse the first call of every batched turn while reporting that it
40
- // had checked. That is the first call of the very behavior this exists to produce, punished with a
41
- // verdict nobody could see was empty.
42
- //
43
- // ## The refusal cannot repeat on the call in hand, but it does repeat as the run keeps single-calling
44
- //
45
- // A refusal repeating on the *same call* would wedge a run, and that is made structurally impossible in
46
- // two ways. The caller records when it last fired, and the immediate re-look never re-fires: a call the
47
- // run answered by re-issuing it unchanged is found on a refused span in the tail (`is_reissued_refusal`)
48
- // and let through, so a turn can have at most one of its calls refused.
49
- //
50
- // **What used to follow from the record was silence for the rest of the run, and kit#2164 is what ends
51
- // that.** The old rule fired only where the open sequence *began* after the last firing — and a run that
52
- // ignored the refusal and kept single-calling never started a new sequence, so it was never spoken to
53
- // again. Measured across every run, that came to one refusal per run against thousands of turns. The
54
- // rule now fires the first time a run of single-call turns reaches the limit, and then **again every
55
- // `REFIRE_EVERY` further single-call turns** it keeps issuing: `is_sequence_at_limit` counts the closed
56
- // single-call turns since the last firing and re-fires once that count reaches the interval. A new
57
- // sequence — the run batched, then lapsed again — is a first firing of its own, exactly as before.
58
- //
59
- // **The re-fire cannot wedge**, for the same reason the first firing cannot: each re-fire refuses a
60
- // *different* call than the one already on a refused span, and a call the run re-issues unchanged after a
61
- // re-fire is let through by `is_reissued_refusal` just as the first refusal's re-issue is.
62
- //
63
- // **And the caller must fail toward allowing.** With no instant on record every sequence looks new, so
64
- // a caller that cannot record the refusal must not make it. `scripts/hooks/batch-guard.ts` states that half.
65
-
66
- // How many consecutive single-call turns are allowed before one is refused. **Three, from the
67
- // measurement rather than from taste**: joshuafolkken/kit#1344 found the longest bundleable sequence
68
- // of each run at 3–5 turns, so refusing at the third catches most sequences while they still have
69
- // turns left to save. Four or more gives most of them back; two would refuse the ordinary pair a
70
- // person would never call a defect.
15
+ // It fires when a sequence first reaches the limit, then every `REFIRE_EVERY` further single-call
16
+ // turns, and never twice on the same call: an unchanged reissue is let through (`is_reissued_refusal`).
17
+ // A caller that cannot record the refusal must not make it (`scripts/hooks/batch-guard.ts`).
18
+
19
+ // The longest bundleable sequence measured at 3–5 turns, so refusing at the third still saves turns.
71
20
  const CONSECUTIVE_LIMIT = 3
72
21
 
73
- // **How many further single-call turns pass between one firing and the next, once a run keeps
74
- // single-calling after being spoken to** (joshuafolkken/kit#2164). This is the `N` the acceptance
75
- // criteria name, and it lives here as a single constant. Before this the guard fired once per unbroken
76
- // run of single-call turns and then went silent — a run that ignored the first refusal and kept issuing
77
- // single calls was never spoken to again, so over thousands of turns the guard delivered one notice. The
78
- // re-fire turns that back into steady pressure: the same `CONSECUTIVE_LIMIT` cadence the first firing
79
- // used, applied again from the last firing, so the reminder recurs every three continued single-call
80
- // turns rather than once. It is deliberately not more frequent than the initial limit — a shorter
81
- // interval would refuse a run that is only two single calls past a reminder it just answered.
22
+ // Not tighter than the first limit, so a run just past an answered reminder is not refused again.
82
23
  const REFIRE_EVERY = CONSECUTIVE_LIMIT
83
24
  const ONE_TURN = 1
84
25
  const NONE = 0
85
26
 
86
- // **The notice's own re-fire interval, and the `N` joshuafolkken/kit#2276 measured as too long.** A
87
- // refusal that fired every single-call turn would refuse a run only one call past a reminder it just
88
- // answered, so `REFIRE_EVERY` holds the refusal at the initial limit. **A notice cannot wedge** — the
89
- // call proceeds either way — so nothing makes the notice pay that caution, and #2164 reusing the
90
- // refusal's three-turn cadence for it is why a lane child single-calling was nudged only once per three
91
- // mistakes. This is a single constant, the one the acceptance criteria name, kept apart from
92
- // `REFIRE_EVERY` so the refusal's cadence and the notice's cannot drift into one number that is wrong
93
- // for one of them.
27
+ // A notice cannot wedge (the call proceeds), so it recurs every turn; kept apart from `REFIRE_EVERY`.
94
28
  const NOTICE_REFIRE_EVERY = ONE_TURN
95
29
 
96
- // **How many of the most recent single-call turns the notice names** (joshuafolkken/kit#2276). #2164's
97
- // notice ended at "batch what follows" and named no call, and the density did not move; naming the
98
- // concrete calls the run just issued one-per-turn is the untried half of "why it did not work" — a
99
- // reader shown *these three reads had no dependency* has something to act on that "batch more" never
100
- // gave. Three, so the notice carries the sequence that tripped the limit without growing the per-turn
101
- // context it rides on.
30
+ // Naming the concrete calls gives the reader something to act on that "batch more" does not.
102
31
  const NAMED_CANDIDATE_COUNT = 3
103
32
 
104
- // **The turns already closed, so the one being interrupted is not among them.** A span exists only
105
- // once its result has come back, and the call being judged has not run yet — so a sequence of
106
- // `CONSECUTIVE_LIMIT - 1` closed turns is the state in which the next call would make the third.
33
+ // The call being judged has not closed, so `CONSECUTIVE_LIMIT - 1` closed turns means it makes the limit.
107
34
  const SEQUENCE_BEFORE_LIMIT = CONSECUTIVE_LIMIT - ONE_TURN
108
35
 
109
- // The call about to go out, named the way the hook payload names it. A record rather than two
110
- // parameters so the tool and its input cannot be handed over in the wrong order — both are strings on
111
- // the caller's side often enough for that to compile.
36
+ // A record so the tool and its input cannot be handed over in the wrong order.
112
37
  interface GuardedCall {
113
38
  name: string
114
39
  input: unknown
115
40
  }
116
41
 
117
- // What naming a call reads off it — a closed turn's span or the call in hand alike, so the live density
118
- // line can name the call that has just run beside the turns behind it (joshuafolkken/kit#3157).
42
+ // A closed turn's span or the call in hand alike.
119
43
  type NamedCall = Pick<Span, 'is_bundleable' | 'is_writing' | 'label' | 'targets'>
120
44
 
121
- // **A write is refusable, and the exclusion that said otherwise is gone** (joshuafolkken/kit#1762).
122
- // Read over 19 recorded runs, 261 of 1,737 round trips (15.0%) were recoverable by batching and **184
123
- // of them (70.5%) were writes** — 158 `Edit` alone. The refusal's own text has always said the rule
124
- // covers them ("edits are covered exactly as reads are"); the implementation had not caught up, so the
125
- // largest single contributor to the waste was the one party the guard could never reach.
126
- //
127
- // **Two different things were rejected before this, and separating them is what unblocked it.** What
128
- // was rejected on measured cost is *widening the hook's matcher and nothing else*: a matcher naming
129
- // `Edit` in front of an `is_guarded_call` that answers `false` for every write starts a process that
130
- // can only ever answer "allow". That reasoning is sound and is untouched — the predicate is widened
131
- // first, so the matcher now reaches a question that has an answer. What was **not** rejected, because
132
- // nobody had proposed it, is making a write refusable at all; "buy nothing a refusal could use" was a
133
- // consequence of the exclusion below it rather than a ground of its own.
134
- //
135
- // **The safety objection was real, and it is narrowed rather than dismissed.** Claude Code denies one
136
- // call of a turn and runs the rest, so a refused edit leaves its siblings applied and itself not, and
137
- // the reissue can meet text that has moved under it. `depends_on_sequence` below closes the half that
138
- // is visible: it withholds the refusal whenever the call in hand shares a target with the sequence
139
- // behind it, writes included, so an edit to a file the run has already been rewriting is never
140
- // refused.
141
- //
142
- // **The half it cannot close is the turn it is interrupting** — for the reason stated above, no field
143
- // in the transcript says what else that turn issued. Three edits to one file batched into a single
144
- // turn can therefore have their first refused while the other two apply. **The bound is that this
145
- // surfaces rather than corrupts**: a refusable write is content-addressed — an `Edit` carries the
146
- // `old_string` it was written against, an in-place `sed` a pattern — so a reissue either applies where
147
- // it was meant to or fails to match and is reported. So the residual cost is one round trip in the
148
- // ordinary case and a failed edit the run must redo in this one — the same false-positive price
149
- // joshuafolkken/kit#1390 named and accepted for reads, now paid on the calls that carry most of the
150
- // waste instead of only on the calls that carry the rest.
151
- //
152
- // **The dispatch it adds is measured, and it is not the figure the deleted text quoted.** One hook run
153
- // is **0.53 s** in this checkout and about 0.4 s in a consumer, essentially all of it process startup —
154
- // measured under `docs/josh-commands-automation.md` → "`josh format:edited`", which is where that reading was
155
- // taken. The "about 2.4 s" above was a `pnpm josh` dispatch measured before joshuafolkken/kit#1342 made
156
- // this command eligible for the in-process path. Against that, one recovered round trip is a whole
157
- // model turn.
158
- //
159
- // **The matcher is settings a consumer can widen, so what a call is stays this module's answer.**
160
- // `is_guarded_call` is the guarantee and `.claude/settings.json` is the wiring; the two are kept apart
161
- // so a consumer editing the second cannot change the first.
162
- //
163
- // **What a call *is* lives in `time-bundle-call.ts`** since joshuafolkken/kit#1509, beside the rest of
164
- // it, because the sequence builder needs the same answer and a second copy here is what let the two
165
- // disagree — the builder had no way to ask at all, so it read a run of edits to one file as a chain of
166
- // dependent calls and no sequence ever formed.
167
-
168
- // One line, and it says four things: what happened, what to do instead, where the rule is written, and
169
- // what to do when the turn was already batching or the call really is alone. **The last of those is not
170
- // a loophole, it is the honest half** — the guard cannot see the turn it interrupted, so a reader told
171
- // only to batch would batch something that already was.
45
+ // Writes are refusable — they were most of the recoverable round trips. A refused edit leaves its
46
+ // siblings applied, but a refusable write is content-addressed, so a reissue either applies or fails
47
+ // loudly; `depends_on_sequence` withholds the refusal where the call shares a target with the sequence.
48
+
49
+ // The three texts carry the action and a pointer; the criterion's reasoning and measured cost stay
50
+ // at the pointer, so a firing does not re-bill the rule body.
51
+ const RULE_POINTER = '`prompts/collaboration-workflow/turn-batching.md`'
52
+ const STREAK = `${String(CONSECUTIVE_LIMIT)} single-call turns in a row`
53
+
54
+ // Includes what to do when the turn was already batching — the guard cannot see the turn it interrupted.
172
55
  const REASON =
173
- `⛔ batching: the last ${String(SEQUENCE_BEFORE_LIMIT)} turns each issued a single tool call, so ` +
174
- `this one would make ${String(CONSECUTIVE_LIMIT)} in a row. Reissue it in one turn together with ` +
175
- `the calls meant to follow it that do not need its result. **The criterion is whether this call's ` +
176
- `input needs another call's result, not what kind of call it is** — edits are covered exactly as ` +
177
- `reads are, and it never authorizes weakening a verification gate or a review: fewer turns, never ` +
178
- `less work. The rule, and where its measured cost and rejected mechanisms are, is in ` +
179
- `\`prompts/collaboration-workflow/turn-batching.md\`. If this turn was already batching, or the call ` +
180
- `genuinely has nothing to go beside it, reissue it as it was: this fires once per run of ` +
181
- `single-call turns and cannot repeat on the call in hand.`
182
-
183
- // The notice a whole-file write earns instead of the refusal above (joshuafolkken/kit#1848). It says
184
- // the same thing REASON does — reissue the calls that do not need each other in one turn — but as a
185
- // **notice, not a refusal**: the write proceeds, because a `Write` cannot be refused safely (see
186
- // `WHOLE_FILE_WRITE_TOOL` below). The honest half is here for the same reason it is on REASON — the
187
- // guard cannot see the turn it is interrupting, so a reader told only to batch would batch a turn that
188
- // already was. It carries no ⛔, so a person watching reads it as advice rather than a stop.
56
+ `⛔ batching: ${STREAK}. Reissue this with the calls that do not need its result — the test is ` +
57
+ `whether a call's input needs another call's result, not what kind of call it is (edits are covered ` +
58
+ `exactly as reads), and it never authorizes weakening a verification gate or a review. Already ` +
59
+ `batching, or nothing to pair? Reissue it unchanged; this fires once per streak. ${RULE_POINTER}`
60
+
61
+ // A whole-file write earns a notice, not a refusal: a `Write` cannot be refused safely.
189
62
  const NOTICE =
190
- `💡 batching: the last ${String(SEQUENCE_BEFORE_LIMIT)} turns each issued a single tool call, so ` +
191
- `this Write makes ${String(CONSECUTIVE_LIMIT)} in a row. This is a notice, not a refusal — the ` +
192
- `write proceeds. Where the writes meant to follow it do not need its result, issue them in one turn ` +
193
- `together. **The criterion is whether a call's input needs another call's result, not what kind of ` +
194
- `call it is** — it never authorizes weakening a verification gate or a review: fewer turns, never ` +
195
- `less work. The rule, and where its measured cost and rejected mechanisms are, is in ` +
196
- `\`prompts/collaboration-workflow/turn-batching.md\`. If this run was already batching, or the write ` +
197
- `genuinely has nothing to go beside it, carry on: this recurs every ` +
198
- `${String(NOTICE_REFIRE_EVERY)} further single-call turn(s).`
199
-
200
- // The notice a *refusable* call earns instead of its refusal when the run is a dispatched lane child
201
- // (joshuafolkken/kit#2164). A headless `claude -p` child ends its turn on a denial, so the batching
202
- // guard cannot refuse there — but the guidance is exactly as useful, so it is delivered as a notice: the
203
- // call proceeds, and the model is told to batch what follows. It carries no ⛔, so a person watching
204
- // reads it as advice rather than a stop, and it says the reminder recurs so a child that keeps
205
- // single-calling knows the pressure is steady rather than spent.
206
- const LANE_NOTICE =
207
- `💡 batching: the last ${String(SEQUENCE_BEFORE_LIMIT)} turns each issued a single tool call, so ` +
208
- `this one makes ${String(CONSECUTIVE_LIMIT)} in a row. This is a notice, not a refusal — the call ` +
209
- `proceeds, because a dispatched lane child ends its turn on a denial. Where the calls meant to follow ` +
210
- `it do not need its result, issue them in one turn together. **The criterion is whether a call's ` +
211
- `input needs another call's result, not what kind of call it is** — it never authorizes weakening a ` +
212
- `verification gate or a review: fewer turns, never less work. The rule, and where its measured cost ` +
213
- `and rejected mechanisms are, is in \`prompts/collaboration-workflow/turn-batching.md\`. If this run was already ` +
214
- `batching, or the call genuinely has nothing to go beside it, carry on: this recurs every ` +
215
- `${String(NOTICE_REFIRE_EVERY)} further single-call turn(s).`
216
-
217
- // The one write that is never refused, because it is the one whose reissue is **unconditional**. Every
218
- // other refusable write is content-addressed and so fails loudly when its turn's siblings moved the
219
- // text under it; a `Write` carries the whole file, so reissuing it re-applies content composed before
220
- // those siblings ran and overwrites an applied edit with no error anywhere. **A turn holding a `Write`
221
- // and an `Edit` of one file is a shape a run actually produces** — create it, then adjust it — which is
222
- // what separates this from a truncating shell redirect, where the colliding turn would have to hold two
223
- // writers of one path and is not a shape that occurs.
224
- //
225
- // **It is not the blanket exclusion joshuafolkken/kit#1762 removed.** That one turned away every write
226
- // for being a write; this turns away one tool because a false positive on it cannot surface. `Edit` —
227
- // 164 of the 251 recoverable round trips against `Write`'s 37, read over 20 runs — is untouched, and
228
- // the matcher leaves `Write` out for the cost reason above rather than relying on this line alone.
63
+ `💡 batching: ${STREAK}; the Write proceeds. Issue the writes that do not need its result in one ` +
64
+ `turn, never by weakening a gate or a review. ${RULE_POINTER}`
65
+
66
+ // A headless lane child ends its turn on a denial, so a refusable call there earns a notice instead.
67
+ // It recurs every single-call turn, so it is kept to one line.
68
+ const LANE_NOTICE = `💡 batching: ${STREAK}; the call proceeds. Pair independent calls. ${RULE_POINTER}`
69
+
70
+ // Never refused: its reissue overwrites an applied sibling edit with no error anywhere.
229
71
  const WHOLE_FILE_WRITE_TOOL = 'Write'
230
72
 
231
- // The one tool the write-side fold names (joshuafolkken/kit#2366). A span's label is its tool name for
232
- // everything but Bash (`time-spans.ts`), so this is how a recent single-call turn is read as an edit
233
- // that `edit:files` could fold — distinct from `Write`, which this command cannot content-address.
73
+ // The one tool the write-side fold names; `Write` cannot be content-addressed by `edit:files`.
234
74
  const EDIT_TOOL = 'Edit'
235
75
 
236
- // Whether this call is one the guard could ever refuse, asked before any transcript is read. **The
237
- // caller uses it to skip that read**: a quarter-megabyte read inside a hook that holds every call is
238
- // not worth paying on a `pnpm josh` invocation the answer can never be about.
239
- //
240
- // **Bundleable is the whole test, because the criterion is dependency and not the kind of call.** The
241
- // `may_write` term that used to sit beside it excluded the 70.5% of recoverable round trips that are
242
- // writes (joshuafolkken/kit#1762). What keeps a write that genuinely cannot be refused safe is
243
- // `depends_on_sequence`, which reads the targets, rather than a blanket exclusion here.
76
+ // Asked before the transcript is read, so the hook skips the read for calls it can never refuse.
77
+ // Bundleable is the whole test — the criterion is dependency, not the kind of call.
244
78
  function is_guarded_call(call: GuardedCall): boolean {
245
79
  if (call.name === WHOLE_FILE_WRITE_TOOL) return false
246
80
 
247
81
  return time_bundle_call.call_facts(call.name, call.input).is_bundleable
248
82
  }
249
83
 
250
- // The counterpart to `is_guarded_call` for the one tool it turns away: the whole-file write is the
251
- // call the guard **notifies** about rather than refuses (joshuafolkken/kit#1848). It cannot be refused
252
- // safely — its reissue overwrites an applied sibling in silence — yet a run of single-call `Write`
253
- // turns was the largest recoverable contributor the refusal could never reach, so the notice carries
254
- // the rule to it without the false-positive cost. `.claude/settings.json` names `Write` in the matcher
255
- // so the hook is even reached, exactly as the predicate is what makes the matcher's answer non-empty.
256
84
  function is_notice_call(call: GuardedCall): boolean {
257
85
  return call.name === WHOLE_FILE_WRITE_TOOL
258
86
  }
259
87
 
260
- // The same question narrowed to calls that write nothing — the test `is_guarded_call` used to be, kept
261
- // under a name that says what it asks rather than deleted. **`scripts/delegation/investigation-reads.ts`
262
- // is its caller**, and it needs this answer rather than the one above: it refuses a `Bash` line only
263
- // where that line is unambiguously a read, so an in-place `sed` stays outside its reach even now that
264
- // the batching guard can refuse one. Widening the single predicate in place would have loosened that
265
- // guard silently, which is the one way this change could have gone wrong without a test noticing.
266
- //
267
- // **`may_write`, not `is_writing`** — this is a refusal test, and it is the one that has to over-call.
268
- // The dependency test reads the other field, which may not (joshuafolkken/kit#1509).
88
+ // For `investigation-reads.ts`, which refuses only unambiguous reads. `may_write` over-calls, as a
89
+ // refusal test must.
269
90
  function is_read_only_call(call: GuardedCall): boolean {
270
91
  const facts = time_bundle_call.call_facts(call.name, call.input)
271
92
 
272
93
  return facts.is_bundleable && !facts.may_write
273
94
  }
274
95
 
275
- // **A shared target is a dependency, and it is what keeps the guard off the search-then-read pair.**
276
- // `time-bundles.ts` treats two calls naming the same path — or one naming a directory the other reads
277
- // inside of — as ordered, and reuses that test here so a call the report would never have counted as
278
- // recoverable is never refused either.
279
- //
280
- // **It asks for the shared target alone, where `time_bundles.is_dependent` exempts a write following a
281
- // write, because the two are answering different questions** (joshuafolkken/kit#1762). The builder asks
282
- // "could these two have gone out together", and for two edits to one file the answer is yes — that
283
- // exemption is what lets such a stretch form a sequence at all (joshuafolkken/kit#1509). This asks "is
284
- // refusing this one safe", and there the same pair is the one case where it is not: the siblings of a
285
- // refused edit still run, so an edit naming a file the run is already rewriting comes back to text that
286
- // has moved under it. Both sides read `shares_target`, so there is one definition of what sharing a
287
- // target means and two uses of it rather than a second copy.
96
+ // A shared target is a dependency. Unlike `time_bundles.is_dependent`, a write after a write is not
97
+ // exempt: refusing an edit to a file the run is rewriting would reissue against moved text.
288
98
  function depends_on_sequence(sequence: ReadonlyArray<Span>, facts: BundleFacts): boolean {
289
99
  return sequence.some((span) => time_bundles.shares_target(span.targets, facts.targets))
290
100
  }
291
101
 
292
- // The instant the open sequence began, as far as the window shows. An empty sequence answers `NONE`,
293
- // and `NONE` is never greater than a recorded refusal — so the length test in `is_sequence_at_limit` is
294
- // what admits a run's first firing, and this decides only whether that firing is the sequence's first.
295
- //
296
- // **Both sides of that comparison are the same machine's wall clock**: the transcript's timestamps and
297
- // the instant the caller recorded. A clock that jumped backwards makes a record read as later than
298
- // every sequence, which withholds the firing — the safe direction, and the one every other failure here
299
- // takes too.
102
+ // A clock that jumped backwards withholds the firing — the safe direction.
300
103
  function sequence_started_ms(sequence: ReadonlyArray<Span>): number {
301
104
  return sequence[0]?.ended_ms ?? NONE
302
105
  }
303
106
 
304
- // How many of the open sequence's closed single-call turns ended after the last firing. For a run whose
305
- // last firing predates this sequence every turn counts; for one already spoken to inside this sequence
306
- // only the turns issued since count — which is what the re-fire interval is measured against.
307
107
  function turns_since(sequence: ReadonlyArray<Span>, last_fired_ms: number): number {
308
108
  return sequence.filter((span) => span.ended_ms > last_fired_ms).length
309
109
  }
310
110
 
311
- // **The firing test, first-time and re-fire in one** (joshuafolkken/kit#2164). The length and dependency
312
- // gates are unchanged. What changed is the instant comparison: where a firing predates the open
313
- // sequence it is that sequence's first, so the length gate alone decides it; where the run has already
314
- // been spoken to inside this sequence, it re-fires only once `REFIRE_EVERY` further single-call turns
315
- // have closed since. The old rule kept only the first branch, which is why it fell silent for the rest
316
- // of a run that kept single-calling.
111
+ // A firing before the open sequence makes this its first; inside it, re-fire every `refire_every` turns.
317
112
  function is_sequence_at_limit(
318
113
  sequence: ReadonlyArray<Span>,
319
114
  facts: BundleFacts,
@@ -327,14 +122,8 @@ function is_sequence_at_limit(
327
122
  return turns_since(sequence, last_fired_ms) >= refire_every
328
123
  }
329
124
 
330
- // **Nothing here reads the turn the call belongs to**, because nothing can: see "What it cannot know"
331
- // above. The two call-shaped tests are asked of the call in hand, and everything else of the turns
332
- // behind it.
333
- // The sequence test both dispositions share, over spans the caller has already parsed: is the open run
334
- // of single-call turns at the limit, for a call that began after the last time this disposition fired.
335
- // Shared so the refusal and the notice cannot drift apart on what "three in a row" means
336
- // (joshuafolkken/kit#1848), and taking spans rather than the tail so a disposition that also asks
337
- // `is_reissued_refusal` parses the transcript once (joshuafolkken/kit#1979).
125
+ // Shared by the refusal and the notice so they agree on "three in a row"; takes parsed spans so the
126
+ // transcript is parsed once.
338
127
  function is_at_limit(
339
128
  spans: ReadonlyArray<Span>,
340
129
  call: GuardedCall,
@@ -349,25 +138,11 @@ function is_at_limit(
349
138
  )
350
139
  }
351
140
 
352
- // This guard's own refusal label, as `time-transcript-line.ts` reads it back off a refused result: the
353
- // token after the ⛔ and before the first colon of REASON. Derived from REASON rather than written a
354
- // second time, so the two can never disagree about which refusals in the transcript are this guard's
355
- // (joshuafolkken/kit#1979).
141
+ // Derived from REASON, so the two never disagree about which transcript refusals are this guard's.
356
142
  const GUARD_LABEL = time_transcript_line.guard_from_refusal(REASON)
357
143
 
358
- // **A call the guard has already refused, found in the tail by the same identity the report compares
359
- // re-issues on** (joshuafolkken/kit#1979). A refused call the run answered by re-issuing it unchanged
360
- // is one that had nothing to batch — refusing the re-issue again buys a round trip and no batching,
361
- // which is the waste `time-guard-refusals.ts`'s `same_args_reissue` counts. The identity is built
362
- // through the same `to_tool_call` the transcript parse uses, so a refused span and the live call about
363
- // to repeat it produce the identical string.
364
- //
365
- // **This is what the timestamp alone could not do.** `refused_at_ms` withholds the immediate
366
- // re-refusal, but an unbroken run of single-call turns longer than the read window presents a sequence
367
- // start that has moved forward and is refused again (see "What it cannot know" above). The refused span
368
- // is still in the tail even when that start has scrolled out of view, so its identity is what survives.
369
- // The first refusal of a novel call still fires — only a call already on a refused span of this guard's
370
- // is let through, so a genuinely bundleable single call is refused exactly as before.
144
+ // An unchanged reissue of a refused call had nothing to batch, so it is let through. Matched by the
145
+ // same identity the report uses, it survives a sequence start that scrolled out of the window.
371
146
  function is_reissued_refusal(spans: ReadonlyArray<Span>, call: GuardedCall): boolean {
372
147
  const identity = time_call_identity.identity_of(
373
148
  time_spans.to_tool_call(call.name, call.input, time_spans.NO_MESSAGE_ID),
@@ -379,9 +154,7 @@ function is_reissued_refusal(spans: ReadonlyArray<Span>, call: GuardedCall): boo
379
154
  )
380
155
  }
381
156
 
382
- // `refire_every` defaults to the refusal's cadence so every existing caller reads unchanged; the
383
- // lane-child downgraded notice passes `NOTICE_REFIRE_EVERY` instead, so a refusable call turned into a
384
- // notice recurs on the notice's tighter cadence rather than the refusal's (joshuafolkken/kit#2276).
157
+ // The lane-child notice passes `NOTICE_REFIRE_EVERY` to recur on the notice's cadence.
385
158
  function should_block(
386
159
  text: string,
387
160
  call: GuardedCall,
@@ -397,11 +170,7 @@ function should_block(
397
170
  return is_at_limit(spans, call, refused_at_ms, refire_every)
398
171
  }
399
172
 
400
- // The notice's rule: the same sequence test, gated on the whole-file write rather than on a refusable
401
- // call. `notified_at_ms` is read from the notice's **own** record, so a notice never spends the
402
- // refusal's stamp and cannot silence a genuine refusal of a later read or edit on the same run. A
403
- // whole-file write is never refused, so it has no re-issue to detect — the reissue test is the
404
- // refusal's alone.
173
+ // `notified_at_ms` is the notice's own record, so a notice never silences a later refusal.
405
174
  function should_notify(text: string, call: GuardedCall, notified_at_ms: number): boolean {
406
175
  if (!is_notice_call(call)) return false
407
176
 
@@ -410,10 +179,7 @@ function should_notify(text: string, call: GuardedCall, notified_at_ms: number):
410
179
  return is_at_limit(spans, call, notified_at_ms, NOTICE_REFIRE_EVERY)
411
180
  }
412
181
 
413
- // One recent single-call turn named the way a reader would recognize it: the tool, and the file it
414
- // touched where the label does not already carry it (joshuafolkken/kit#2276). `label` is the tool name
415
- // for a non-shell call and the command for a shell one, so the target is appended only where it adds
416
- // something the label has not already said.
182
+ // The target is appended only where the label does not already carry it.
417
183
  function describe_span(span: NamedCall): string {
418
184
  const target = span.targets[0] ?? ''
419
185
  if (target === '' || span.label.includes(target)) return span.label
@@ -421,17 +187,9 @@ function describe_span(span: NamedCall): string {
421
187
  return `${span.label} ${target}`
422
188
  }
423
189
 
424
- // **The fewest reads that a composite call can fold** (joshuafolkken/kit#2311). One path is a single
425
- // call already, so nothing folds below two — the directive is withheld and the run keeps the guidance
426
- // alone, exactly as it does when the recent turns were not reads at all.
427
190
  const FOLD_MINIMUM = 2
428
191
 
429
- // **The recent single-call turns that were file reads, each named by the one path it read.** A fold
430
- // needs a *file* path, so three targets are dropped: one that named none (a bare `pwd`), a write (a run
431
- // of edits has nothing for `read:files` to do), and a directory (`ls scripts/` names `scripts/`, which
432
- // `read:files` cannot read — it would emit `Cannot read scripts/` and exit 1, so the paste-ready
433
- // command must never carry it). The directory test is `has_extension` reused from the target scanner,
434
- // not a second copy. Deduped, so a run that read one file twice folds it once and names it once.
192
+ // File paths only: no target, a write, or a directory (`read:files` cannot read one) is dropped.
435
193
  function read_targets(sequence: ReadonlyArray<NamedCall>): ReadonlyArray<string> {
436
194
  const paths = sequence
437
195
  .filter((span) => span.is_bundleable && !span.is_writing)
@@ -441,14 +199,7 @@ function read_targets(sequence: ReadonlyArray<NamedCall>): ReadonlyArray<string>
441
199
  return [...new Set(paths)]
442
200
  }
443
201
 
444
- // **The composite-command half of the notice** (joshuafolkken/kit#2311): the single call that folds the
445
- // recent single-call reads, handed to the run ready to paste. Naming the concrete calls did not move the
446
- // density (#2276) — the notice still asked the model to *reissue them in one turn*, which is a request
447
- // for the parallel `tool_use` blocks the model structurally resists. The lever measured to move
448
- // round-trip density is a composite command that folds a routine section into one call (`read:files`,
449
- // kit#2202); so the guard now offers *that* command, the one the model can emit in a single turn,
450
- // rather than another way to say "batch". Below two reads there is nothing to fold, so it is empty and
451
- // the guidance stands alone.
202
+ // A paste-ready composite command moves density where asking for parallel calls did not.
452
203
  function read_fold_directive(sequence: ReadonlyArray<NamedCall>): string {
453
204
  const paths = read_targets(sequence)
454
205
  if (paths.length < FOLD_MINIMUM) return ''
@@ -456,13 +207,7 @@ function read_fold_directive(sequence: ReadonlyArray<NamedCall>): string {
456
207
  return ` Fold them into one call: \`pnpm josh read:files ${paths.join(' ')}\`.`
457
208
  }
458
209
 
459
- // **The write-side counterpart of the read fold** (joshuafolkken/kit#2366): the recent single-call
460
- // `Edit` turns, folded into one `edit:files` call. The read fold pastes a whole command because a read
461
- // is addressed by its path alone; an edit carries its own text, so the fold names the files and points
462
- // at the command that applies a plan of edits over them in one call — the composite command the model
463
- // can emit in a single turn where reissuing the edits as parallel `tool_use` blocks is the shape it
464
- // resists. Only `Edit` counts: a whole-file `Write` creates content this command cannot content-address,
465
- // and it earns its own notice already. Below two edits there is nothing to fold.
210
+ // The write-side fold: an edit carries its own text, so it names the files for one `edit:files` plan.
466
211
  function write_targets(sequence: ReadonlyArray<NamedCall>): ReadonlyArray<string> {
467
212
  const paths = sequence
468
213
  .filter((span) => span.label === EDIT_TOOL)
@@ -479,8 +224,7 @@ function write_fold_directive(sequence: ReadonlyArray<NamedCall>): string {
479
224
  return ` Fold them into one \`pnpm josh edit:files\` call with a plan over: ${paths.join(' ')}.`
480
225
  }
481
226
 
482
- // The calls named, and their folds offered — the text both the refusable-call notice and the live
483
- // density line carry, written once so the two cannot word the same calls differently.
227
+ // Shared by the notice and the live density line, so both word the same calls alike.
484
228
  function name_candidates(calls: ReadonlyArray<NamedCall>): string {
485
229
  if (calls.length === NONE) return ''
486
230
 
@@ -490,29 +234,15 @@ function name_candidates(calls: ReadonlyArray<NamedCall>): string {
490
234
  return ` Just issued one per turn, so at least these could have shared a turn: ${named}.${folds}`
491
235
  }
492
236
 
493
- // **The concrete half of the notice** (joshuafolkken/kit#2276): the most recent single-call turns,
494
- // named, so the model is shown the calls it should have batched rather than only told to batch — and,
495
- // since kit#2311, the one `read:files` call that folds them where they were reads. Parsed from the tail
496
- // here rather than threaded from `should_notify` because it runs only when a notice actually fires,
497
- // which is rare enough that the second parse costs less than carrying the spans through the hook's
498
- // notice contract. An empty sequence names nothing and the notice falls back to its guidance alone.
237
+ // Re-parsed here rather than threaded through: it runs only when a notice actually fires.
499
238
  function recent_candidates(tail: string): string {
500
239
  return name_candidates(
501
240
  time_bundles.open_sequence(time_spans.parse_timeline(tail).spans).slice(-NAMED_CANDIDATE_COUNT),
502
241
  )
503
242
  }
504
243
 
505
- // **The candidates for a call that has already run** (joshuafolkken/kit#3157): what the `PostToolUse`
506
- // density line names. A lane child never sees the notice above — kit#2405 turned it `off` there — so
507
- // the density line is the one batching signal a lane receives, and until this it named nothing. The
508
- // call in hand is not in the open sequence (its turn has not closed), so it is named after the turns
509
- // behind it — and it is checked against them with the same shared-target test the refusal uses, so a
510
- // call that read what the turn before it wrote is never offered as one that could have gone beside
511
- // it. A call that is not bundleable names no targets, so the shared-target test cannot see what it
512
- // needs — `pnpm josh gate` after a run of edits reads every one of them — and it is never offered
513
- // either, exactly as `is_guarded_call` never refuses one. An empty answer means there is no concrete
514
- // pair to name, and the caller says nothing at all. A call the payload does not name is judged on the
515
- // closed turns alone.
244
+ // For the `PostToolUse` density line, a lane's only batching signal. The call in hand is named after
245
+ // the closed turns unless it depends on them or is not bundleable; empty means nothing to name.
516
246
  function pairing_candidates(tail: string, call: GuardedCall | undefined): string {
517
247
  const sequence = time_bundles.open_sequence(time_spans.parse_timeline(tail).spans)
518
248
 
@@ -529,15 +259,10 @@ function pairing_candidates(tail: string, call: GuardedCall | undefined): string
529
259
  return name_candidates([...sequence.slice(ONE_TURN - NAMED_CANDIDATE_COUNT), current])
530
260
  }
531
261
 
532
- // **This guard's own name for its once-per-run record.** It lives beside the rule rather than in
533
- // `batch-guard.ts` because a second module now has to read the same record: `delivered-rules.ts`
534
- // stands aside for this guard and has to ask whether it has *already* refused, and a second copy of
535
- // the string is the clone that would let the two disagree about which file they are reading.
262
+ // Here rather than in `batch-guard.ts`: `delivered-rules.ts` reads the same record.
536
263
  const STAMP_PREFIX = 'josh-batch-guard-'
537
264
 
538
- // The notice's own record, distinct from `STAMP_PREFIX` so a notice fired on a Write cannot move the
539
- // instant the refusal reads — the two dispositions dedupe independently, once each per run of
540
- // single-call turns (joshuafolkken/kit#1848).
265
+ // Separate, so the notice and the refusal dedupe independently.
541
266
  const NOTICE_STAMP_PREFIX = 'josh-batch-guard-notice-'
542
267
 
543
268
  const time_batch_guard = {