@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
@@ -10,7 +10,6 @@ import { filing_cap } from './filing-cap'
10
10
  import { git_force } from './git-force'
11
11
  import { implementation_cut } from './implementation-cut'
12
12
  import { issue_comments } from './issue-comments'
13
- import { issue_fold_rule } from './issue-fold-rule'
14
13
  import { josh_git_bare } from './josh-git-bare'
15
14
  import { lane_background } from './lane-background'
16
15
  import { lane_carry_conflict } from './lane-carry-conflict'
@@ -29,151 +28,70 @@ import { run_tail_rule } from './run-tail-rule'
29
28
  import { shell_body_trigger } from './shell-body-trigger'
30
29
  import { test_declared_commit } from './test-declared-commit'
31
30
  import { third_party_write } from './third-party-write'
32
- import { wip_cap } from './wip-cap'
33
31
  import { worktree_guard } from './worktree-guard'
34
32
 
35
- // The enumeration of rules delivered at the moment they bind, rather than carried resident in
36
- // `CLAUDE.md` on every turn (joshuafolkken/kit#1524).
37
- //
38
- // **It exists because residency ran out and delivery did not.** `CLAUDE.md` sits 6 tokens under the
39
- // ceiling `scripts/claude/workflow-skills.test.ts` enforces, while `prompts/` and `.claude/skills/` hold
40
- // fifteen times as much on demand — so the pressure is on the one channel that costs every turn.
41
- // joshuafolkken/kit#1344 measured three consecutive runs in which resident prose about batching moved
42
- // the number not at all, and joshuafolkken/kit#1460 measured the same for the investigation
43
- // threshold; in both, a `PreToolUse` refusal was what finally moved it. A rule whose trigger can be
44
- // named is therefore cheaper **and** stronger delivered than carried.
45
- //
46
- // **No new machinery.** `hook_decision.create_transcript_guard` is the shell both existing guards
47
- // already share (joshuafolkken/kit#1460) — the payload schema, the deny envelope, the switch, the
48
- // `.env` load and the once-per-run stamp — and every entry below is one of its specs. Building a
49
- // second delivery path would be the clone `CLAUDE.md` prohibits, in the one place where two paths
50
- // would disagree about whether a rule was delivered at all.
51
- //
52
- // **What this file is not.** It holds no rule *text* that exists nowhere else: each entry's reason is
53
- // the trigger plus the instruction that must be obeyed before anything else is read, and names the
54
- // topic file that carries the procedure — the same "trigger plus pointer" shape a resident rule takes
55
- // (`prompts/collaboration-workflow/residency.md`).
56
-
57
- // The escape hatch, on by default like the other two guards. A distributed convention nobody enabled
58
- // would leave this Issue where it started.
33
+ // The rules delivered by a `PreToolUse` refusal at the moment they bind, rather than carried resident
34
+ // in `CLAUDE.md` — a nameable trigger is cheaper and stronger delivered than carried. Every entry is a
35
+ // `hook_decision.create_transcript_guard` spec; each reason is a trigger plus a pointer to its topic
36
+ // file (`prompts/collaboration-workflow/residency.md`).
37
+
38
+ // The escape hatch, on by default like the other two guards.
59
39
  const SWITCH_ENV_KEY = 'JOSH_RULE_GUARD'
60
40
 
61
- // **What a compliance test is asked of: the call, the turn it went out in, and the run it belongs
62
- // to** — the calls the same assistant message issued, and every call the run made
63
- // (joshuafolkken/kit#1792 for the turn, joshuafolkken/kit#1867 for the run). Every row but two answers
64
- // from the call alone and simply ignores the rest, which is why widening the one signature costs them
65
- // nothing. **The batching rule cannot be written without the turn**: its subject is *how many calls a
66
- // turn carried*, and no field of a single call says that. **The pre-gate cut cannot be written without
67
- // the run**: a cut relaunches a second process that issues the identical entry check, so the two
68
- // halves are separable only by a call one of them makes elsewhere in the run. In both cases the
69
- // alternative was a second predicate slot beside this one, i.e. two ways to declare the same thing.
41
+ // A compliance test sees the call, its turn and its run: batching needs the turn, the pre-gate cut
42
+ // needs the run; every other row reads the call alone.
70
43
  type CallTest = (
71
44
  call: GuardedCall,
72
45
  turn: ReadonlyArray<GuardedCall>,
73
46
  run: ReadonlyArray<GuardedCall>,
74
47
  ) => boolean
75
48
 
