@joshuafolkken/kit 1.1514.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 (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -3,6 +3,7 @@ import { doctor_consumer } from '#scripts/doctor/doctor-consumer'
3
3
  import { json_value } from '#scripts/lib/json-value'
4
4
  import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
5
5
  import { bash_triggers } from './bash-triggers'
6
+ import { git_argv } from './git-argv'
6
7
  import { shell_segments } from './shell-segments'
7
8
 
8
9
  // The trigger and the delivered text behind the `protected-file` row of `delivered-rules.ts`:
@@ -31,25 +32,44 @@ const SETTINGS_FILE = path.join('.claude', 'settings.json')
31
32
  const WHITESPACE = /\s+/u
32
33
  const TOKEN_QUOTES = /["']/gu
33
34
  const INPUT_REDIRECT = '<'
35
+ // Programs that print a named file's bytes, or run them. `cp` and `mv` are deliberately absent: they
36
+ // write rather than print, and `cp .env.example .env` is how a checkout's `.env` is made.
34
37
  const SHELL_READERS: ReadonlySet<string> = new Set([
35
38
  '.',
36
39
  'awk',
40
+ 'base64',
37
41
  'bat',
38
42
  'cat',
43
+ 'cmp',
44
+ 'column',
45
+ 'comm',
39
46
  'cut',
47
+ 'diff',
48
+ 'fold',
40
49
  'grep',
41
50
  'head',
51
+ 'hexdump',
52
+ 'jq',
42
53
  'less',
43
54
  'more',
44
55
  'nl',
45
56
  'od',
57
+ 'paste',
58
+ 'perl',
59
+ 'python',
60
+ 'python3',
61
+ 'rev',
46
62
  'rg',
63
+ 'ruby',
47
64
  'sed',
48
65
  'sort',
49
66
  'source',
50
67
  'strings',
68
+ 'tac',
51
69
  'tail',
70
+ 'uniq',
52
71
  'xxd',
72
+ 'yq',
53
73
  ])
54
74
 
55
75
  function file_path_of(call: GuardedCall): string {
@@ -80,15 +100,15 @@ function is_environment_read_segment(segment: string): boolean {
80
100
  const is_redirected = words.some(
81
101
  (word, index) => word === INPUT_REDIRECT && is_environment_path(words[index + 1] ?? ''),
82
102
  )
83
- const [command = '', ...rest] = words
103
+ const call = git_argv.program_of(segment)
84
104
 
85
- return (
86
- is_redirected || (SHELL_READERS.has(command) && rest.some((word) => is_environment_path(word)))
87
- )
105
+ if (is_redirected || call === undefined) return is_redirected
106
+
107
+ return SHELL_READERS.has(call.name) && call.args.some((word) => is_environment_path(word))
88
108
  }
89
109
 
90
110
  function is_environment_shell_read(command: string): boolean {
91
- return shell_segments.segments_of(command).some((segment) => is_environment_read_segment(segment))
111
+ return shell_segments.commands_of(command).some((segment) => is_environment_read_segment(segment))
92
112
  }
93
113
 
94
114
  function is_environment_read(call: GuardedCall): boolean {
@@ -130,6 +150,13 @@ const ROW = {
130
150
  decide: (): boolean => true,
131
151
  // The opening the reason carried before it was cut to the action and the next command.
132
152
  former_reasons: ['⛔ protected file: `.env` holds the Telegram bot token'],
153
+ about: {
154
+ title: 'Protected file',
155
+ topic: '`operating-rules.md`',
156
+ fires:
157
+ 'a `Read` of `.env`, or an `Edit` / `Write` of `.claude/settings.json` outside kit. Every occurrence',
158
+ quiet: "kit itself, or the user's `~/.claude/settings.json`",
159
+ },
133
160
  }
134
161
 
135
162
  const protected_files = { ROW, is_protected_file_call }
@@ -44,6 +44,12 @@ const ROW = {
44
44
  is_trigger: bash_triggers.on_bash_command(posts_at_path_literally),
45
45
  reason: RAW_FIELD_BODY_REASON,
46
46
  decide: (): boolean => true,
47
+ about: {
48
+ title: 'Posting `@path` literally',
49
+ topic: '`shell-body.md`',
50
+ fires: 'a raw field (`-f` / `--raw-field`) passing `body=@<path>`. Every occurrence',
51
+ quiet: '`-F` / `--field body=@`, a body without `@`, or `pnpm josh issue:comment`',
52
+ },
47
53
  }
48
54
 
49
55
  const raw_field_body = { RAW_FIELD_BODY_REASON, ROW, posts_at_path_literally }
@@ -178,6 +178,14 @@ const ROW = {
178
178
  reason: RULE_BODY_REASON,
179
179
  already_satisfied: answered_placement,
180
180
  keeps: bash_triggers.on_bash_command(runs_placement_oracle),
181
+ about: {
182
+ title: 'Question 0 and the ordering question before writing a rule into prose',
183
+ topic: '`residency.md`',
184
+ fires:
185
+ 'an `Edit` / `Write` to `CLAUDE.md` / `prompts/**/*.md` / `.claude/skills/**/*.md` appending at least the threshold. Refused until both `pnpm josh oracle:list` and `pnpm josh run:step` ran',
186
+ quiet:
187
+ 'not a rule document, an append under the threshold (typo, link swap, deletion), or both commands ran',
188
+ },
181
189
  }
182
190
 
183
191
  const rule_body_guard = {
@@ -2,53 +2,34 @@
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { delivered_rules } from './delivered-rules'
4
4
  import { guard_remedy } from './guard-remedy'
5
- import { rule_registry, type RegisteredRule } from './rule-registry'
5
+ import { stop_rule_rows, type StopRule } from './stop-rule-rows'
6
6
 
7
7
  // `josh rule:list` — the list of trigger-delivered rules, rendered from the guard rows themselves.
8
8
  // One item per `MEASURED_RULES` row in delivery order, then the `Stop`
9
9
  // hook's rows; each carries its single source, the call it fires on and the turn it stays silent on.
10
- // The prose is `rule-registry.ts`; the order and the set are `delivered-rules.ts`, so a row added
11
- // there is listed without a document edit — and a row with no registry entry is listed as missing.
10
+ // The prose is each row's own `about`, so a row added there is listed without a document edit.
12
11
 
13
12
  const HEADER =
14
13
  '# Trigger-delivered rules — rendered by `pnpm josh rule:list` from `scripts/rules/delivered-rules.ts`'
15
- const MISSING = '(no entry in `scripts/rules/rule-registry.ts`)'
16
14
  const MISSING_WHY = '(no `why` in `scripts/rules/guard-remedy.ts`)'
17
15
 
18
- function item(id: string, rule: RegisteredRule | undefined): string {
19
- if (rule === undefined) return `- \`${id}\` ${MISSING}`
20
-
16
+ function item({ id, about }: StopRule): string {
21
17
  return [
22
- `- **${rule.title}** (\`${id}\`, ${rule.topic})`,
23
- ` - fires: \`${rule.entry}\` — ${rule.fires}`,
24
- ` - silent: ${rule.quiet}`,
18
+ `- **${about.title}** (\`${id}\`, ${about.topic})`,
19
+ ` - fires: \`${about.entry ?? delivered_rules.PRETOOL_GUARD}\` — ${about.fires}`,
20
+ ` - silent: ${about.quiet}`,
25
21
  ` - not automated: ${guard_remedy.why_of(id) ?? MISSING_WHY}`,
26
22
  ].join('\n')
27
23
  }
28
24
 
29
- function row_ids(): ReadonlyArray<string> {
30
- return delivered_rules.MEASURED_RULES.map((rule) => rule.id)
31
- }
32
-
33
25
  function render(): string {
34
- const rows = row_ids().map((id) => item(id, rule_registry.entry_for(id)))
35
- const stops = rule_registry.STOP_ROWS.map((rule) => item(rule.id, rule))
36
-
37
- return [HEADER, '', ...rows, ...stops].join('\n')
38
- }
39
-
40
- // Registry entries no guard row reaches — a renamed or removed row left its prose behind.
41
- function orphans(): ReadonlyArray<string> {
42
- const reached = new Set(row_ids().map((id) => rule_registry.registry_id(id)))
43
- const stop_ids = new Set(rule_registry.STOP_ROWS.map((rule) => rule.id))
26
+ const rows = [...delivered_rules.MEASURED_RULES, ...stop_rule_rows.ROWS].map((rule) => item(rule))
44
27
 
45
- return rule_registry.REGISTERED_RULES.map((rule) => rule.id).filter(
46
- (id) => !reached.has(id) && !stop_ids.has(id),
47
- )
28
+ return [HEADER, '', ...rows].join('\n')
48
29
  }
49
30
 
50
31
  if (process.argv[1] === fileURLToPath(import.meta.url)) process.stdout.write(`${render()}\n`)
51
32
 
52
- const rule_list = { MISSING, MISSING_WHY, orphans, render }
33
+ const rule_list = { MISSING_WHY, render }
53
34
 
54
35
  export { rule_list }
@@ -1,7 +1,9 @@
1
1
  import { spawn } from 'node:child_process'
2
- import { mkdirSync, renameSync, statSync, writeFileSync } from 'node:fs'
2
+ import { statSync } from 'node:fs'
3
3
  import path from 'node:path'
4
+ import { atomic_write } from '#scripts/lib/atomic-write'
4
5
  import { file_reader } from '#scripts/lib/read-file'
6
+ import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
5
7
 
6
8
  // The `rule:value` reading at the `backlogrun` loop head, without the loop waiting on it.
7
9
  // Measuring re-reads every transcript and takes minutes, and `backlog:offer`
@@ -16,12 +18,10 @@ const CACHE_DIRECTORY = ['node_modules', '.cache', 'josh']
16
18
  const CACHE_FILE = 'rule-value.txt'
17
19
  // Touched when a refresh starts, so the loop head starts at most one per interval however often it runs.
18
20
  const STAMP_FILE = 'rule-value.stamp'
19
- const MS_PER_MINUTE = 60_000
20
21
  const REFRESH_MINUTES = 15
21
22
  const REFRESH_MS = REFRESH_MINUTES * MS_PER_MINUTE
22
23
  const REFRESH_ARGV = ['josh', 'rule:value', '--refresh']
23
24
  const PNPM = 'pnpm'
24
- const TEMPORARY_SUFFIX = '.tmp'
25
25
 
26
26
  interface CachePorts {
27
27
  now: () => number
@@ -45,12 +45,7 @@ function is_refresh_due(cwd: string, now_ms: number): boolean {
45
45
  }
46
46
 
47
47
  function write_cache_file(cwd: string, file: string, text: string): void {
48
- const target = cache_path(cwd, file)
49
- const temporary = `${target}${TEMPORARY_SUFFIX}`
50
-
51
- mkdirSync(path.dirname(target), { recursive: true })
52
- writeFileSync(temporary, text)
53
- renameSync(temporary, target)
48
+ atomic_write.replace_file(cache_path(cwd, file), text)
54
49
  }
55
50
 
56
51
  function ignore_spawn_error(): void {
@@ -26,46 +26,62 @@ const UNMEASURED = 'unmeasured'
26
26
  // A measurable rule no run reached: the denominator is zero, so no rate is taken over it.
27
27
  const UNREACHED = 'unreached'
28
28
 
29
- interface OwnedText {
30
- owner: string
31
- text: string
32
- }
33
-
34
- function owned_text(file: SessionFile): OwnedText | undefined {
35
- const text = cost_transcript.read_optional(file)
36
-
37
- if (text === undefined) return undefined
38
-
39
- return { owner: cost_transcript.owning_session_id(file), text }
40
- }
41
-
42
29
  // Every transcript grouped by the run it belongs to: a session's own file and the units it delegated
43
30
  // share one `owning_session_id`, so a lane child is counted with its parent rather than as a run of
44
- // its own — the unit `rule_value.measure` reads.
45
- function group_by_run(files: ReadonlyArray<SessionFile>): Map<string, Array<string>> {
46
- const runs = new Map<string, Array<string>>()
31
+ // its own — the unit `rule_value.measure` reads. **Paths only**: no text is read here, so the
32
+ // grouping never holds the corpus.
33
+ function group_by_run(files: ReadonlyArray<SessionFile>): Map<string, Array<SessionFile>> {
34
+ const runs = new Map<string, Array<SessionFile>>()
47
35
 
48
36
  for (const file of files) {
49
- const owned = owned_text(file)
50
-
51
- if (owned === undefined) continue
52
-
53
- const texts = runs.get(owned.owner) ?? []
37
+ const owner = cost_transcript.owning_session_id(file)
38
+ const owned = runs.get(owner) ?? []
54
39
 
55
- texts.push(owned.text)
56
- runs.set(owned.owner, texts)
40
+ owned.push(file)
41
+ runs.set(owner, owned)
57
42
  }
58
43
 
59
44
  return runs
60
45
  }
61
46
 
47
+ function readable_texts(files: ReadonlyArray<SessionFile>): Array<string> {
48
+ return files
49
+ .map((file) => cost_transcript.read_optional(file))
50
+ .filter((text): text is string => text !== undefined)
51
+ }
52
+
53
+ // **One run read at a time.** Each run's text is read only when `measure` asks for it and released
54
+ // before the next is read, so the peak is the largest run rather than the whole corpus. A run whose
55
+ // every file is unreadable yields nothing, as it was never a measurement target.
56
+ function* runs_of(groups: Iterable<ReadonlyArray<SessionFile>>): Generator<Array<string>> {
57
+ for (const files of groups) {
58
+ const texts = readable_texts(files)
59
+
60
+ if (texts.length > 0) yield texts
61
+ }
62
+ }
63
+
62
64
  // Every run reachable from the working tree — the session's own transcript directory and any lane
63
- // slugs beneath its main checkout — grouped into the shape `rule_value.measure` reads.
64
- function gather_runs(cwd: string = process.cwd()): Array<Array<string>> {
65
+ // slugs beneath its main checkout — in the shape `rule_value.measure` reads.
66
+ function gather_runs(cwd: string = process.cwd()): Generator<Array<string>> {
65
67
  const directories = cost_transcript.transcript_directories(cwd)
66
68
  const files = cost_transcript.list_sessions_across(directories)
67
69
 
68
- return [...group_by_run(files).values()]
70
+ return runs_of(group_by_run(files).values())
71
+ }
72
+
73
+ interface Tally {
74
+ runs: number
75
+ }
76
+
77
+ function* counted(
78
+ runs: Iterable<ReadonlyArray<string>>,
79
+ tally: Tally,
80
+ ): Generator<ReadonlyArray<string>> {
81
+ for (const texts of runs) {
82
+ tally.runs += 1
83
+ yield texts
84
+ }
69
85
  }
70
86
 
71
87
  // The id column, wide enough for the longest rule id, so the reading lines up whatever the registry
@@ -94,13 +110,15 @@ function row(reading: RuleReading): string {
94
110
 
95
111
  // The reading as text, or `NO_TARGETS` when nothing measurable was found — never an empty output that
96
112
  // would read as a broken command.
97
- function render(runs: ReadonlyArray<ReadonlyArray<string>>): string {
98
- if (runs.length === 0) return NO_TARGETS
113
+ // The runs are counted as `measure` consumes them, since a lazy source cannot be asked its length
114
+ // up front.
115
+ function render(runs: Iterable<ReadonlyArray<string>>): string {
116
+ const tally: Tally = { runs: 0 }
117
+ const readings = rule_value.measure(counted(runs, tally))
118
+
119
+ if (tally.runs === 0) return NO_TARGETS
99
120
 
100
- return rule_value
101
- .measure(runs)
102
- .map((reading) => row(reading))
103
- .join('\n')
121
+ return readings.map((reading) => row(reading)).join('\n')
104
122
  }
105
123
 
106
124
  // `--refresh` is the detached measurement the `backlogrun` loop head starts: the reading goes to the
@@ -123,6 +141,7 @@ const rule_value_cli = {
123
141
  render,
124
142
  row,
125
143
  run_rule_value,
144
+ runs_of,
126
145
  NO_TARGETS,
127
146
  UNMEASURED,
128
147
  UNREACHED,
@@ -40,7 +40,7 @@ const PERCENT = 100
40
40
  // **A refusal is an errored result, which is what separates it from a read of the file it is written
41
41
  // in.** Every signature exists verbatim in the module its rule is written in — the six delivered
42
42
  // rules in `scripts/rules/delivered-rules.ts`, the batching row's in
43
- // `scripts/time/time-batch-guard.ts` — so a session that
43
+ // `tools/time/time-batch-guard.ts` — so a session that
44
44
  // merely opened that file carries the text too — and did so in a result whose `is_error` is false.
45
45
  //
46
46
  // **That fact is read off the parsed block, never off the raw line**. The
@@ -16,11 +16,44 @@ import { time_shell } from '#scripts/time-runtime/time-shell'
16
16
  const SEGMENT_SEPARATOR = /&&|\|\||;|\n/u
17
17
  const SEGMENT_PARTS = new RegExp(`(${SEGMENT_SEPARATOR.source})`, 'u')
18
18
 
19
+ // **The rows that read a segment as argv cut at the pipe and the background `&` as well.** Their
20
+ // question is which program a segment launches, and `true | git push -f` or `x & git push -f`
21
+ // launches git all the same; a `--jq` fragment cut off by a `|` begins with no program word, so it
22
+ // launches nothing they look for. A `&` that belongs to a redirection (`2>&1`, `&>file`, `<&3`) does
23
+ // not cut.
24
+ const COMMAND_SEPARATOR = /&&|\|\||;|\n|\|&?|(?<![<>])&(?!>)/u
25
+
19
26
  /** The line's commands, trimmed. Empty segments are kept: a caller anchoring at `^` rejects them. */
20
27
  function segments_of(command: string): Array<string> {
21
28
  return command.split(SEGMENT_SEPARATOR).map((segment) => segment.trim())
22
29
  }
23
30
 
31
+ /** The line's commands as separate programs: the `segments_of` cut plus a pipe and a background `&`. */
32
+ function commands_of(command: string): Array<string> {
33
+ return command.split(COMMAND_SEPARATOR).map((segment) => segment.trim())
34
+ }
35
+
36
+ const COMMAND_SEPARATORS = new RegExp(COMMAND_SEPARATOR.source, 'gu')
37
+
38
+ /**
39
+ * The `commands_of` cut taken where the quote-blanked line puts each separator, so a `|` or `;`
40
+ * inside a quoted argument does not cut it; a heredoc line falls back to `commands_of`.
41
+ */
42
+ function quote_aware_commands_of(command: string): Array<string> {
43
+ const plain = time_shell.blanked(command)
44
+
45
+ if (plain === undefined) return commands_of(command)
46
+
47
+ const cuts = [...plain.matchAll(COMMAND_SEPARATORS)].map((match) => ({
48
+ begin: match.index,
49
+ end: match.index + match[0].length,
50
+ }))
51
+ const starts = [0, ...cuts.map((cut) => cut.end)]
52
+ const stops = cuts.map((cut) => cut.begin)
53
+
54
+ return starts.map((start, index) => command.slice(start, stops[index] ?? command.length).trim())
55
+ }
56
+
24
57
  /** The same cut, untrimmed and with each separator kept between its commands, so the parts join back to the line. */
25
58
  function parts_of(command: string): Array<string> {
26
59
  return command.split(SEGMENT_PARTS)
@@ -55,9 +88,11 @@ function is_josh_command(segment: string, names: ReadonlySet<string>): boolean {
55
88
  }
56
89
 
57
90
  const shell_segments = {
91
+ commands_of,
58
92
  first_of,
59
93
  is_josh_command,
60
94
  parts_of,
95
+ quote_aware_commands_of,
61
96
  segments_of,
62
97
  }
63
98
 
@@ -0,0 +1,64 @@
1
+ import type { DeliveredRule } from './delivered-rules'
2
+
3
+ // The `Stop` hook's rows; `stop:guard` judges every stop. A row with a fixed answer runs it itself and
4
+ // blocks only when that fails; a row that needs judgement blocks the stop while it holds. They have no
5
+ // guard row, so the listing reads their description from here.
6
+
7
+ type StopRule = Pick<DeliveredRule, 'about' | 'id'>
8
+
9
+ const STOP_GUARD = 'pnpm josh stop:guard'
10
+
11
+ const ROWS: ReadonlyArray<StopRule> = [
12
+ {
13
+ id: 'stop-notify',
14
+ about: {
15
+ title: 'Stop notification',
16
+ topic: '`CLAUDE.md` → "Mid-workflow stop notification"',
17
+ entry: STOP_GUARD,
18
+ fires:
19
+ 'a stop with the work tree held and no `confirmation` notify that turn. Sends the notify itself; blocks only when the send fails',
20
+ quiet: 'no hold, a `confirmation` notify on the tail, or a pre-gate cut taken',
21
+ },
22
+ },
23
+ {
24
+ id: 'hold-release',
25
+ about: {
26
+ title: 'Hold release',
27
+ topic: '`.claude/skills/workflow-commands/working-tree-hold.md`',
28
+ entry: STOP_GUARD,
29
+ fires:
30
+ 'a stop on a clean tree with the `run:hold` record still in place. Releases the hold itself; blocks only when that fails',
31
+ quiet:
32
+ 'a dirty tree (a `halfrun` stop before the commit, a `needs-human-review` stop) or already released',
33
+ },
34
+ },
35
+ {
36
+ id: 'issue-citation',
37
+ about: {
38
+ title: 'Issue citation format',
39
+ topic: '`prompts/collaboration-workflow/issue-citation.md`',
40
+ entry: STOP_GUARD,
41
+ fires:
42
+ 'a bare `#N` in the prose of the last reply. Prints the citation lines itself; blocks only when a number cannot be cited',
43
+ quiet:
44
+ 'link form, inside code or a quote, `#N` right after `PR`, or a GitHub-facing artifact',
45
+ },
46
+ },
47
+ {
48
+ id: 'filing-offer',
49
+ about: {
50
+ title: 'Offer to file',
51
+ topic: '`.claude/skills/workflow-commands/observation-filing.md`',
52
+ entry: STOP_GUARD,
53
+ fires:
54
+ 'an unattended run (a kit-launched headless session, a lane child, a `backlogrun` parent) whose last reply offers to file without filing. Blocks the stop',
55
+ quiet:
56
+ 'an interactive session, already filed, inside a fence or quote, a named third-party `owner/repo`, or an unknown owner',
57
+ },
58
+ },
59
+ ]
60
+
61
+ const stop_rule_rows = { ROWS }
62
+
63
+ export type { StopRule }
64
+ export { stop_rule_rows }
@@ -1,4 +1,5 @@
1
1
  import { hook_decision } from '#scripts/josh/hook-decision'
2
+ import { json_value } from '#scripts/lib/json-value'
2
3
  import { z } from 'zod'
3
4
  import { filing_offer } from './filing-offer'
4
5
  import { issue_citation } from './issue-citation'
@@ -169,7 +170,7 @@ function build_citation_reason(references: ReadonlyArray<string>): string {
169
170
  const FILING_OFFER_REASON =
170
171
  '⛔ filing offer: your reply offers to file an Issue instead of filing it, and this run is ' +
171
172
  'unattended — nobody is there to answer. Run ' +
172
- '`pnpm josh issue:file "<title>" --body-file <path> --depth <0|1|2>` (Tier A, ' +
173
+ '`pnpm josh issue:file "<title>" --body-file <path>` (Tier A, ' +
173
174
  '`observation-filing.md`), then end with the one-line citation of what was filed; do not repeat ' +
174
175
  'your previous reply. If it is not worth filing after all, say so in one line instead.'
175
176
 
@@ -447,9 +448,7 @@ function notice_envelope(notice: string): string {
447
448
  }
448
449
 
449
450
  function parse_stop_payload(raw_payload: string): StopPayload | undefined {
450
- const parsed = stop_payload_schema.safeParse(JSON.parse(raw_payload))
451
-
452
- return parsed.success ? parsed.data : undefined
451
+ return json_value.parse_with(raw_payload, stop_payload_schema)
453
452
  }
454
453
 
455
454
  function is_enabled(): boolean {
@@ -38,7 +38,17 @@ const REASON =
38
38
  // The enumeration row itself, so `delivered-rules.ts` spreads one entry rather than restating the
39
39
  // trigger and reason it already single-sources here. Once per run (the default delivery) for the
40
40
  // reason above.
41
- const ROW = { id: 'test-declared', is_trigger: is_untested_commit, reason: REASON }
41
+ const ROW = {
42
+ id: 'test-declared',
43
+ is_trigger: is_untested_commit,
44
+ reason: REASON,
45
+ about: {
46
+ title: 'Test declaration',
47
+ topic: '`CLAUDE.md` → Code Change Rules',
48
+ fires: '`pnpm josh git -y` (`josh g`) while `pnpm josh test:declared` answers `required`',
49
+ quiet: '`exempt` (non-runtime only) or `satisfied` (tests included)',
50
+ },
51
+ }
42
52
 
43
53
  const test_declared_commit = { REASON, ROW }
44
54
 
@@ -117,6 +117,13 @@ const ROW = {
117
117
  is_trigger: bash_triggers.on_bash_command((command: string) => writes_third_party(command)),
118
118
  reason: THIRD_PARTY_WRITE_REASON,
119
119
  decide: (): boolean => true,
120
+ about: {
121
+ title: 'Third-party write',
122
+ topic: '`upstream-interrupt.md`',
123
+ fires:
124
+ 'a `gh api` write (field flag or a write method) to a repository whose owner is not this session. Every occurrence',
125
+ quiet: 'a read, or a first-party owner (`pnpm josh repo:party`)',
126
+ },
120
127
  }
121
128
 
122
129
  const third_party_write = {
@@ -0,0 +1,69 @@
1
+ import { bash_triggers } from './bash-triggers'
2
+ import { shell_segments } from './shell-segments'
3
+
4
+ // The trigger and the delivered text behind the `timed-rerun` row of `delivered-rules.ts`
5
+ // (joshuafolkken/kit#4356). A lane agent timed a whole-tree `eslint` twice to learn what CI already
6
+ // records, and each run took about 1.3 cores for seven minutes outside the core budget.
7
+ //
8
+ // **The timer is the trigger, not the tool.** What a run is after when it prefixes `time` or reaches
9
+ // for `hyperfine` is a duration, and a duration of CI or of the gate is already on record — the Actions
10
+ // jobs and the lane ledger. The tool under the timer can be anything, so reading the timer is the one
11
+ // trigger that does not have to enumerate them.
12
+ //
13
+ // **Once per run.** The rule allows one re-run when the record cannot answer, so the reissue goes
14
+ // through. On that reissue `lane-direct-tool` still refuses a lane child's `time`-prefixed heavy tool
15
+ // (`git_argv` skips the timer) and points it at `pnpm josh reserved-run`, the overlap
16
+ // `delivered-rules.ts` admits. A `hyperfine "<command>"` carries the tool inside a quoted argument,
17
+ // which `lane-direct-tool` does not read, so in a lane that reissue is not budgeted.
18
+
19
+ // A segment that opens with a timer, behind any environment assignments: `time`, `/usr/bin/time -p`
20
+ // and `hyperfine`. Anchored at the segment start, so a quoted mention or an argument is not a timer.
21
+ const TIMED_SEGMENT = /^\s*(?:[A-Za-z_]\w*=\S*\s+)*(?:\S*\/)?(?:time|hyperfine)\s/u
22
+
23
+ function is_timed_run(command: string): boolean {
24
+ return shell_segments
25
+ .quote_aware_commands_of(command)
26
+ .some((segment) => TIMED_SEGMENT.test(segment))
27
+ }
28
+
29
+ // Reading the record: an Actions run or job listing, or the lane ledger's gate timings.
30
+ const RECORD_READ = /\bgh\s+api\b.*\/actions\/runs\b|\bjosh\s+(?:lane:stats|lst)\b/u
31
+
32
+ function reads_the_record(command: string): boolean {
33
+ return RECORD_READ.test(command)
34
+ }
35
+
36
+ function measures_duration(command: string): boolean {
37
+ return reads_the_record(command) || is_timed_run(command)
38
+ }
39
+
40
+ const TIMED_RERUN_REASON =
41
+ '⛔ timed re-run: a CI or gate duration is already on record — read the Actions jobs with ' +
42
+ '`gh api …/actions/runs/<run_id>/jobs` or the gate timings with `pnpm josh lane:stats`. Re-run ' +
43
+ 'only when the record cannot answer: reissue the same command once, and post the result on the ' +
44
+ 'Issue (`prompts/collaboration-workflow/measurement.md`).'
45
+
46
+ // The row itself, so `delivered-rules.ts` spreads one entry; once per run, so the one allowed re-run
47
+ // goes through on the reissue.
48
+ const ROW = {
49
+ id: 'timed-rerun',
50
+ is_trigger: bash_triggers.on_bash_command(is_timed_run),
51
+ reason: TIMED_RERUN_REASON,
52
+ keeps: bash_triggers.on_bash_command(reads_the_record),
53
+ reaches: bash_triggers.on_bash_command(measures_duration),
54
+ about: {
55
+ title: 'Timed re-run',
56
+ topic: '`measurement.md`',
57
+ fires: 'a command timed with `time` / `/usr/bin/time` / `hyperfine`',
58
+ quiet: 'the duration is read from the Actions jobs or `pnpm josh lane:stats`',
59
+ },
60
+ }
61
+
62
+ const timed_rerun = {
63
+ ROW,
64
+ TIMED_RERUN_REASON,
65
+ is_timed_run,
66
+ reads_the_record,
67
+ }
68
+
69
+ export { timed_rerun }
@@ -17,7 +17,9 @@ import { shell_segments } from './shell-segments'
17
17
  // that stash findable and poppable by `pnpm josh stash:pop`, which is the whole of `operating-rules.md`'s
18
18
  // safety argument; the forms it warns against are the *positional/bare* ones. So `git stash push -m`
19
19
  // (with or without `-u`) and the read-only `git stash list` / `show` pass, and everything else — bare
20
- // `git stash`, a message-less push, `pop` / `apply` / `drop` / `save` / `clear` — is refused.
20
+ // `git stash`, a message-less push, `pop` / `apply` / `drop` / `save` / `clear` — is refused. Those
21
+ // flows now push with `pnpm josh stash:push` (joshuafolkken/kit#4131), invisible here; the raw message
22
+ // form still passes for a procedure written before it.
21
23
  //
22
24
  // **The refusal names the way on for a handed-over stash.** joshuafolkken/kit#3630's plan restored a
23
25
  // stash with `git stash apply`, and the lane parked on how to apply it instead of popping by message;
@@ -117,7 +119,7 @@ function is_unauthorized_segment(segment: string): boolean {
117
119
  }
118
120
 
119
121
  function is_unauthorized_worktree_change(command: string): boolean {
120
- return shell_segments.segments_of(command).some((segment) => is_unauthorized_segment(segment))
122
+ return shell_segments.commands_of(command).some((segment) => is_unauthorized_segment(segment))
121
123
  }
122
124
 
123
125
  // The instruction in the shape a refusal can carry: what the command touches, the authorized route,
@@ -125,7 +127,7 @@ function is_unauthorized_worktree_change(command: string): boolean {
125
127
  // invisible to this trigger, so a run that uses them is never refused.
126
128
  const WORKTREE_MUTATION_REASON =
127
129
  '⛔ unauthorized working-tree change: `git checkout --`, `git restore`, `git clean -f`, ' +
128
- '`git stash`. A documented flow stashes with `git stash push -u -m "<message>"`; a handed-over ' +
130
+ '`git stash`. A documented flow stashes with `pnpm josh stash:push "<message>"`; a handed-over ' +
129
131
  'stash is `pnpm josh stash:pop "<message>"`; record the substitution on the Issue (Tier A) unless ' +
130
132
  'the plan says why the owner keeps the stash: then stop and confirm. It fires on every occurrence ' +
131
133
  '(`operating-rules.md`).'
@@ -135,6 +137,14 @@ const ROW = {
135
137
  is_trigger: bash_triggers.on_bash_command(is_unauthorized_worktree_change),
136
138
  reason: WORKTREE_MUTATION_REASON,
137
139
  decide: (): boolean => true,
140
+ about: {
141
+ title: 'Unauthorized work-tree mutation',
142
+ topic: '`operating-rules.md`',
143
+ fires:
144
+ '`git checkout -- <path>` / `git restore <path>` / forced `git clean -f` / an unauthorized `git stash` (bare, push without a message, positional pop). Every occurrence',
145
+ quiet:
146
+ '`git stash push -m`, `git stash list`, `pnpm josh git`, `pnpm josh stash:push`, `pnpm josh stash:pop`',
147
+ },
138
148
  }
139
149
 
140
150
  const worktree_guard = {