@joshuafolkken/kit 1.1471.0 → 1.1784.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 (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -1,4 +1,9 @@
1
1
  import { json_value } from '#scripts/lib/json-value'
2
+ import {
3
+ transcript_record,
4
+ type TranscriptBlock,
5
+ type TranscriptContent,
6
+ } from '#scripts/lib/transcript-record'
2
7
  import { z } from 'zod'
3
8
 
4
9
  // Reading the content blocks out of a session transcript.
@@ -18,27 +23,7 @@ import { z } from 'zod'
18
23
  const CONTENT_ITEM_SCHEMA = z.object({ text: z.string().nullish() })
19
24
  const RESULT_CONTENT_SCHEMA = z.union([z.string(), z.array(CONTENT_ITEM_SCHEMA)])
20
25
 
21
- // Every field is optional, including `type`. A required field would make one unexpected block fail
22
- // the whole array it sits in, and with it every other block on that line — an entire assistant turn
23
- // dropped from the table because one tool wrote a shape this reader had not seen. A block that
24
- // parses to nothing contributes nothing, which is the cost it should have.
25
- const BLOCK_SCHEMA = z.object({
26
- type: z.string().nullish(),
27
- text: z.string().nullish(),
28
- name: z.string().nullish(),
29
- input: z.unknown().nullish(),
30
- content: RESULT_CONTENT_SCHEMA.nullish(),
31
- })
32
-
33
- const LINE_CONTENT_SCHEMA = z.union([z.string(), z.array(BLOCK_SCHEMA)])
34
- const MESSAGE_SCHEMA = z.object({ content: LINE_CONTENT_SCHEMA.nullish() })
35
- const CONTENT_LINE_SCHEMA = z.object({ type: z.string(), message: MESSAGE_SCHEMA.nullish() })
36
-
37
- type RawBlock = z.infer<typeof BLOCK_SCHEMA>
38
-
39
- const TEXT_TYPE = 'text'
40
- const TOOL_USE_TYPE = 'tool_use'
41
- const TOOL_RESULT_TYPE = 'tool_result'
26
+ const { TEXT_TYPE, TOOL_USE_TYPE, TOOL_RESULT_TYPE } = transcript_record
42
27
  const BASH_TOOL = 'Bash'
43
28
  const COMMAND_KEY = 'command'
44
29
 
@@ -71,7 +56,7 @@ function split_bash_input(input: unknown): { command: string; rest: string } {
71
56
  }
72
57
  }
73
58
 