76
- // One rule delivered by trigger. `id` keys its own refusal record, so one rule firing never spends
77
- // another's budget.
49
+ // `id` keys the rule's own refusal record, so one rule firing never spends another's budget.
78
50
  interface DeliveredRule {
79
51
  id: string
80
- // Whether this call is the moment the rule binds, judged from the call alone.
81
52
  is_trigger: (call: GuardedCall) => boolean
82
- // What the model is told. The deny reason is the only text that reaches it, so it carries the
83
- // instruction and the pointer rather than a summary of either.
53
+ // The only text that reaches the model: the instruction and the pointer.
84
54
  reason: string
85
- // **A stand-down read from the transcript tail, not the call** (joshuafolkken/kit#1905). A rule
86
- // whose subject a run can *satisfy earlier in the run* — the comments read on the first open, so a
87
- // later body read of the same Issue asks for nothing new — supplies this so the delivery is
88
- // suppressed once that earlier act is on the tail. It is checked before `is_first_delivery`, so a
89
- // satisfied call neither refuses nor spends the once-per-run record. Absent, delivery is unchanged.
55
+ // A stand-down when an earlier act on the tail already satisfied the rule; checked first, so a
56
+ // satisfied call spends no record.
90
57
  already_satisfied?: (tail: string, call: GuardedCall) => boolean
91
- // **A rule that has to bind on every occurrence supplies this, and once-per-run stops applying to
92
- // it** (joshuafolkken/kit#1570). Once per run is right for a rule a run then obeys — read the
93
- // comments, count the Issues, put the body in a file — because the refusal changes what the run
94
- // knows. It is wrong for one whose subject is a *recurring* act: refused once and free
95
- // afterwards, the enforcement is back to the parent's self-restraint, which is the thing that
96
- // failed. A row with this field is asked it instead, and it is asked on every candidate call —
97
- // `can_record` is what the batching stand-aside becomes for such a row (see `delivery_decision`).
98
- // **`delivered_at_ms` is this row's own last refusal instant** (joshuafolkken/kit#2385) — `fire_once`
99
- // writes the stamp only when a refusal actually fired, so a row that fires per crossing but must let
100
- // an immediate reissue through (the implementation-phase cut) can tell a fresh crossing from a
101
- // reissue of the edit it just refused. Rows that refuse unconditionally ignore it.
58
+ // For a rule that binds on every occurrence instead of once per run. `at_ms` is this row's own last
59
+ // refusal, so an immediate reissue can be let through.
102
60
  decide?: (call: GuardedCall, run: GuardRun, can_record: boolean, at_ms: number) => boolean
103
- // **What keeping this rule looks like, as a call** (joshuafolkken/kit#1525). It names the act the
104
- // rule asks for, so a run that made it *before* the trigger fired can be told apart from one that
105
- // complied only because the refusal made it. `scripts/rules/rule-value.ts` reads that difference
106
- // off recorded sessions to score what the rule's carried text earns unaided; a row that declares
107
- // none is reported unmeasured rather than scored, because "never kept" and "always kept" are both
108
- // claims the absence of a predicate does not support. It lives here rather than in the
109
- // measurement so a rule's trigger and its compliance test stay one definition.
61
+ // What keeping the rule looks like, for `rule-value.ts`; absent reads as unmeasured, not as a score.
110
62
  keeps?: CallTest
111
- // **The occasion the rule governs, read in either spelling** (joshuafolkken/kit#1643).
112
- // `is_trigger` is the right denominator for a rule whose trigger is a *neutral* act — filing an
113
- // Issue, reading one — because a run that keeps the rule makes that call too. It is the wrong one
114
- // for a rule whose trigger is the violation itself: a run that backgrounded every push never trips
115
- // `run-tail`, so it drops out of the reading altogether and the rate is taken over runs that broke
116
- // the rule at least once. Such a row declares this instead, and `scripts/rules/rule-value.ts`
117
- // counts a run that reached it whether or not the trigger fired. Absent, the denominator stays
118
- // `is_trigger` and the row's reading is exactly what it was.
63
+ // The occasion the rule governs, for a row whose trigger is the violation itself (else `is_trigger`
64
+ // would only count runs that broke it).
119
65
  reaches?: CallTest
66
+ // The note a hook attaches where it rewrites a violating call instead of refusing it, so
67
+ // `rule-value.ts` counts the rewrite as this row's delivery.
68
+ rewrite_note?: string
69
+ // Openings the reason had before it was reworded, so `rule-value.ts` still credits a refusal
70
+ // delivered with the old text while those transcripts remain in its window.
71
+ former_reasons?: ReadonlyArray<string>
120
72
  }
121
73
 
122
- // **A rule the measurement scores, whether or not `pnpm josh rule:guard` is what delivers it**
123
- // (joshuafolkken/kit#1792). `DELIVERED_RULES` is the *delivery* registry — every row in it becomes a
124
- // live `PreToolUse` guard through `GUARDS` below — so a rule already delivered by a binary of its own
125
- // cannot join it without being refused twice for one violation, each refusal spending a record the
126
- // other cannot see. The batching guard is that rule: `pnpm josh batch:guard` has delivered it since
127
- // joshuafolkken/kit#1344, and until now it was the one delivered rule `pnpm josh rule:value` could
128
- // not read. So the two registries are separated rather than merged, and `is_trigger` — the field
129
- // that only a *delivered* row needs, because it is what `guard_of` makes the candidate test from —
130
- // becomes the one optional field here.
74
+ // Scored but possibly delivered by its own binary (batching, investigation) — joining `DELIVERED_RULES`
75
+ // would refuse one violation twice — so `is_trigger` is optional here.
131
76
  type MeasuredRule = Omit<DeliveredRule, 'is_trigger'> & {
132
77
  is_trigger?: DeliveredRule['is_trigger']
133
78
  }
134
79
 
135
80
  const STAMP_PREFIX = 'josh-rule-guard-'
136
81
 
137
- // **`is_issue_filing` and `on_bash_command` moved to `bash-triggers.ts`** (joshuafolkken/kit#2119):
138
- // three rows share the filing trigger — the WIP cap, the per-run filing cap and the fold — and the
139
- // last two live in their own modules, which could not import the enumeration back to reach a private
140
- // function of it. `on_bash_command` went with it because those modules build their own rows.
141
82
  const { is_issue_filing, on_bash_command } = bash_triggers
142
83
 
143
- // The reading of the call itself — which spellings carry a body inline, and what the shell does to
144
- // the value — is `shell-body-trigger.ts`, beside its own cases, as is the refusal text. A row states
145
- // its trigger and its text; a model of zsh quoting is more than a row.
146
84
  const { SHELL_BODY_REASON, carries_a_body, is_shell_evaluated_body, keeps_body_safe } =
147
85
  shell_body_trigger
148
86
 
149
- // **The occasion the pre-gate cut governs, in the one shape that separates a cut run's two halves**
150
- // (joshuafolkken/kit#1867). Asking about the cut is what a lane child does whatever it goes on to do;
151
- // claiming the working tree is what only the process on the near side of the boundary does, because
152
- // the `resume` verdict tells its counterpart to skip that claim. A run doing both reached the
153
- // boundary; a run that asked without claiming is the session the cut produced, which had no cut of
87
+ // Order matters only where triggers overlap (see `delivery`); the notes below name each overlap.
154
88
  const DELIVERED_RULES: ReadonlyArray<DeliveredRule> = [
155
- // **Listed first, ahead of the filing trigger it overlaps** (joshuafolkken/kit#2122). A `gh api`
156
- // that files an Issue into a repository we do not own trips both this row and `wip-cap` /
157
- // `issue-scout` / `filing-cap` — but the backlog count, the scout and the per-run cap are all about
158
- // filing into *our own* backlog, so on a third-party target the right answer is to stop the write
159
- // entirely rather than to count anything. Placing it first means a third-party write is refused
160
- // before any of those speak; on a first-party filing it is silent (the owners match), so `wip-cap`
161
- // still speaks first, exactly as before. It fires on every occurrence (`git-force.ts`).
89
+ // First: a third-party write is stopped before the first-party filing rows count anything.
162
90
  third_party_write.ROW,
163
- // **A hand-built filing is refused on every occurrence** (joshuafolkken/kit#2808) and pointed at
164
- // `josh issue:file`, which runs the scout, the lint, the labels, the `## Origin` check and
165
- // `epic:bundle` itself. It claims the direct call only, so the rows below — which trigger on the
166
- // `issue:file` call — never overlap it.
91
+ // The direct call only; `filing-cap` below triggers on `issue:file`. The WIP cap and the fold
92
+ // question are `issue:file`'s own steps, so no row gates them.
167
93
  direct_filing.ROW,
168
- wip_cap.ROW,
169
- // **Two more rows share the filing trigger** (joshuafolkken/kit#2119, joshuafolkken/kit#2213), listed
170
- // after `wip-cap` so the backlog count still speaks first: `filing-cap` refuses every filing past
171
- // the per-run ceiling, and `issue-fold` refuses a *second* filing the run has not folded. Each is a
172
- // real instance of the admissible overlap the comment on `delivery` describes — the losing rule's
173
- // delivery is still correct one reissue later — so an unfolded, over-cap second filing is delivered
174
- // `wip-cap`, then `filing-cap`, then `issue-fold` across its reissues.
175
94
  filing_cap.ROW,
176
- issue_fold_rule.ROW,
177
95
  issue_comments.ROW,
178
96
  {
179
97
  id: 'shell-body',
@@ -182,12 +100,6 @@ const DELIVERED_RULES: ReadonlyArray<DeliveredRule> = [
182
100
  keeps: on_bash_command(keeps_body_safe),
183
101
  reaches: on_bash_command(carries_a_body),
184
102
  },
185
- // **The sibling of `shell-body`, one call further along** (joshuafolkken/kit#2304). `shell-body`
186
- // refuses a body passed inline so the shell evaluates it; this refuses a body passed by path with
187
- // the raw field flag (`-f` / `--raw-field body=@<path>`), which posts the literal `@<path>`. It
188
- // claims no command any row above does — `shell-body` triggers on a backtick or `$`, which the
189
- // `@<path>` misfire carries neither, and `is_issue_filing` leaves the comment endpoint alone — so
190
- // the exactly-one-rule invariant over its fixtures holds. It fires on every occurrence (`git-force.ts`).
191
103
  raw_field_body.ROW,
192
104
  {
193
105
  id: 'piped-verification',
@@ -195,6 +107,8 @@ const DELIVERED_RULES: ReadonlyArray<DeliveredRule> = [
195
107
  reason: piped_verification.PIPED_VERIFICATION_REASON,
196
108
  keeps: on_bash_command(piped_verification.keeps_verdict_intact),
197
109
  reaches: on_bash_command(piped_verification.runs_verification),
110
+ // A `| tail` / `| grep` masking is rewritten under `pipefail` by `pretool-guard.ts`, never refused.
111
+ rewrite_note: piped_verification.PIPEFAIL_NOTE,
198
112
  },
199
113
  {
200
114
  id: 'early-heartbeat',
@@ -204,29 +118,11 @@ const DELIVERED_RULES: ReadonlyArray<DeliveredRule> = [
204
118
  keeps: on_bash_command(early_heartbeat.is_progress_watch),
205
119
  reaches: on_bash_command(early_heartbeat.waits_for_progress),
206
120
  },
207
- // **Listed before `run-tail`, the one row it deliberately overlaps** (joshuafolkken/kit#2118). A
208
- // foreground `pnpm josh git -y` with no test beside the change is claimed by both: `test-declared`
209
- // decides whether the commit should happen at all, so it is listed first, exactly as `wip-cap`
210
- // precedes `shell-body` for deciding whether an Issue should exist. Nothing is lost by `run-tail`
211
- // losing the race — the stamps are keyed per `id`, so the reissued push is delivered `run-tail`,
212
- // which is asserted rather than assumed. The overlap only arises in a real checkout where the
213
- // verdict is `required`; in the hermetic non-repo suite the git read fails to `exempt`, so
214
- // `test-declared` claims nothing and the "exactly one rule" invariant over `run-tail`'s fixture holds.
121
+ // Before `run-tail`: whether to commit at all is decided before how to push.
215
122
  test_declared_commit.ROW,
216
- // **The long-running josh command a lane child backgrounds and loses** (joshuafolkken/kit#2704). A
217
- // headless child's background tasks die with its turn, so a backgrounded `josh gate` / `git` /
218
- // `followup` is killed before it reports; this refuses the launch and hands back `josh ship
219
- // --detach`, whose supervisor outlives the turn. **Listed before `run-tail`, whose push it claims in
220
- // a child**: that row answers a foreground push with "reissue it backgrounded", the reissue this row
221
- // refuses, so a child is sent to the detached ship on its first refusal instead of through both.
222
- // Outside a child it claims nothing. A backgrounded bare `josh git` also trips `josh-git-bare`
223
- // below; this row wins, and `ship --detach` satisfies both. It fires on every occurrence.
123
+ // Before `run-tail`, so a lane child goes straight to `ship --detach` instead of through both.
224
124
  lane_background.ROW,
225
- // **The one row whose trigger reads a field of the input beside the command**, so it supplies its
226
- // own tool-name check rather than going through `on_bash_command`: a push step already issued with
227
- // `run_in_background` is the rule obeyed, and refusing it would charge a run for doing the right
228
- // thing. It supplies `decide` because a push is a recurring act — one per child in a batch, and a
229
- // second inside one `fullrun` when round 2 fixes a finding in place.
125
+ // Reads `run_in_background` beside the command; `decide`, since a push recurs.
230
126
  {
231
127
  id: 'run-tail',
232
128
  is_trigger: run_tail_rule.is_foreground_push_step,
@@ -235,36 +131,10 @@ const DELIVERED_RULES: ReadonlyArray<DeliveredRule> = [
235
131
  keeps: run_tail_rule.is_backgrounded_push_step,
236
132
  reaches: run_tail_rule.is_push_step_call,
237
133
  },
238
- // **The one row whose trigger consults the world beside the command**, because "is this a lane that
239
- // has not cut" is not readable from the call: it is the working directory's own name and the cut
240
- // record on disk. Both reads are synchronous, and the command match runs first, so a run that never
241
- // types `pnpm josh gate` pays nothing for it.
242
- //
243
- // **Once per run rather than `decide`, and the direction of the error is why.** Taking the cut ends
244
- // the process, so this is not the recurring act joshuafolkken/kit#1570 wrote `decide` for — and the
245
- // five verdicts that legitimately leave a run at the gate (`not-a-lane`, `unready`, `busy`,
246
- // `failed`, `unknown`) all need the reissue to go through. A row that refused every time would wedge exactly
247
- // those runs; a row that refuses once cannot.
248
- //
249
- // **`pnpm josh rule:value` read this row with a ceiling of about 50%, and joshuafolkken/kit#1867 is
250
- // what removed it** (the ceiling was recorded here by joshuafolkken/kit#1864's review round 2). A
251
- // cut relaunches a *new session*, which the measurement groups as a run of its own, and that
252
- // resumed run issues the entry check — so scored on the asking alone it joined the denominator
253
- // while never being able to satisfy `keeps`, which only the cutting run can, and ten perfectly
254
- // obedient children read as ten kept out of twenty. **The two halves are separable, just not from
255
- // one call**: both processes issue byte-identical `--resume` strings, but the `fresh` verdict sends
256
- // a run on to claim the working-tree hold while the `resume` verdict tells its counterpart to skip
257
- // that claim. `reaches_the_pre_gate_boundary` is that conjunction, and it is why `CallTest` is
258
- // handed the run's calls beside the turn's rather than a second predicate slot of its own.
259
- // Dropping `reaches` altogether is still strictly worse — the trigger evaluates against the
260
- // *measuring* process's working directory, so it is always false from the main checkout and the row
261
- // would read as no runs at all.
262
- //
263
- // **It overlaps `piped-verification` on a piped gate call, and the order is safe in both
264
- // directions.** `pnpm josh gate | tail` in an uncut lane is a real instance of both defects; the
265
- // earlier row speaks, its own reason says to reissue, and this one delivers on the reissue — the
266
- // reading "the losing rule's delivery is still correct one call later" that the comment below
267
- // requires of any admissible overlap.
134
+ // Reads the lane name and the cut record. Once per run, not `decide`: taking the cut ends the
135
+ // process, and the verdicts that leave a run at the gate all need the reissue through. `reaches`
136
+ // tells the cutting run from the resumed one by the run's calls. Overlaps `piped-verification`
137
+ // safely: that row speaks first and this one delivers on the reissue.
268
138
  {
269
139
  id: 'pre-gate-cut',
270
140
  is_trigger: on_bash_command(pre_gate_cut.is_uncut_gate),
@@ -272,158 +142,36 @@ const DELIVERED_RULES: ReadonlyArray<DeliveredRule> = [
272
142
  keeps: on_bash_command(pre_gate_cut.takes_the_cut),
273
143
  reaches: pre_gate_cut.reaches_the_pre_gate_boundary,
274
144
  },
275
- // **The second row whose trigger consults the world beside the command** (joshuafolkken/kit#2034):
276
- // "is this a dispatched lane child" is the dispatch mark against this checkout's own issue, read
277
- // synchronously by `lane_child_marker.is_child_of`, and the command match runs first so an ordinary
278
- // run pays nothing for it.
279
- // Its once-per-run disposition is stated beside the row in `lane-park.ts`.
280
- //
281
- // **A split child's park is refused first** (joshuafolkken/kit#3296): a lane child that promoted its
282
- // own Issue to an epic this run has nothing to park, so `lane-split-park` refuses the label write
283
- // and the confirmation notify onto that epic on every occurrence. It shares the notify with
284
- // `lane-park` and is listed first; a run that promoted nothing falls through to `lane-park`.
145
+ // A split child's park is refused before `lane-park` sees it.
285
146
  lane_split_park.ROW,
286
147
  lane_park.ROW,
287
- // **joshuafolkken/kit#2034's rule, one tool-call earlier** (joshuafolkken/kit#2201). `lane-park`
288
- // fires on the `confirmation` notify a routed child reaches; a child that reaches for
289
- // `AskUserQuestion` never gets there, because the harness ends its turn at the refused ask. This
290
- // row's trigger is that ask, so the refusal becomes an instruction — park the question — instead of
291
- // the child's death. Its trigger reads the input's tool name and consults the dispatch mark, like
292
- // `lane-park`, and shares no command with any Bash row, so it claims no `gh` / `git` / `josh` call.
293
- // It fires on every occurrence (`decide` returns true), the disposition `git-force.ts` takes: an
294
- // interactive ask must never succeed in a child, and the route is always the park, never a reissue.
295
148
  lane_interactive_ask.ROW,
296
- // **The parent budget commands a lane child must never run** (joshuafolkken/kit#2267). A dispatched
297
- // child that ran `pnpm josh run:merge` read its `busy` as a competing session and parked its Issue
298
- // unimplemented — but the live carry record is the parent that launched it, never a competitor. This
299
- // row refuses `run:merge` / `run:carry` in a lane child and hands back the mechanical branch: the
300
- // record is the parent's, so continue implementing rather than park or ask. Its trigger claims a
301
- // `josh` subcommand no other row does (the filing rows are `gh`, `run-tail` is `git push`), so it
302
- // overlaps nothing. It fires on every occurrence (`decide` returns true): a child must never run
303
- // these, and the route is always "continue", never a reissue (`git-force.ts`).
304
149
  lane_carry_conflict.ROW,
305
- // **The `git switch main` a lane child can never succeed at** (joshuafolkken/kit#2313), the fifth of
306
- // the "always fails" misfires joshuafolkken/kit#2297 catalogued. A lane is a linked work tree and the
307
- // primary checkout holds the default branch, so a child's `git switch main` fails structurally
308
- // (`already used by worktree`); this refuses it before it fails and hands back the next command —
309
- // skip the step, `pnpm josh main:merge` brings the default in during the gate. Its trigger reads the
310
- // dispatch mark and the lane branch like `lane-carry-conflict`, and claims a `git switch` no row
311
- // above matches — `git-force` is `git push` / `git branch`, `worktree-mutation` is `git checkout --`
312
- // / `restore` / `stash` — so no two rows claim one command. It fires on every occurrence (`decide`
313
- // returns true): a child must never run this, and the route is always "continue" (`git-force.ts`).
314
150
  lane_switch_main.ROW,
315
- // **A `pnpm josh git` with no `-y` cannot succeed from an agent** (joshuafolkken/kit#2297). It
316
- // prompts to confirm the staging, the no-TTY prompt cancels, and the run reissues with `-y` after
317
- // throwing away the time it took to fail. This row refuses the bare call and hands back the `-y`
318
- // form. It is disjoint from `run-tail` by the flag — that row requires `-y`, this refuses its
319
- // absence — so no two rows claim one command. It fires on every occurrence (`decide` returns true):
320
- // a bare call wastes the same time each time, so the route is always the `-y` reissue
321
- // (`git-force.ts`).
151
+ // Disjoint from `run-tail` by the `-y` flag.
322
152
  josh_git_bare.ROW,
323
- // **The three Bash-string gaps the deny glob cannot express** (joshuafolkken/kit#2120), each reading
324
- // the command's argv rather than a literal a glob keys on. They share no trigger with any row above —
325
- // force/delete is `git push` / `git branch`, the worktree change is `git checkout` / `restore` /
326
- // `stash`, and the file body is a heredoc / `node -e` / `perl -i` — so no two rows claim one command,
327
- // which `delivered-rules-bash.test.ts` pins. Each declares `decide` returning true: a destructive or
328
- // billed act is refused on every occurrence, never once per run (`git-force.ts`).
153
+ // The Bash-string gaps the deny glob cannot express, read by argv; `delivered-rules-bash.test.ts`
154
+ // pins that no two rows claim one command.
329
155
  git_force.ROW,
330
156
  worktree_guard.ROW,
331
157
  file_body.ROW,
332
- // **The deny-list bypasses closed by argv and path rather than glob** (joshuafolkken/kit#2983) — an
333
- // index mutation, a recursive forced `rm` or destructive `gh` call, and a protected file. Each
334
- // claims a command or file no row above does and refuses every occurrence (`permission-guards.ts`).
335
158
  ...permission_guards.ROWS,
336
- // **The hand-written wait loop a lane child improvises over a backgrounded command's output**
337
- // (joshuafolkken/kit#2371). `early-heartbeat` refuses a bare `sleep` and stands down on any loop
338
- // keyword; this is the loop it left — a `while`/`until` that sleeps between probes of an output
339
- // file. Its trigger claims a command no row above matches: the loop-plus-`sleep` shape carries no
340
- // `gh` / `git` / `josh` subcommand any other trigger keys on, and a poll loop is never a bare
341
- // `sleep` (the loop keyword makes `early-heartbeat.is_wait_timer` false), so the Bash
342
- // `rules_claiming` invariant holds. It fires on every occurrence (`decide` returns true): a poll
343
- // loop wastes the same round trips each time, so the route is always "background it and end the
344
- // turn", never a reissue (`git-force.ts`).
345
159
  poll_loop.ROW,
346
- // **The second row whose trigger is an `Edit` / `Write` rather than a shell call**
347
- // (joshuafolkken/kit#2310), and the third that consults the world beside the call: "is this a lane
348
- // child whose recent-context cost has crossed the threshold" reads the dispatch mark, the cut record
349
- // on disk and the synchronous `pnpm josh cost --cut` verdict — the same measurement the parent
350
- // hand-off uses, never a second one (joshuafolkken/kit#1933). The `Edit` / `Write` name match runs
351
- // first, then the lane read, then the transcript-priced verdict, so a run that is not a dispatched
352
- // child in an uncut lane pays nothing for it. It self-gates on the tool name, so it claims no `Bash`
353
- // command any row above matches — the Bash `rules_claiming` invariant is untouched.
354
- //
355
- // **Listed before `rule-body`, the one row it can overlap.** Both trigger on an `Edit` / `Write`; a
356
- // rule-document edit made in a lane child that is already over threshold trips both. The cut is the
357
- // right thing to do first — end the process and drop the accumulated context — and on the reissue in
358
- // the fresh, under-threshold process this row is silent and `rule-body` delivers, the "losing rule's
359
- // delivery still correct one reissue later" reading any admissible overlap needs.
360
- //
361
- // **It carries `decide`, and the inversion of the pre-gate cut's reasoning is why** (joshuafolkken/kit#2385).
362
- // `pre-gate-cut` and `lane-park` are once per run because taking the cut, or the park, *ends the
363
- // process* — the one act is not a recurring one, and the five verdicts that leave a run holding it
364
- // all need the one reissue to go through. This cut ends the process too, but its *trigger* does not:
365
- // crossing the threshold mid-implementation is a recurring state that once-per-run silenced for the
366
- // rest of a process the moment its first refusal landed — so a `busy` / `failed` / `unready` verdict,
367
- // or an edit the model reissued unchanged, left the context to grow unwatched (joshuafolkken/kit#2382
368
- // ran to 282,747 tokens with the cut never taken). `decide` re-asks on every over-threshold edit, and
369
- // its `delivered_at_ms` lets an edit reissued right after a refusal through, so `busy` / `failed`
370
- // cannot wedge the run edit after edit — the reissue path once-per-run gave for free, now made
371
- // explicit. The fresh process after a successful cut reads its own transcript under threshold, so it
372
- // is silent without needing a carried record to quiet it.
373
- //
374
- // **No `reaches`, because the occasion is live-only.** `pre-gate-cut` gives a `reaches` because both
375
- // its halves leave a command-string trace (`run:cut --resume` at entry); this row's occasion —
376
- // crossing the threshold mid-implementation — is the working directory, the cut record and the cost
377
- // verdict, none of which a transcript records. `pnpm josh rule:value` therefore reads it as no runs
378
- // rather than as 0% kept (`keeps` stays, so the compliance act is named for a future measurement
379
- // redesign), the same honest-unmeasured stance the batching and investigation rows take for the same
380
- // reason: a trigger no transcript can reconstruct. The row itself lives in `implementation-cut.ts`.
160
+ // Before `rule-body`, its one overlap: the cut is the right first act, and `rule-body` delivers on
161
+ // the reissue in the fresh process.
381
162
  implementation_cut.ROW,
382
- // **The first row whose trigger is an `Edit` / `Write` rather than a shell call**
383
- // (joshuafolkken/kit#2272). It delivers the residency questions at the edit that writes a rule into
384
- // prose, and self-gates on the tool name and the file path, so it claims no `Bash` command any row
385
- // above matches — the `rules_claiming` invariant over Bash fixtures is untouched. It carries no
386
- // `decide`, so it is once per run and takes the batching stand-aside `is_first_delivery` gives every
387
- // default row: the batching guard treats an `Edit` as a candidate, exactly as it treats an Issue
388
- // read, so this row stands aside on a batched turn and delivers on the reissue.
389
163
  rule_body_guard.ROW,
390
- // **The generic oracle-consulted rows, one per oracle that declared a firing point**
391
- // (joshuafolkken/kit#2324). Each refuses the action the oracle governs when the run has not run that
392
- // oracle's command first, stood down once it has. Listed last; the one firing point left
393
- // (`pkg:scout` on a package add) claims a command no row above matches.
394
164
  ...oracle_consulted.ROWS,
395
165
  ]
396
166
 
397
- // A turn that issued more than this many calls is a turn that batched. The guard counts turns that
398
- // issued a *single* tool call, so the boundary is the same one `SEQUENCE_BEFORE_LIMIT` is counted in.
399
167
  const ALONE_IN_TURN = 1
400
168
 
401
- // **Keeping the batching rule is a refusable call that went out beside siblings** — the one
402
- // compliance test of the seven that cannot be read off the call alone (joshuafolkken/kit#1792). The
403
- // guard's whole subject is the run of turns that each issued one call, so the act it asks for is a
404
- // turn carrying more than one, and `is_guarded_call` is what keeps the credit to calls the guard
405
- // could actually have refused: a turn of two `Write`s is not the rule being kept, because neither
406
- // call was ever at risk.
169
+ // Kept: a call the guard could refuse went out beside siblings.
407
170
  function batches_the_turn(call: GuardedCall, turn: ReadonlyArray<GuardedCall>): boolean {
408
171
  return time_batch_guard.is_guarded_call(call) && turn.length > ALONE_IN_TURN
409
172
  }
410
173
 
411
- // **The row `pnpm josh rule:value` scores the batching guard from** (joshuafolkken/kit#1792). It is
412
- // measured but not delivered, for the reason `MeasuredRule` states.
413
- //
414
- // **It declares no `is_trigger`, and that is the honest answer rather than a gap.** Whether a call
415
- // would be refused depends on the turns *behind* it — `time_batch_guard.should_block` reads the
416
- // transcript tail for exactly that — and `scripts/rules/rule-value.ts` hands a predicate one call at
417
- // a time, so a call-shaped trigger here could only ever be a guess. What the transcript does record
418
- // is the refusal itself, and the measurement takes that as the trigger: compliance credited after a
419
- // refusal is the delivery's contribution, which is the same line every other row is scored on.
420
- //
421
- // **The `reaches` half is what keeps the reading off zero**, the failure joshuafolkken/kit#1643
422
- // named. The batching guard fires only on the violation, so scored against its trigger the rate
423
- // would be taken over runs that broke the rule at least once and would read near zero by
424
- // construction — a manufactured retirement candidate for the most-cited resident rule there is. The
425
- // occasion it governs is issuing a call the guard could refuse, in *either* spelling: alone in its
426
- // turn, or beside the calls that did not need its result.
174
+ // No `is_trigger`: a refusal depends on the turns behind a call, so the recorded refusal is the trigger.
427
175
  const BATCHING_RULE: MeasuredRule = {
428
176
  id: 'batching',
429
177
  reason: time_batch_guard.REASON,
@@ -431,94 +179,32 @@ const BATCHING_RULE: MeasuredRule = {
431
179
  reaches: time_batch_guard.is_guarded_call,
432
180
  }
433
181
 
434
- // **The row `pnpm josh rule:value` scores the investigation guard from** (joshuafolkken/kit#1764).
435
- // It is measured but not delivered, for exactly the reason the batching row is: `josh
436
- // investigation:guard` has delivered it since joshuafolkken/kit#1460, and a row in `DELIVERED_RULES`
437
- // would refuse the same violation a second time, each refusal spending a record the other cannot
438
- // see. Until now it was the second delivered rule the measurement could not read at all — and the
439
- // one whose subject, `investigation` at 35.9% of a run's turns, is the largest contributor any
440
- // mechanism here addresses.
441
- //
442
- // **It declares no `is_trigger`, and that is honest rather than a gap.** Whether a read would be
443
- // refused depends on the reads *behind* it — `investigation_reads.should_block` reads the transcript
444
- // tail for exactly that — and the measurement hands a predicate one call at a time, so a call-shaped
445
- // trigger could only be a guess. The refusal itself is what the transcript records, and
446
- // `observe_error` takes that as the trigger.
447
- //
448
- // **`reaches` is the read the guard could have refused, not the refusal**, the distinction
449
- // joshuafolkken/kit#1643 drew: scored against a trigger that fires only on the violation, the rate
450
- // would be taken over runs that broke the rule at least once and would read near zero by
451
- // construction.
452
- //
453
- // **It declares no `keeps` either, and the unmeasured cell is the honest answer rather than a gap.**
454
- // The obvious predicate — a subagent dispatch — credits *any* dispatch, because that is what the
455
- // guard's own reset does; a run that read twenty files in the main line, was never refused and sent
456
- // one review agent at the end would score as full compliance. That row would sit near 100% for the
457
- // rule this very Issue measures as let through on a third of all reads, and `pnpm josh rule:value` is
458
- // what retirement decisions are read from. The module's own doctrine settles it: a rule with no
459
- // `keeps` is reported unmeasured, because 0 and 1 are both claims the data does not make. **The
460
- // compliance reading exists elsewhere and is better**: `pnpm josh time`'s `Investigation reads:`
461
- // block, built from this same guard's predicates, says per run how much reading was refused, let
462
- // through, or main-line by design. What this row adds is the reach and the delivery count, which is
463
- // the continuous reading the guard had none of.
182
+ // No `is_trigger`, as for batching. No `keeps`: any dispatch would read as compliance, so it is left
183
+ // unmeasured — `pnpm josh time`'s `Investigation reads:` block is the compliance reading.
464
184
  const INVESTIGATION_RULE: MeasuredRule = {
465
185
  id: 'investigation',
466
186
  reason: investigation_reads.REASON,
467
187
  reaches: investigation_reads.is_refusable_call,
468
188
  }
469
189
 
470
- // Every rule the measurement can score, delivery registry first so a printed table reads in
471
- // enumeration order with the rows delivered from here at the top.
472
190
  const MEASURED_RULES: ReadonlyArray<MeasuredRule> = [
473
191
  ...DELIVERED_RULES,
474
192
  BATCHING_RULE,
475
193
  INVESTIGATION_RULE,
476
194
  ]
477
195
 
478
- // **Once per run, never once per call.** A rule delivered again on the next call would wedge a run
479
- // that had already obeyed it, which is the failure `hook_decision`'s stamp exists to prevent; the
480
- // reason text says so, so a reader knows reissuing is the expected next move.
481
- //
482
- // **The tail read is what keeps two `Bash` guards off the same call.** `pnpm josh batch:guard` is
483
- // wired to `Bash` as well, and the shared shell records the stamp *before* returning a reason. Claude
484
- // Code surfaces one permission decision per call, so a call both hooks refused would lose one of the
485
- // two reasons while both records were already written — and a rule whose record is set can never fire
486
- // again in that run. That is a silent deletion, of exactly the kind this enumeration exists to
487
- // prevent. So a call the batching guard may refuse is **stepped aside from rather than delivered
488
- // on**: nothing is recorded (the shared shell stamps only after `should_block` answers true), the
489
- // batching guard's own reason says to reissue the call, and this rule delivers on the reissue.
490
- //
491
- // **Inert for `wip-cap` and live for `issue-comments`, which is why it was written before either
492
- // needed it.** The batching guard does not treat a filing call as a candidate at all, so the branch
493
- // never fires for `wip-cap`; it *does* treat `gh issue view` as one, so the second row genuinely
494
- // stands aside on a turn the batching guard is about to refuse and delivers on the reissue.
495
- // `delivered-rules.test.ts` pins both halves, and it is what any new row has to be re-checked
496
- // against. Erring toward standing aside costs at most one call's delay, while erring the other way
497
- // costs the rule for the whole run.
498
- // The batching guard's own record for this run, read through the same shell that writes it.
196
+ // Once per run, so a run that obeyed is never wedged. A call the batching guard may refuse is stepped
197
+ // aside from: only one hook's reason surfaces per call, and a stamp written for a lost reason would
198
+ // silence the rule for the run. The rule delivers on the reissue instead.
499
199
  const BATCH_STAMP = hook_decision.create_refusal_stamp(time_batch_guard.STAMP_PREFIX)
500
200
 
501
- // **A record this young is the batching guard speaking about the call in hand.** The two hooks are
502
- // separate processes started for the same `PreToolUse` event with no ordering between them, and the
503
- // shared shell writes its stamp *before* it returns a reason — so presence alone cannot answer "has
504
- // it refused?" without making the stand-aside depend on which process won the race. A record older
505
- // than this window is a refusal about an earlier call, which that guard will not repeat on the same
506
- // open sequence, and this rule is free to speak.
201
+ // The two hooks race on one event and the stamp is written before the reason, so a record this young
202
+ // is the batching guard speaking about the call in hand.
507
203
  const BATCH_REFUSAL_WINDOW_MS = 10_000
508
204
 
509
- // **The question is what the batching guard will do on this call, not what it would do from a clean
510
- // slate.** Asked with `NEVER_MS` in place of its record, the answer stayed `true` for the whole of an
511
- // open sequence it had *already* refused — and since that guard will not refuse the same sequence
512
- // twice, a run that kept single-calling after being refused had neither hook speak, and this rule was
513
- // lost for the run with nothing recorded to say so. That is the silent deletion the stand-aside
514
- // exists to prevent, arrived at from the other side.
205
+ // Asked with its real record, not `NEVER_MS`: that guard never refuses one sequence twice.
515
206
  function will_batch_guard_refuse(tail: string, call: GuardedCall, run: GuardRun): boolean {
516
- // In a dispatched lane child the batching guard no longer refuses (joshuafolkken/kit#2138,
517
- // joshuafolkken/kit#2164, joshuafolkken/kit#2178, joshuafolkken/kit#2276): its mode is `notice`, so it
518
- // speaks but never denies. It will *refuse* nothing there, and the stand-aside must agree — or a lone
519
- // rule trigger (`shell-body`) would be stepped aside from for a batching refusal that can no longer
520
- // come and lost for the run. The test is therefore "will it refuse", i.e. mode `refuse`, not "is it
521
- // notice or off".
207
+ // In a lane child the batching guard only notices, so there is nothing to stand aside for.
522
208
  if (lane_guard_policy.mode_here('batching') !== 'refuse') return false
523
209
 
524
210
  const refused_at_ms = BATCH_STAMP.last_ms(BATCH_STAMP.path(run.transcript))
@@ -537,23 +223,9 @@ function is_first_delivery(
537
223
  return delivered_at_ms === hook_decision.NEVER_MS && !will_batch_guard_refuse(tail, call, run)
538
224
  }
539
225
 
540
- // **For a row that decides for itself, the stand-aside changes what it protects.** For a once-per-run
541
- // row it protects the *record*, because a lost race spends the one delivery the run gets. A recurring
542
- // row cannot be silently deleted that way — it fires again — and standing aside from the refusal would
543
- // instead make it silent on precisely the lone `Bash` call the batching guard also claims, which is
544
- // what an armed timer always is, for the whole ten-second window and the reissue inside it. So the
545
- // refusal is asked unconditionally and the stand-aside is handed to the row as `can_record`: what must
546
- // not happen on a call another hook may stop is the *write*, which would record a timer that never ran.
547
- // **It is a trade, and the other side is named rather than hidden**: an arm allowed inside that window
548
- // that really does run is not recorded either, so a second one before it fires goes uncaught. A missing
549
- // record loses one detection; a wrong one blocks every arm until it expires.
550
- // **Both extras replace `is_first_delivery`, and a row declares at most one.** `decide` is for a
551
- // recurring rule (joshuafolkken/kit#1570); `already_satisfied` is for a precondition the run satisfies
552
- // with an earlier act (joshuafolkken/kit#1905), and that act is the only way past it: the row refuses
553
- // every candidate call until the act is on the tail (joshuafolkken/kit#2807). Once per run, the
554
- // reissue went through with the precondition still unmet — a guard that passed precisely the run that
555
- // skipped the procedure. Repeating cannot wedge a run that obeys, because the stand-down answers first.
556
- // A row with neither takes `is_first_delivery` unchanged.
226
+ // `decide` and `already_satisfied` each replace `is_first_delivery`. A recurring row is always asked;
227
+ // the stand-aside reaches it as `can_record`, since what must not happen is recording a refused act.
228
+ // An `already_satisfied` row refuses every call until the satisfying act is on the tail.
557
229
  function delivery_decision(rule: DeliveredRule): TranscriptGuardSpec['should_block'] {
558
230
  const { decide, already_satisfied } = rule
559
231
 
@@ -584,27 +256,13 @@ function guard_of(rule: DeliveredRule): ReturnType<typeof hook_decision.create_t
584
256
 
585
257
  const GUARDS = new Map(DELIVERED_RULES.map((rule) => [rule.id, guard_of(rule)]))
586
258
 
587
- // Where one rule's once-per-run record lives, so a caller can clear it. Exposed for the suite: the
588
- // records land in the shared temp directory rather than under any directory a test owns, and a record
589
- // left behind would silence the next case exactly as it silences the next call.
259
+ // Exposed for the suite, whose records land in the shared temp directory and must be cleared.
590
260
  function delivery_path(rule_id: string, transcript_path: string): string {
591
261
  return GUARDS.get(rule_id)?.refusal_path(transcript_path) ?? ''
592
262
  }
593
263
 
594
- // **The first entry whose delivery actually fires wins — not the first whose trigger matches.** Only
595
- // one refusal can leave a `PreToolUse` hook, so a rule that matched but has already been delivered
596
- // this run falls through and a later rule may speak on the same call. **A rule added here whose
597
- // trigger another row also matches is admissible only when the overlap is safe** — the losing rule's
598
- // delivery still correct one reissue later — and the enumeration's own suite asserts, per fixture,
599
- // that every command is claimed by exactly the rows meant to overlap on it.
600
- //
601
- // **The filing trigger is shared by three rows, and the order is what makes the overlap safe**
602
- // (joshuafolkken/kit#2119). `wip-cap`, `issue-scout` and `filing-cap` all match a filing; a
603
- // scout-less, over-cap filing is delivered `wip-cap`, then `issue-scout`, then `filing-cap` across its
604
- // reissues, each still the right thing to say when it is reached. `wip-cap` is listed first because it
605
- // decides whether the backlog has room at all — the same reason it precedes `shell-body`, which claims
606
- // a filing whose body carries a backtick (joshuafolkken/kit#1198). Nothing is lost by losing a race:
607
- // the stamps are keyed per `id`, so the reissued call is delivered the next rule.
264
+ // The first entry whose delivery fires wins. An overlap is admissible only when the losing rule is
265
+ // still right one reissue later; stamps are keyed per id, so it is delivered then.
608
266
  function delivery(raw_payload: string, now_ms: number = Date.now()): string | undefined {
609
267
  for (const guard of GUARDS.values()) {
610
268
  const reason = guard.refusal(raw_payload, now_ms)
@@ -627,7 +285,6 @@ const delivered_rules = {
627
285
  FILING_CAP_REASON: filing_cap.FILING_CAP_REASON,
628
286
  GIT_FORCE_REASON: git_force.GIT_FORCE_REASON,
629
287
  ISSUE_COMMENTS_REASON: issue_comments.ISSUE_COMMENTS_REASON,
630
- ISSUE_FOLD_REASON: issue_fold_rule.ISSUE_FOLD_REASON,
631
288
  LANE_INTERACTIVE_ASK_REASON: lane_interactive_ask.LANE_INTERACTIVE_ASK_REASON,
632
289
  LANE_PARK_REASON: lane_park.LANE_PARK_REASON,
633
290
  MEASURED_RULES,
@@ -639,8 +296,6 @@ const delivered_rules = {
639
296
  SHELL_BODY_REASON,
640
297
  SWITCH_ENV_KEY,
641
298
  THIRD_PARTY_WRITE_REASON: third_party_write.THIRD_PARTY_WRITE_REASON,
642
- WIP_CAP: wip_cap.WIP_CAP,
643
- WIP_CAP_REASON: wip_cap.WIP_CAP_REASON,
644
299
  WORKTREE_MUTATION_REASON: worktree_guard.WORKTREE_MUTATION_REASON,
645
300
  delivery,
646
301
  delivery_path,