74
- function to_tool_use(block: RawBlock): ContentBlock {
59
+ function to_tool_use(block: TranscriptBlock): ContentBlock {
75
60
  const tool_name = block.name ?? ''
76
61
  const is_bash = tool_name === BASH_TOOL
77
62
  const { command, rest } = is_bash
@@ -83,31 +68,33 @@ function to_tool_use(block: RawBlock): ContentBlock {
83
68
 
84
69
  // A tool result is either a plain string or a list of blocks. Only the textual items are counted:
85
70
  // an image block carries no text here, and inventing a size for it would put a made-up number in a
86
- // table whose whole purpose is to be compared against another run's.
87
- function result_text(content: string | ReadonlyArray<z.infer<typeof CONTENT_ITEM_SCHEMA>>): string {
88
- if (typeof content === 'string') return content
89
-
90
- return content.map((item) => item.text ?? '').join('')
71
+ // table whose whole purpose is to be compared against another run's. A body of neither shape
72
+ // contributes nothing rather than dropping the line it sits on.
73
+ function result_text(content: unknown): string {
74
+ const parsed = RESULT_CONTENT_SCHEMA.safeParse(content)
75
+ if (!parsed.success) return ''
76
+ if (typeof parsed.data === 'string') return parsed.data
77
+
78
+ return parsed.data.map((item) => item.text ?? '').join('')
91
79
  }
92
80
 
93
81
  // Everything that is not a tool call: a result contributes its textual content, and anything else —
94
82
  // text, thinking, a block type this reader has never seen — contributes its `text`, which for
95
83
  // thinking is the empty string Claude Code writes there.
96
- function to_plain_block(block: RawBlock): ContentBlock {
84
+ function to_plain_block(block: TranscriptBlock): ContentBlock {
97
85
  const base = { type: block.type ?? '', tool_name: '', command: '' }
98
- const text =
99
- block.type === TOOL_RESULT_TYPE ? result_text(block.content ?? '') : (block.text ?? '')
86
+ const text = block.type === TOOL_RESULT_TYPE ? result_text(block.content) : (block.text ?? '')
100
87
 
101
88
  return { ...base, text }
102
89
  }
103
90
 
104
- function to_block(block: RawBlock): ContentBlock {
91
+ function to_block(block: TranscriptBlock): ContentBlock {
105
92
  return block.type === TOOL_USE_TYPE ? to_tool_use(block) : to_plain_block(block)
106
93
  }
107
94
 
108
95
  // A user turn whose content is a bare string — the prompt itself, plus whatever a `UserPromptSubmit`
109
96
  // hook injected into it. Counted as text, which is what it is.
110
- function to_blocks(content: string | ReadonlyArray<RawBlock>): Array<ContentBlock> {
97
+ function to_blocks(content: string | ReadonlyArray<TranscriptBlock>): Array<ContentBlock> {
111
98
  if (typeof content === 'string') {
112
99
  return [{ type: TEXT_TYPE, tool_name: '', command: '', text: content }]
113
100
  }
@@ -116,13 +103,11 @@ function to_blocks(content: string | ReadonlyArray<RawBlock>): Array<ContentBloc
116
103
  }
117
104
 
118
105
  // A blank line, a line that is not JSON, and a line carrying no message content are one answer:
119
- // nothing to count. With `BLOCK_SCHEMA` accepting anything object-shaped, the only line lost whole
106
+ // nothing to count. With the block schema accepting anything object-shaped, the only line lost whole
120
107
  // is one that is not JSON at all — which `cost-usage.ts` already counts as unparseable, so
121
108
  // reporting it again here would double one missing-data figure.
122
- function content_of(line: string): z.infer<typeof LINE_CONTENT_SCHEMA> | undefined {
123
- const parsed = CONTENT_LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line))
124
-
125
- return parsed.success ? (parsed.data.message?.content ?? undefined) : undefined
109
+ function content_of(line: string): TranscriptContent | undefined {
110
+ return transcript_record.parse(line)?.message?.content ?? undefined
126
111
  }
127
112
 
128
113
  function parse_line(line: string): Array<ContentBlock> {
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env tsx
2
- import { fileURLToPath } from 'node:url'
3
1
  import { agent_role_profile, type AgentProvider } from '#scripts/agent/agent-role-profile'
4
2
  import { cli_flags } from '#scripts/lib/cli-flags'
5
3
  import { codex_usage } from './codex-usage'
@@ -20,7 +18,6 @@ import { transcript_cwd } from './transcript-cwd'
20
18
  // `backlogrun` / `halfrun` / `pre-gate-cut` ask, and the `josh time` run-timing report keeps the
21
19
  // hand-off aggregates used to compare the shared context-cut threshold.
22
20
 
23
- const ARGV_OFFSET = 2
24
21
  const FAILURE_EXIT_CODE = 1
25
22
  const USAGE = 'Usage: josh cost (--cut | --over <tokens-per-request>) [--path <dir>]'
26
23
  // The read-only verdict's third answer, beside `cost_verdict`'s over/under: a session that cannot be
@@ -29,6 +26,12 @@ const UNMEASURABLE_VERDICT = 'unmeasurable'
29
26
 
30
27
  type CostVerdict = ReturnType<typeof cost_verdict.classify> | typeof UNMEASURABLE_VERDICT
31
28
 
29
+ interface SessionFigures {
30
+ verdict: CostVerdict
31
+ cost: number | undefined
32
+ threshold: number
33
+ }
34
+
32
35
  interface Options {
33
36
  over?: number
34
37
  // The target project whose transcripts to read, or absent for this process's own working
@@ -243,6 +246,28 @@ function verdict_of(measurement: OverMeasurement | undefined): CostVerdict {
243
246
  return cost_verdict.classify(measurement, CONTEXT_CUT_THRESHOLD)
244
247
  }
245
248
 
249
+ // The verdict with the figures it was decided on — the newest request's billed input and the shared
250
+ // threshold — so a report that cites the verdict quotes the same numbers rather than re-measuring.
251
+ // An unmeasurable session has no cost to quote, which is `undefined`, never `0`.
252
+ function figures_of(measurement: OverMeasurement | undefined): SessionFigures {
253
+ const verdict = verdict_of(measurement)
254
+ const is_priced = measurement !== undefined && verdict !== UNMEASURABLE_VERDICT
255
+ const cost = is_priced ? cost_verdict.per_request_cost(measurement) : undefined
256
+
257
+ return { verdict, cost, threshold: CONTEXT_CUT_THRESHOLD }
258
+ }
259
+
260
+ // The `--cut` verdict and its figures as a value, printing nothing. `run:report --handoff` quotes the
261
+ // figures in the hand-off report; `session_verdict` reads the verdict alone.
262
+ function session_figures(
263
+ cwd: string = process.cwd(),
264
+ environment: Environment = process.env,
265
+ ): SessionFigures {
266
+ const provider = provider_of(environment)
267
+
268
+ return figures_of(provider === undefined ? undefined : measure(cwd, provider, environment))
269
+ }
270
+
246
271
  // The `--cut` verdict as a value, printing nothing. `run:status` bundles
247
272
  // this beside the issue state and the carry record, so it needs the token rather than the exit code
248
273
  // `run` returns. `unmeasurable` is the read-only counterpart of `report_empty` / the empty-session
@@ -252,10 +277,7 @@ function session_verdict(
252
277
  cwd: string = process.cwd(),
253
278
  environment: Environment = process.env,
254
279
  ): CostVerdict {
255
- const provider = provider_of(environment)
256
- if (provider === undefined) return UNMEASURABLE_VERDICT
257
-
258
- return verdict_of(measure(cwd, provider, environment))
280
+ return session_figures(cwd, environment).verdict
259
281
  }
260
282
 
261
283
  function run_context(
@@ -294,20 +316,15 @@ function run(
294
316
  return run_over(target, context.over, context.provider, environment)
295
317
  }
296
318
 
297
- function main(argv: ReadonlyArray<string>): void {
298
- process.exitCode = run(argv)
299
- }
300
-
301
319
  const cost_cli = {
302
320
  UNMEASURABLE_VERDICT,
303
321
  USAGE,
304
322
  parse_options,
305
323
  to_threshold,
306
324
  run,
325
+ session_figures,
307
326
  session_verdict,
308
327
  }
309
328
 
310
- if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
311
-
312
- export type { CostVerdict, Options }
329
+ export type { CostVerdict, Options, SessionFigures }
313
330
  export { cost_cli }
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { cost_cli } from './cost-cli'
4
+
5
+ // The `josh cost` entry, kept apart from `cost-cli.ts` because `implementation-cut.ts` imports that
6
+ // one: a bundle is one file, so a main guard there would fire for every command that carries it
7
+ // (joshuafolkken/kit#4186).
8
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
9
+ const ARGV_OFFSET = 2
10
+
11
+ process.exitCode = cost_cli.run(process.argv.slice(ARGV_OFFSET))
12
+ }
@@ -505,6 +505,7 @@ const cost_transcript = {
505
505
  transcript_directory,
506
506
  transcript_directories,
507
507
  session_cwd,
508
+ lane_transcript_directories,
508
509
  unit_directory,
509
510
  list_sessions,
510
511
  list_sessions_across,
@@ -26,8 +26,9 @@ interface DelegatableStep {
26
26
  // Where the pre-implementation reading stops being cheaper in the main line.
27
27
  //
28
28
  // **A count, not a forecast.** The reads are counted as they are made rather than predicted before
29
- // the investigation starts, so nothing here rests on guessing how large it will be. Two files the run
30
- // will not edit stay in the main line, because delegating costs two extra main-line turns — one to
29
+ // the investigation starts, so nothing here rests on guessing how large it will be. It is where the
30
+ // guard refuses, not a budget: a run that knows its subject needs reading delegates before the first
31
+ // read (`run:prep`, #4345). Two stray files the run will not edit are tolerated, because delegating costs two extra main-line turns — one to
31
32
  // write the brief, one to read the result, about 18 seconds at roughly 8.8 s of model
32
33
  // wait per turn — and below the threshold that round trip costs more than carrying the text.
33
34
  const INVESTIGATION_FILE_THRESHOLD = 3
@@ -38,6 +39,15 @@ const INVESTIGATION_FILE_THRESHOLD = 3
38
39
  // target, in the main line and sends the continuing sweep to a unit.
39
40
  const INVESTIGATION_SEARCH_TURN_THRESHOLD = 3
40
41
 
42
+ // `.claude/agents/investigator.md`; a consumer receives it through the plugin as `kit:investigator`.
43
+ const INVESTIGATOR_AGENT = 'investigator'
44
+
45
+ // The limit and the remedy, worded once: the guard's refusal and `run:prep`'s entry notice both print
46
+ // them, so a run told the step up front is told the same step the refusal would name.
47
+ const INVESTIGATION_LIMIT = `${String(INVESTIGATION_FILE_THRESHOLD)} files read and not edited, or ${String(INVESTIGATION_SEARCH_TURN_THRESHOLD)} search turns, since the last delegated unit`
48
+ // Only the dispatch resets the count, so the step names no `josh delegate` call before it (#4345).
49
+ const INVESTIGATION_STEP = `Dispatch the \`${INVESTIGATOR_AGENT}\` agent (\`kit:${INVESTIGATOR_AGENT}\` in a consumer); it returns \`file:line\` citations, never the file text.`
50
+
41
51
  // The enumeration. Short on purpose: every entry had to name a verifier, and most candidates could
42
52
  // not (below).
43
53
  const DELEGATABLE_STEPS: ReadonlyArray<DelegatableStep> = [
@@ -59,12 +69,12 @@ const DELEGATABLE_STEPS: ReadonlyArray<DelegatableStep> = [
59
69
  {
60
70
  name: 'followup-filing',
61
71
  // The late-run follow-up filing chain — `issue:file` (which scouts, lints, labels and runs
62
- // epic:bundle itself) → epic --add — is a dependency chain `batch:guard`
72
+ // epic:bundle itself) → epic --add — is a dependency chain the batching guard
63
73
  // correctly keeps one call per step, and what makes it expensive is the ~340k context it runs in
64
74
  // at the tail of a run, not the step count. A fresh unit runs the same
65
75
  // chain at a small context, and the review round cap already composed the finding text, so what
66
76
  // the unit is handed is mechanical: run the commands and act on their deterministic answers. This
67
- // is not `batch:guard`'s business — delegation only moves the chain to a cheaper context.
77
+ // is not the batching guard's business — delegation only moves the chain to a cheaper context.
68
78
  does: 'run the late-run follow-up filing chain in an isolated unit — issue:file (scout, lint, labels, epic:bundle), then epic --add — given the finding text the parent already composed, and return the new Issue number and the epic:bundle answer',
69
79
  verifier:
70
80
  "the parent reads the filed Issue from GitHub with `pnpm josh issue:state <new>`, not the unit's summary; a follow-up reported filed but not created is still absent, the way `epic-child`'s reported-done-but-not-merged child is still open. The finding text came from the parent and `issue:file`'s steps are deterministic, so the unit's work is the mechanical execution `issue:state` confirms",
@@ -181,7 +191,10 @@ function reason_for(name: string): string {
181
191
  const delegation_policy = {
182
192
  DELEGATE_VERDICT,
183
193
  INVESTIGATION_FILE_THRESHOLD,
194
+ INVESTIGATION_LIMIT,
184
195
  INVESTIGATION_SEARCH_TURN_THRESHOLD,
196
+ INVESTIGATION_STEP,
197
+ INVESTIGATOR_AGENT,
185
198
  KEEP_VERDICT,
186
199
  DELEGATABLE_STEPS,
187
200
  REJECTED_STEPS,
@@ -1,7 +1,4 @@
1
- #!/usr/bin/env tsx
2
1
  import { statSync } from 'node:fs'
3
- import { text } from 'node:stream/consumers'
4
- import { fileURLToPath } from 'node:url'
5
2
  import { hook_decision } from '#scripts/josh/hook-decision'
6
3
  import { lane_guard_policy, type LaneGuardMode } from '#scripts/lane/lane-guard-policy'
7
4
  import { json_value } from '#scripts/lib/json-value'
@@ -176,8 +173,8 @@ function is_candidate(call: GuardedCall): boolean {
176
173
  }
177
174
 
178
175
  // A refusable call is refused only where the mode is `refuse`. A lane child is `notice`, so it reaches
179
- // here and is withheld the refusal — the notice branch carries the guidance instead, because a refusal
180
- // ends a headless child's turn.
176
+ // here and is withheld the refusal — the notice branch carries the guidance instead, for the reason its
177
+ // `because` in `lane-guard-policy.ts` records.
181
178
  function should_block_here(tail: string, call: GuardedCall, refused_at_ms: number): boolean {
182
179
  if (duplicate_mode() !== 'refuse') return false
183
180
 
@@ -217,11 +214,6 @@ const duplicate_reads = {
217
214
  NOTICE,
218
215
  }
219
216
 
220
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
221
- if (process.stdin.isTTY) hook_decision.report_no_payload('duplicate-read:guard')
222
- else hook_decision.write_outcome(await text(process.stdin), duplicate_read_outcome)
223
- }
224
-
225
217
  export {
226
218
  deny_envelope,
227
219
  DISABLED_VALUES,
@@ -1,8 +1,6 @@
1
- #!/usr/bin/env tsx
2
- import { text } from 'node:stream/consumers'
3
- import { fileURLToPath } from 'node:url'
1
+ import { agent_session_role } from '#scripts/agent/agent-session-role'
4
2
  import { hook_decision, type GuardRun } from '#scripts/josh/hook-decision'
5
- import { lane_guard_policy, type LaneGuardMode } from '#scripts/lane/lane-guard-policy'
3
+ import { lane_guard_policy } from '#scripts/lane/lane-guard-policy'
6
4
  import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
7
5
  import { investigation_reads } from './investigation-reads'
8
6
 
@@ -21,107 +19,51 @@ import { investigation_reads } from './investigation-reads'
21
19
  // file — debugging the guard itself, or a session whose reading really is all edit targets.
22
20
  const SWITCH_ENV_KEY = 'JOSH_INVESTIGATION_GUARD'
23
21
 
24
- // This guard's refusal record, and the notice's own record — distinct so a lane-child notice never
25
- // spends the refusal's stamp, the same split the batching guard keeps.
26
22
  const STAMP_PREFIX = 'josh-investigation-guard-'
27
- const NOTICE_STAMP_PREFIX = 'josh-investigation-guard-notice-'
28
23
 
29
- // **How the guard behaves for the session in hand, decided from the one-place enumeration**.
30
- // Outside a lane child the mode is `refuse` and the
31
- // guard refuses; in a dispatched lane child it is `notice`, because a lane child does read unedited
32
- // files and can dispatch sub-agents, so the reading is there to send out. The enumeration reads `JOSH_LANE_CHILD` against this checkout's own
33
- // issue only for a guard whose mode it would change, so a person working in a lane sees the guard
34
- // unchanged. It wraps `investigation_reads.should_block` here rather than inside it so the pure counting
35
- // rule stays free of process state and its own suite keeps testing it directly.
36
- function investigation_mode(): LaneGuardMode {
37
- return lane_guard_policy.mode_here('investigation')
38
- }
39
-
40
- // A refusable call is refused only where the mode is `refuse` — the main line. A lane child is
41
- // `notice`, so it reaches the notice branch and is withheld the refusal that would end its headless
42
- // turn; an `off` some future enumeration sets stays silent here too.
24
+ // **How the guard behaves for the session in hand, decided from the one-place enumeration**. It is
25
+ // `refuse` in a dispatched lane child too (joshuafolkken/kit#3927): a hook denial returns to the model
26
+ // as guidance, and the notice it replaced was measured not to move the reading. It wraps
27
+ // `investigation_reads.should_block` here rather than inside it so the pure counting rule stays free of
28
+ // process state and its own suite keeps testing it directly. A reviewer session stands down: reading
29
+ // the diff's files is its whole task, and it carries the lane's marker, so it would otherwise be refused
30
+ // like the child it reviews — the stand-down `implementation-cut.ts` takes for the same session.
43
31
  function should_block(
44
32
  tail: string,
45
33
  call: GuardedCall,
46
34
  refused_at_ms: number,
47
35
  run?: GuardRun,
48
36
  ): boolean {
49
- if (investigation_mode() !== 'refuse') return false
37
+ if (
38
+ agent_session_role.is_reviewer() ||
39
+ lane_guard_policy.mode_here('investigation') !== 'refuse'
40
+ ) {
41
+ return false
42
+ }
50
43
 
51
44
  return investigation_reads.should_block(tail, call, refused_at_ms, run)
52
45
  }
53
46
 
54
- // The lane-child notice: the same threshold, delivered without a `permissionDecision`. It
55
- // reads the notify stamp's own record, so a notice never spends the refusal's stamp and re-arms on the
56
- // next accumulation exactly as the refusal does.
57
- function should_notify(
58
- tail: string,
59
- call: GuardedCall,
60
- notified_at_ms: number,
61
- run?: GuardRun,
62
- ): boolean {
63
- if (investigation_mode() !== 'notice') return false
64
-
65
- return investigation_reads.should_block(tail, call, notified_at_ms, run)
66
- }
67
-
68
- // **The lane-child counterpart of REASON, delivered as a notice rather than a refusal**.
69
- // A dispatched lane child ends its turn on a denial, so
70
- // the same guidance is carried without a `permissionDecision`: the read proceeds and the child is nudged
71
- // to delegate rather than killed. It carries no ⛔, so a person watching reads it as advice.
72
- const NOTICE = `💡 investigation: files read and not edited, or search turns, since the last delegated unit reached the threshold; the read proceeds. Run \`pnpm josh delegate investigation\`, then dispatch the \`${investigation_reads.INVESTIGATOR_AGENT}\` agent (\`kit:${investigation_reads.INVESTIGATOR_AGENT}\` in a consumer); it returns \`file:line\` citations, never the file text. Keep main-line reads to files you will edit.`
73
-
74
- // The notice as it reaches the model: the base guidance with the concrete unedited reads named, so a
75
- // lane child is shown *which* reads to send to a unit rather than only told to delegate. An empty
76
- // set names nothing and the notice falls back to its guidance alone. The call is part of the notify
77
- // contract but this guard's wording depends on the tail alone.
78
- function notice_text(_call: GuardedCall, tail: string): string {
79
- const pending = investigation_reads
80
- .tally_of(tail)
81
- .pending.map((absolute) => investigation_reads.repository_relative(absolute))
82
-
83
- return pending.length === 0
84
- ? NOTICE
85
- : `${NOTICE} Read and not edited so far: ${pending.join(' ')}.`
86
- }
87
-
88
47
  const GUARD = hook_decision.create_transcript_guard({
89
48
  prefix: STAMP_PREFIX,
90
49
  switch_key: SWITCH_ENV_KEY,
91
50
  is_candidate: investigation_reads.is_refusable_call,
92
51
  should_block,
93
52
  reason: investigation_reads.REASON,
94
- // The lane-child notice fires where the refusal is withheld, on a record of its own so it
95
- // never spends the refusal's stamp.
96
- notify: {
97
- prefix: NOTICE_STAMP_PREFIX,
98
- should_notify,
99
- text: notice_text,
100
- },
101
53
  })
102
54
 
103
55
  const investigation_refusal = GUARD.refusal
104
56
  const investigation_outcome = GUARD.outcome
105
57
  const { is_enabled, refusal_path } = GUARD
106
- // The notice's stamp path, exposed the way `refusal_path` is so a test can clean it apart from the
107
- // refusal's record.
108
- const investigation_notice_path = hook_decision.create_refusal_stamp(NOTICE_STAMP_PREFIX).path
109
58
  const { deny_envelope, load_environment_file, DISABLED_VALUES } = hook_decision
110
59
 
111
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
112
- if (process.stdin.isTTY) hook_decision.report_no_payload('investigation:guard')
113
- else hook_decision.write_outcome(await text(process.stdin), investigation_outcome)
114
- }
115
-
116
60
  export {
117
61
  deny_envelope,
118
- investigation_notice_path,
119
62
  investigation_outcome,
120
63
  investigation_refusal,
121
64
  is_enabled,
122
65
  load_environment_file,
123
66
  refusal_path,
124
67
  DISABLED_VALUES,
125
- NOTICE,
126
68
  SWITCH_ENV_KEY,
127
69
  }
@@ -38,11 +38,10 @@ const SEARCH_LABELS: ReadonlySet<string> = new Set(
38
38
  SEARCH_COMMANDS.map((command) => time_shell.bash_label(command)),
39
39
  )
40
40
 
41
- // `.claude/agents/investigator.md`; a consumer receives it through the plugin as `kit:investigator`.
42
- const INVESTIGATOR_AGENT = 'investigator'
41
+ const { INVESTIGATOR_AGENT } = delegation_policy
43
42
 
44
43
  // The deny reason is the only text that reaches the model, so it names the count, command and return shape.
45
- const REASON = `⛔ investigation: ${String(delegation_policy.INVESTIGATION_FILE_THRESHOLD)} files read and not edited, or ${String(delegation_policy.INVESTIGATION_SEARCH_TURN_THRESHOLD)} search turns, since the last delegated unit. Run \`pnpm josh delegate investigation\`, then dispatch the \`${INVESTIGATOR_AGENT}\` agent (\`kit:${INVESTIGATOR_AGENT}\` in a consumer); it returns \`file:line\` citations, never the file text. Keep main-line reads to files you will edit; every read-only search turn counts. \`.claude/skills/workflow-commands/delegation.md\``
44
+ const REASON = `⛔ investigation: ${delegation_policy.INVESTIGATION_LIMIT}. ${delegation_policy.INVESTIGATION_STEP} Keep main-line reads to files you will edit; every read-only search turn counts. \`.claude/skills/workflow-commands/delegation.md\``
46
45
 
47
46
  interface ReadTally {
48
47
  // The files read and not since edited, resolved.
@@ -61,7 +60,7 @@ interface ReadTally {
61
60
  }
62
61
 
63
62
  // The run's own instructions are not the Issue's subject and cannot be delegated, so they never count.
64
- // Matched relative to the repository root, so `scripts/eval/prompts/x.ts` stays subject code.
63
+ // Matched relative to the repository root, so `tools/eval/prompts/x.ts` stays subject code.
65
64
  const INSTRUCTION_PATHS: ReadonlyArray<string> = ['prompts', '.claude/skills']
66
65
  const INSTRUCTION_FILES: ReadonlySet<string> = new Set(['CLAUDE.md', 'AGENTS.md', 'GEMINI.md'])
67
66
  const REPOSITORY_ROOT = process.cwd()
@@ -362,7 +361,6 @@ const investigation_reads = {
362
361
  is_session_artifact,
363
362
  is_subject_file,
364
363
  projected_count,
365
- repository_relative,
366
364
  resolved,
367
365
  should_block,
368
366
  tally_of,
@@ -0,0 +1,194 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import {
4
+ DEFAULT_RELEASE_AGE_MINUTES,
5
+ release_window,
6
+ type ReleaseWindow,
7
+ } from '#scripts/version/release-window'
8
+
9
+ // Dependabot's `cooldown` is the workspace's `minimumReleaseAge` restated in days, so a freshly
10
+ // published action or package waits out the same window pnpm and Safe Chain enforce (kit #4023).
11
+ // The edit is line-based and touches only each entry's `cooldown` block: a consumer's own keys and
12
+ // the file's comments survive, which a YAML round trip would discard.
13
+ const DEPENDABOT_FILE = path.join('.github', 'dependabot.yml')
14
+ const MINUTES_PER_DAY = 1440
15
+ // Dependabot accepts `default-days` from 1 to 90.
16
+ const MIN_DAYS = 1
17
+ const MAX_DAYS = 90
18
+ // pnpm's exclusions name npm packages, so only the npm entry receives them.
19
+ const NPM_ECOSYSTEM = 'npm'
20
+ const UPDATES_PATTERN = /^updates:\s*(?:#.*)?$/u
21
+ const ECOSYSTEM_PATTERN = /^\s*(?:-\s+)?package-ecosystem:\s*['"]?([\w-]+)/u
22
+ const TOP_LEVEL_KEY_PATTERN = /^[^\s#-]/u
23
+ const COOLDOWN_KEY = 'cooldown:'
24
+
25
+ interface UpdateEntry {
26
+ start: number
27
+ end: number
28
+ key_indent: string
29
+ }
30
+
31
+ function cooldown_days(minutes: number | undefined): number {
32
+ const days = Math.ceil((minutes ?? DEFAULT_RELEASE_AGE_MINUTES) / MINUTES_PER_DAY)
33
+
34
+ return Math.min(MAX_DAYS, Math.max(MIN_DAYS, days))
35
+ }
36
+
37
+ function quote(value: string): string {
38
+ return `'${value.replaceAll("'", "''")}'`
39
+ }
40
+
41
+ function cooldown_lines(ecosystem: string, window: ReleaseWindow, indent: string): Array<string> {
42
+ const lines = ['cooldown:', ` default-days: ${String(cooldown_days(window.minutes))}`]
43
+
44
+ if (ecosystem === NPM_ECOSYSTEM && window.exclusions.length > 0) {
45
+ lines.push(' exclude:', ...window.exclusions.map((name) => ` - ${quote(name)}`))
46
+ }
47
+
48
+ return lines.map((line) => `${indent}${line}`)
49
+ }
50
+
51
+ function indent_width(line: string): number {
52
+ return line.length - line.trimStart().length
53
+ }
54
+
55
+ function is_blank(line: string | undefined): boolean {
56
+ return line?.trim() === ''
57
+ }
58
+
59
+ function trim_trailing_blanks(lines: ReadonlyArray<string>): Array<string> {
60
+ const trimmed = [...lines]
61
+ while (trimmed.length > 1 && is_blank(trimmed.at(-1))) trimmed.pop()
62
+
63
+ return trimmed
64
+ }
65
+
66
+ function is_comment(line: string | undefined): boolean {
67
+ return line?.trimStart().startsWith('#') === true
68
+ }
69
+
70
+ // A blank line, or a comment left of `width`: it may sit inside a block or head the next one.
71
+ function is_detached(line: string | undefined, width: number): boolean {
72
+ return is_blank(line) || (is_comment(line) && indent_width(line ?? '') < width)
73
+ }
74
+
75
+ // The first key line at or after `from` that sits left of `width`, or `limit`.
76
+ function block_stop(
77
+ lines: ReadonlyArray<string>,
78
+ from: number,
79
+ width: number,
80
+ limit: number,
81
+ ): number {
82
+ const relative = lines
83
+ .slice(from, limit)
84
+ .findIndex((line) => !is_blank(line) && !is_comment(line) && indent_width(line) < width)
85
+
86
+ return relative === -1 ? limit : from + relative
87
+ }
88
+
89
+ // The block runs to the next key line left of `width`. A comment left of `width` in the middle stays
90
+ // inside, while the run of such comments right before that key belongs to what follows.
91
+ function block_end(
92
+ lines: ReadonlyArray<string>,
93
+ from: number,
94
+ width: number,
95
+ limit: number,
96
+ ): number {
97
+ const stop = block_stop(lines, from, width, limit)
98
+ let end = stop
99
+
100
+ for (let index = stop - 1; index >= from && is_detached(lines[index], width); index -= 1) {
101
+ if (!is_blank(lines[index])) end = index
102
+ }
103
+
104
+ return end
105
+ }
106
+
107
+ // The next top-level key. A list written flush with `updates:` and a comment at column 0 both still
108
+ // belong to it, so neither ends the list.
109
+ function updates_end(lines: ReadonlyArray<string>, updates: number): number {
110
+ const relative = lines.slice(updates + 1).findIndex((line) => TOP_LEVEL_KEY_PATTERN.test(line))
111
+
112
+ return relative === -1 ? lines.length : updates + 1 + relative
113
+ }
114
+
115
+ function find_entries(lines: ReadonlyArray<string>, updates: number): Array<UpdateEntry> {
116
+ const limit = updates_end(lines, updates)
117
+ const starts = lines
118
+ .map((line, index) => ({ index, item: /^(\s*-\s+)\S/u.exec(line)?.[1] }))
119
+ .filter(({ index, item }) => index > updates && index < limit && item !== undefined)
120
+ const item_width = Math.min(...starts.map(({ item }) => item?.indexOf('-') ?? 0))
121
+
122
+ return starts
123
+ .filter(({ item }) => item?.indexOf('-') === item_width)
124
+ .map(({ index, item = '' }) => ({
125
+ start: index,
126
+ end: block_end(lines, index + 1, item.length, limit),
127
+ key_indent: ' '.repeat(item.length),
128
+ }))
129
+ }
130
+
131
+ // The entry's own `cooldown:` key, either on a key line or on the item line itself (`- cooldown:`).
132
+ function is_cooldown_key(line: string, index: number, key_indent: string): boolean {
133
+ const is_key_line = index === 0 || line.startsWith(key_indent)
134
+
135
+ return is_key_line && line.slice(key_indent.length).startsWith(COOLDOWN_KEY)
136
+ }
137
+
138
+ // An entry that opened with `- cooldown:` hands its item marker to the next key once the block goes.
139
+ function promote_first_key(rest: ReadonlyArray<string>, marker: string): Array<string> {
140
+ const first = rest.findIndex((line) => !is_blank(line) && !line.trimStart().startsWith('#'))
141
+
142
+ return rest.map((line, index) =>
143
+ index === first ? `${marker}${line.slice(marker.length)}` : line,
144
+ )
145
+ }
146
+
147
+ function without_cooldown(entry: ReadonlyArray<string>, key_indent: string): Array<string> {
148
+ const start = entry.findIndex((line, index) => is_cooldown_key(line, index, key_indent))
149
+ if (start === -1) return [...entry]
150
+ const rest = entry.slice(block_end(entry, start + 1, key_indent.length + 1, entry.length))
151
+ if (start > 0) return [...entry.slice(0, start), ...rest]
152
+
153
+ return promote_first_key(rest, (entry.at(0) ?? '').slice(0, key_indent.length))
154
+ }
155
+
156
+ function rewrite_entry(
157
+ entry: ReadonlyArray<string>,
158
+ key_indent: string,
159
+ window: ReleaseWindow,
160
+ ): Array<string> {
161
+ const ecosystem = entry.map((line) => ECOSYSTEM_PATTERN.exec(line)?.[1]).find(Boolean)
162
+ if (ecosystem === undefined) return [...entry]
163
+ const body = trim_trailing_blanks(without_cooldown(entry, key_indent))
164
+ const trailing = entry.slice(trim_trailing_blanks(entry).length)
165
+
166
+ return [...body, ...cooldown_lines(ecosystem, window, key_indent), ...trailing]
167
+ }
168
+
169
+ function merge_cooldown(existing: string, window: ReleaseWindow): string {
170
+ const lines = existing.split('\n')
171
+ const updates = lines.findIndex((line) => UPDATES_PATTERN.test(line))
172
+ if (updates === -1) return existing
173
+
174
+ for (const { start, end, key_indent } of find_entries(lines, updates).toReversed()) {
175
+ lines.splice(start, end - start, ...rewrite_entry(lines.slice(start, end), key_indent, window))
176
+ }
177
+
178
+ return lines.join('\n')
179
+ }
180
+
181
+ function sync_dependabot_cooldown(root: string): boolean {
182
+ const config_path = path.join(root, DEPENDABOT_FILE)
183
+ if (!existsSync(config_path)) return false
184
+ const existing = readFileSync(config_path, 'utf8')
185
+ const merged = merge_cooldown(existing, release_window.read_release_window(root))
186
+ if (merged === existing) return false
187
+ writeFileSync(config_path, merged)
188
+
189
+ return true
190
+ }
191
+
192
+ const dependabot_cooldown = { cooldown_days, merge_cooldown, sync_dependabot_cooldown }
193
+
194
+ export { dependabot_cooldown }