@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
@@ -0,0 +1,82 @@
1
+ import type { SnapshotObserver } from '#scripts/gh/git-pr-checks'
2
+ import type { PrStateSnapshot } from '#scripts/gh/git-pr-checks-parse'
3
+ import { lane_ledger } from '#scripts/lane/lane-ledger'
4
+ import type { CodeRabbitState } from '#scripts/run/event/run-event-checks'
5
+ import { followup_checks_event } from './followup-checks-event'
6
+
7
+ // How long `followup`'s check waits spent with CodeRabbit still running or rate-limited
8
+ // (joshuafolkken/kit#4574). CodeRabbit does not gate the merge, so the wait never names it; without
9
+ // this, a followup that sat for half an hour beside a rate-limited CodeRabbit leaves nothing in the
10
+ // lane ledger but a long `ci-wait`.
11
+ //
12
+ // **The time between two polls is the state the earlier poll saw** — the observer sees snapshots, not
13
+ // transitions, so the clock is read at each one and the interval since the last is charged to the
14
+ // state that held over it. The clock is `performance.now()`'s, monotonic for the reason
15
+ // `git-followup-stages.ts` states.
16
+
17
+ const NO_TIME = 0
18
+ const RATE_LIMITED: CodeRabbitState = 'rate-limited'
19
+ const WAITING_STATES: ReadonlySet<CodeRabbitState> = new Set(['running', RATE_LIMITED])
20
+
21
+ interface Poll {
22
+ state: CodeRabbitState
23
+ at_ms: number
24
+ }
25
+
26
+ // Mutable for the reason `StageLog` is: the observer adds to it as the wait polls.
27
+ interface CodeRabbitWait {
28
+ wait_ms: number
29
+ rate_limited_ms: number
30
+ last?: Poll
31
+ }
32
+
33
+ function new_wait(): CodeRabbitWait {
34
+ return { wait_ms: NO_TIME, rate_limited_ms: NO_TIME }
35
+ }
36
+
37
+ function charge(wait: CodeRabbitWait, last: Poll, now_ms: number): void {
38
+ const elapsed_ms = now_ms - last.at_ms
39
+
40
+ if (WAITING_STATES.has(last.state)) wait.wait_ms += elapsed_ms
41
+ if (last.state === RATE_LIMITED) wait.rate_limited_ms += elapsed_ms
42
+ }
43
+
44
+ function observe(wait: CodeRabbitWait, snapshot: PrStateSnapshot, now_ms: number): void {
45
+ if (wait.last !== undefined) charge(wait, wait.last, now_ms)
46
+
47
+ wait.last = { state: followup_checks_event.coderabbit_of(snapshot), at_ms: now_ms }
48
+ }
49
+
50
+ // **Each check wait is timed from its own first poll**: the time between two waits — the comment scans,
51
+ // the merge that found the head moved — is not CodeRabbit's, whatever the earlier wait last saw.
52
+ function observer_of(wait: CodeRabbitWait): SnapshotObserver {
53
+ delete wait.last
54
+
55
+ return async function time_snapshot(snapshot: PrStateSnapshot): Promise<void> {
56
+ observe(wait, snapshot, performance.now())
57
+ }
58
+ }
59
+
60
+ // Both observers on every poll — the board's event line and this timer.
61
+ function both(first: SnapshotObserver, second: SnapshotObserver): SnapshotObserver {
62
+ return async function observe_both(snapshot: PrStateSnapshot): Promise<void> {
63
+ await first(snapshot)
64
+ await second(snapshot)
65
+ }
66
+ }
67
+
68
+ async function record_part(stage: string, elapsed_ms: number): Promise<void> {
69
+ if (elapsed_ms > NO_TIME) await lane_ledger.record_stage({ stage, elapsed_ms })
70
+ }
71
+
72
+ // **A run that never saw CodeRabbit waiting records nothing**, so a row's run count is how many
73
+ // followups CodeRabbit held up, and its median is over those.
74
+ async function record(wait: CodeRabbitWait): Promise<void> {
75
+ await record_part(lane_ledger.CODERABBIT_WAIT_STAGE, wait.wait_ms)
76
+ await record_part(lane_ledger.CODERABBIT_RATE_LIMIT_STAGE, wait.rate_limited_ms)
77
+ }
78
+
79
+ const followup_coderabbit_wait = { both, new_wait, observe, observer_of, record }
80
+
81
+ export type { CodeRabbitWait }
82
+ export { followup_coderabbit_wait }
@@ -0,0 +1,81 @@
1
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
2
+ import { issue_watch_gate } from '#scripts/issue/issue-watch-gate'
3
+ import { review_attest } from '#scripts/review/review-attest'
4
+ import { review_interaction } from '#scripts/review/review-interaction'
5
+ import { review_record } from '#scripts/review/review-record'
6
+
7
+ // The merge gates over the review rounds — that the review read its own checkout, and that each round
8
+ // the change owes left its ledger line. `git-followup-workflow.ts` runs them first, before the gates over
9
+ // the pull request body.
10
+
11
+ // `/code-review` is forked by the harness and inherits the *session's* working directory, so a run
12
+ // implementing in a lane can be reviewed against a different tree entirely — one holding the
13
+ // previous child's already-merged code. That review finds nothing wrong and says so, and the run
14
+ // would read the silence as a clean round. **This is the seam where that is caught**: a merge is
15
+ // refused unless the review attested the checkout it was briefed on.
16
+ //
17
+ // **Absence is a refusal, not a pass.** The defect produces *no* signal, so a check that only
18
+ // compared two present records would answer `ok` in exactly the state it exists to catch.
19
+ //
20
+ // **Scoped to a checkout that actually briefed a review.** `review_attest.check` answers
21
+ // `not-required` where no `josh review:brief` was run here inside a run's lifetime, so a project or
22
+ // a flow that does not use the brief merges exactly as it did before.
23
+ //
24
+ // The direction is deliberate: a wrongly-refused merge costs one re-run of the review, and a wrongly
25
+ // allowed one ships a diff nobody read. Thrown rather than reported, so no `completion` Telegram is
26
+ // sent and nothing merges — `git_pr_followup.run` is never reached.
27
+ // `ok` means the guard was satisfied and `not-required` means it never applied to this checkout —
28
+ // both let the merge proceed, so the two gates below read the verdict through one predicate rather
29
+ // than repeating the pair of statuses.
30
+ function is_merge_permitted(status: string): boolean {
31
+ return status === 'ok' || status === 'not-required'
32
+ }
33
+
34
+ function is_valid_issue(issue_number: string | undefined): issue_number is string {
35
+ return issue_number !== undefined && issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue_number)
36
+ }
37
+
38
+ async function assert_review_attested(should_merge: boolean): Promise<void> {
39
+ if (!should_merge) return
40
+
41
+ const verdict = await review_attest.check_here()
42
+
43
+ if (!is_merge_permitted(verdict.status)) throw new Error(review_attest.refusal_message(verdict))
44
+
45
+ const refusal = await issue_watch_gate.review_refusal_here()
46
+
47
+ if (refusal !== undefined) throw new Error(refusal)
48
+ }
49
+
50
+ // Recording a review round as a prose request leaves the recurrence ledger blind whenever it is
51
+ // skipped. **This is the seam where it is a gate instead**: a merge is refused unless the round left
52
+ // a `- rf:` line for its issue, a zero-finding `none` line included — and, for a change to the run
53
+ // tooling, unless the interaction review left its `- ri:` line too (joshuafolkken/kit#4276).
54
+ //
55
+ // **Absence is a refusal, `missing` exactly as `assert_review_attested`'s is** — the defect this
56
+ // exists for produces *no* line, so silence must not read as success. A checkout that keeps no ledger
57
+ // answers `not-required` and merges as before, and a run whose issue the followup cannot identify has
58
+ // no key to check, so it carries on rather than blocking on missing information.
59
+ async function assert_review_recorded(
60
+ should_merge: boolean,
61
+ issue_number: string | undefined,
62
+ ): Promise<void> {
63
+ if (!should_merge || !is_valid_issue(issue_number)) return
64
+
65
+ const issue = Number(issue_number)
66
+ const verdict = await review_record.check(issue)
67
+
68
+ if (!is_merge_permitted(verdict.status)) throw new Error(review_record.refusal_message(issue))
69
+
70
+ const refusal = await review_interaction.refusal(issue)
71
+
72
+ if (refusal !== undefined) throw new Error(refusal)
73
+ }
74
+
75
+ const followup_review_gates = {
76
+ assert_review_attested,
77
+ assert_review_recorded,
78
+ is_valid_issue,
79
+ }
80
+
81
+ export { followup_review_gates }
@@ -1,6 +1,7 @@
1
1
  import { PrConflictError } from '#scripts/gh/git-pr-checks-eval'
2
2
  import { lane_ledger } from '#scripts/lane/lane-ledger'
3
3
  import { time_format } from '#scripts/time-runtime/time-format'
4
+ import { followup_coderabbit_wait, type CodeRabbitWait } from './followup-coderabbit-wait'
4
5
 
5
6
  // Where `pnpm josh followup` spends its own wall clock.
6
7
  //
@@ -90,13 +91,17 @@ interface FollowupStage {
90
91
  // `last_ms` is `performance.now()`'s clock rather than `Date.now()`'s, for the reason
91
92
  // `buffered-process.ts` states: it is monotonic, so a system clock adjusted mid-wait cannot produce a
92
93
  // negative lap.
94
+ //
95
+ // `coderabbit` rides on the log because every check wait of the run — the merge gate's and the one the
96
+ // merge goes back to (#4036) — adds to the same CodeRabbit time.
93
97
  interface StageLog {
94
98
  stages: Array<FollowupStage>
95
99
  last_ms: number
100
+ coderabbit: CodeRabbitWait
96
101
  }
97
102
 
98
103
  function new_log(): StageLog {
99
- return { stages: [], last_ms: performance.now() }
104
+ return { stages: [], last_ms: performance.now(), coderabbit: followup_coderabbit_wait.new_wait() }
100
105
  }
101
106
 
102
107
  function lap(log: StageLog, name: string): void {
@@ -140,7 +145,7 @@ function print_stages(log: StageLog): void {
140
145
 
141
146
  // The wait for CI goes to the lane ledger as well, where `josh lane:stats` reads it beside the review
142
147
  // round it would overlap: the printed block reaches only this run's reader. A wait that threw is the
143
- // `interrupted` lap and records nothing here.
148
+ // `interrupted` lap and records nothing here. CodeRabbit's part of the waits goes beside it.
144
149
  async function record_ci_wait(log: StageLog): Promise<void> {
145
150
  const wait = log.stages.find((stage) => stage.name === STAGE.checks_wait)
146
151
 
@@ -152,6 +157,11 @@ async function record_ci_wait(log: StageLog): Promise<void> {
152
157
  })
153
158
  }
154
159
 
160
+ async function record_waits(log: StageLog): Promise<void> {
161
+ await record_ci_wait(log)
162
+ await followup_coderabbit_wait.record(log.coderabbit)
163
+ }
164
+
155
165
  const git_followup_stages = {
156
166
  STAGE,
157
167
  STAGE_LINE_PREFIX,
@@ -161,7 +171,7 @@ const git_followup_stages = {
161
171
  total_ms,
162
172
  format_stages,
163
173
  print_stages,
164
- record_ci_wait,
174
+ record_waits,
165
175
  stopped_lap,
166
176
  }
167
177
 
@@ -2,15 +2,14 @@
2
2
  import { parseArgs } from 'node:util'
3
3
  import { git_branch } from '#scripts/git/git-branch'
4
4
  import { git_error } from '#scripts/git/git-error'
5
- import { issue_number_shape } from '#scripts/issue/issue-number-shape'
6
- import { issue_watch_gate } from '#scripts/issue/issue-watch-gate'
7
5
  import { cli_body } from '#scripts/josh/cli-body'
8
6
  import { josh_environment_file } from '#scripts/josh/josh-environment-file'
9
7
  import { git_notify, type GitNotifyConfig } from '#scripts/notify/git-notify'
8
+ import { acceptance_map_check } from '#scripts/review/acceptance-map-check'
10
9
  import { live_evidence } from '#scripts/review/live-evidence'
11
- import { review_attest } from '#scripts/review/review-attest'
12
- import { review_record } from '#scripts/review/review-record'
10
+ import { removed_tests_check } from '#scripts/review/removed-tests-check'
13
11
  import { parse_issue_number_from_text } from './followup-issue-number'
12
+ import { followup_review_gates } from './followup-review-gates'
14
13
  import { git_followup_finish } from './git-followup-finish'
15
14
  import { git_followup_flush } from './git-followup-flush'
16
15
  import { git_followup_merged, type MergePlan } from './git-followup-merged'
@@ -120,78 +119,48 @@ function is_merge_resolved(values: CliArguments['values']): boolean {
120
119
  return values['no-merge'] !== true
121
120
  }
122
121
 
123
- // `/code-review` is forked by the harness and inherits the *session's* working directory, so a run
124
- // implementing in a lane can be reviewed against a different tree entirely — one holding the
125
- // previous child's already-merged code. That review finds nothing wrong and says so, and the run
126
- // would read the silence as a clean round. **This is the seam where that is caught**: a merge is
127
- // refused unless the review attested the checkout it was briefed on.
128
- //
129
- // **Absence is a refusal, not a pass.** The defect produces *no* signal, so a check that only
130
- // compared two present records would answer `ok` in exactly the state it exists to catch.
131
- //
132
- // **Scoped to a checkout that actually briefed a review.** `review_attest.check` answers
133
- // `not-required` where no `josh review:brief` was run here inside a run's lifetime, so a project or
134
- // a flow that does not use the brief merges exactly as it did before.
135
- //
136
- // The direction is deliberate: a wrongly-refused merge costs one re-run of the review, and a wrongly
137
- // allowed one ships a diff nobody read. Thrown rather than reported, so no `completion` Telegram is
138
- // sent and nothing merges — `git_pr_followup.run` is never reached.
139
- // `ok` means the guard was satisfied and `not-required` means it never applied to this checkout —
140
- // both let the merge proceed, so the two gates below read the verdict through one predicate rather
141
- // than repeating the pair of statuses.
142
- function is_merge_permitted(status: string): boolean {
143
- return status === 'ok' || status === 'not-required'
144
- }
145
-
146
- function is_valid_issue(issue_number: string | undefined): boolean {
147
- return issue_number !== undefined && issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue_number)
148
- }
122
+ const { assert_review_attested, assert_review_recorded, is_valid_issue } = followup_review_gates
149
123
 
150
- async function assert_review_attested(should_merge: boolean): Promise<void> {
124
+ // A runtime change merges only with its acceptance criteria run for real and
125
+ // recorded in the pull request body — `live_evidence` carries the why. `exempt` (no runtime path
126
+ // changed) merges as before, and a `--no-merge` run has not reached the gate at all.
127
+ async function assert_live_evidence(should_merge: boolean, branch_name: string): Promise<void> {
151
128
  if (!should_merge) return
152
129
 
153
- const verdict = await review_attest.check_here()
154
-
155
- if (!is_merge_permitted(verdict.status)) throw new Error(review_attest.refusal_message(verdict))
130
+ const verdict = await live_evidence.check(branch_name)
156
131
 
157
- const refusal = await issue_watch_gate.review_refusal_here()
132
+ if (verdict !== 'required') return
158
133
 
159
- if (refusal !== undefined) throw new Error(refusal)
134
+ throw new Error(live_evidence.refusal_message())
160
135
  }
161
136
 
162
- // Recording a review round as a prose request leaves the recurrence ledger blind whenever it is
163
- // skipped. **This is the seam where it is a gate instead**: a merge is refused unless the round left
164
- // a `- rf:` line for its issue, a zero-finding `none` line included.
165
- //
166
- // **Absence is a refusal, `missing` exactly as `assert_review_attested`'s is** — the defect this
167
- // exists for produces *no* line, so silence must not read as success. A checkout that keeps no ledger
168
- // answers `not-required` and merges as before, and a run whose issue the followup cannot identify has
169
- // no key to check, so it carries on rather than blocking on missing information.
170
- async function assert_review_recorded(
137
+ // Every acceptance criterion the Issue carries at the merge maps to a row in the pull request body —
138
+ // `acceptance_map` carries the why. Re-read here rather than at the commit, so a criterion added
139
+ // during the review is refused too. A run whose issue it cannot identify has no criteria to read.
140
+ async function assert_acceptance_mapped(
171
141
  should_merge: boolean,
172
142
  issue_number: string | undefined,
143
+ branch_name: string,
173
144
  ): Promise<void> {
174
145
  if (!should_merge || !is_valid_issue(issue_number)) return
175
146
 
176
- const issue = Number(issue_number)
177
- const verdict = await review_record.check(issue)
178
-
179
- if (is_merge_permitted(verdict.status)) return
147
+ const refusal = await acceptance_map_check.refusal(issue_number, branch_name)
180
148
 
181
- throw new Error(review_record.refusal_message(issue))
149
+ if (refusal !== undefined) throw new Error(refusal)
182
150
  }
183
151
 
184
- // A runtime change merges only with its acceptance criteria run for real and
185
- // recorded in the pull request body — `live_evidence` carries the why. `exempt` (no runtime path
186
- // changed) merges as before, and a `--no-merge` run has not reached the gate at all.
187
- async function assert_live_evidence(should_merge: boolean, branch_name: string): Promise<void> {
152
+ // Every test the change removes is disposed of in the pull request body — `removed_tests` carries the
153
+ // why. It reads this checkout's diff, which `assert_live_evidence` has already refused to read for a
154
+ // branch other than the one checked out.
155
+ async function assert_removed_tests_disposed(
156
+ should_merge: boolean,
157
+ branch_name: string,
158
+ ): Promise<void> {
188
159
  if (!should_merge) return
189
160
 
190
- const verdict = await live_evidence.check(branch_name)
191
-
192
- if (verdict !== 'required') return
161
+ const refusal = await removed_tests_check.refusal(branch_name)
193
162
 
194
- throw new Error(live_evidence.refusal_message())
163
+ if (refusal !== undefined) throw new Error(refusal)
195
164
  }
196
165
 
197
166
  // Every pre-merge refusal, in order — each one throws, so nothing merges past the first that fails.
@@ -203,6 +172,8 @@ async function assert_merge_gates(
203
172
  await assert_review_attested(should_merge)
204
173
  await assert_review_recorded(should_merge, issue_number)
205
174
  await assert_live_evidence(should_merge, branch_name)
175
+ await assert_acceptance_mapped(should_merge, issue_number, branch_name)
176
+ await assert_removed_tests_disposed(should_merge, branch_name)
206
177
  }
207
178
 
208
179
  // After the gates, before the CI wait: a line appended since the run's commit rides the pull request
@@ -261,9 +232,9 @@ try {
261
232
  }
262
233
 
263
234
  const git_followup_workflow = {
235
+ assert_acceptance_mapped,
264
236
  assert_live_evidence,
265
- assert_review_attested,
266
- assert_review_recorded,
237
+ assert_removed_tests_disposed,
267
238
  parse_issue_number_from_text,
268
239
  prepare_merge,
269
240
  resolve_branch_name,
@@ -1,5 +1,8 @@
1
1
  import { epic_close } from '#scripts/epic/epic-close'
2
2
  import { git_gh_command } from '#scripts/gh/git-gh-command'
3
+ import type { PrStateSnapshot } from '#scripts/gh/git-pr-checks'
4
+ import { git_pr_merge_checked, type WaitForGreen } from '#scripts/gh/git-pr-merge-checked'
5
+ import { issue_body_or_comment } from '#scripts/issue/issue-body-or-comment'
3
6
  import { issue_watch_gate } from '#scripts/issue/issue-watch-gate'
4
7
  import { git_notify, type GitNotifyConfig } from '#scripts/notify/git-notify'
5
8
  import { git_followup_cleanup } from './git-followup-cleanup'
@@ -40,6 +43,10 @@ interface WrapupInput {
40
43
  // already on the issue does not post it twice (`git-followup-merged.ts`).
41
44
  is_merged?: boolean | undefined
42
45
  is_completion_recorded?: boolean | undefined
46
+ // The snapshot the merge gate passed, whose head the merge names, and the wait to go back to when
47
+ // that head moved before the merge (`git-pr-merge-checked.ts`, #4036).
48
+ checked?: PrStateSnapshot | undefined
49
+ wait_for_green: WaitForGreen
43
50
  }
44
51
 
45
52
  function build_notify_body(input: {
@@ -57,12 +64,6 @@ function build_notify_body(input: {
57
64
  })
58
65
  }
59
66
 
60
- function is_blank_issue_body(body: string | undefined): boolean {
61
- if (body === undefined) return true
62
-
63
- return body.trim().length === 0
64
- }
65
-
66
67
  async function post_notify_issue(input: {
67
68
  issue_number: string | undefined
68
69
  body: string
@@ -71,12 +72,7 @@ async function post_notify_issue(input: {
71
72
  throw new Error('Issue number is required for issue notification.')
72
73
  }
73
74
 
74
- const current_body = await git_gh_command.issue_get_body(input.issue_number)
75
- const should_edit_body = current_body !== undefined && is_blank_issue_body(current_body)
76
-
77
- await (should_edit_body
78
- ? git_gh_command.issue_edit_body(input.issue_number, input.body)
79
- : git_gh_command.issue_comment(input.issue_number, input.body))
75
+ await issue_body_or_comment.post(input.issue_number, input.body)
80
76
  }
81
77
 
82
78
  function should_notify_pr(target: GitNotifyConfig['target']): boolean {
@@ -239,7 +235,7 @@ async function run_tail_steps(input: WrapupInput): Promise<void> {
239
235
  async function run_wrapup(input: WrapupInput, log: StageLog): Promise<void> {
240
236
  if (input.should_merge && input.is_merged !== true) {
241
237
  await issue_watch_gate.assert_read_here()
242
- await git_gh_command.pr_merge(input.branch_name)
238
+ await git_pr_merge_checked.merge_checked(input)
243
239
  lap(log, STAGE.merge)
244
240
  }
245
241
 
@@ -256,7 +252,6 @@ export {
256
252
  git_pr_followup_wrapup,
257
253
  post_notify_issue,
258
254
  post_completion_notification,
259
- is_blank_issue_body,
260
255
  build_notify_body,
261
256
  }
262
257
  export type { WrapupInput }
@@ -1,7 +1,9 @@
1
1
  import { git_gh_command } from '#scripts/gh/git-gh-command'
2
2
  import { git_pr_ai_review, type TelegramContext } from '#scripts/gh/git-pr-ai-review'
3
+ import type { PrStateSnapshot } from '#scripts/gh/git-pr-checks'
3
4
  import { git_pr_coderabbit } from '#scripts/gh/git-pr-coderabbit'
4
5
  import { git_pr_managed_config } from '#scripts/gh/git-pr-managed-config'
6
+ import type { WaitForGreen } from '#scripts/gh/git-pr-merge-checked'
5
7
  import { github_issue_url } from '#scripts/gh/github-issue-url'
6
8
  import { git_closes_keyword } from '#scripts/git/git-closes-keyword'
7
9
  import type { GitNotifyConfig } from '#scripts/notify/git-notify'
@@ -11,6 +13,7 @@ import {
11
13
  type TelegramTaskType,
12
14
  } from '#scripts/notify/telegram-notify'
13
15
  import { followup_checks_event } from './followup-checks-event'
16
+ import { followup_coderabbit_wait } from './followup-coderabbit-wait'
14
17
  import { git_followup_merged } from './git-followup-merged'
15
18
  import { git_followup_pending } from './git-followup-pending'
16
19
  import { git_followup_stages, type StageLog } from './git-followup-stages'
@@ -226,22 +229,45 @@ async function run_comment_scans(
226
229
  // different destinations: every note reaches the completion notification, and this one alone also
227
230
  // reaches the completion report posted to the Issue. Returning it twice is
228
231
  // what lets `run_stages` hand each destination what belongs to it without re-deriving the answer.
232
+ //
233
+ // **The snapshot travels on to the merge**, which names its head, and the same wait is what the merge
234
+ // goes back to when that head moved before it (#4036).
235
+ interface ReviewChecks {
236
+ notes: Array<string>
237
+ managed: Array<string>
238
+ snapshot?: PrStateSnapshot
239
+ }
240
+
241
+ function wait_for_green_of(
242
+ input: FollowupInput,
243
+ context: TelegramContext,
244
+ issue_number: string | undefined,
245
+ log: StageLog,
246
+ ): WaitForGreen {
247
+ return async function wait_for_green(): Promise<PrStateSnapshot> {
248
+ return await run_checks({
249
+ branch_name: input.branch_name,
250
+ is_skip_watch: input.is_skip_watch,
251
+ observe: followup_coderabbit_wait.both(
252
+ followup_checks_event.observer_of(issue_number, context.pr_url),
253
+ followup_coderabbit_wait.observer_of(log.coderabbit),
254
+ ),
255
+ })
256
+ }
257
+ }
258
+
229
259
  async function run_review_checks(
230
260
  input: FollowupInput,
231
261
  context: TelegramContext,
232
262
  log: StageLog,
233
263
  issue_number: string | undefined,
234
- ): Promise<{ notes: Array<string>; managed: Array<string> }> {
264
+ ): Promise<ReviewChecks> {
235
265
  if (input.is_merged === true) return { notes: [], managed: [] }
236
266
 
237
267
  const managed = await git_pr_managed_config.handle_managed_config_changes({
238
268
  should_merge: input.should_merge,
239
269
  })
240
- const snapshot = await run_checks({
241
- branch_name: input.branch_name,
242
- is_skip_watch: input.is_skip_watch,
243
- observe: followup_checks_event.observer_of(issue_number, context.pr_url),
244
- })
270
+ const snapshot = await wait_for_green_of(input, context, issue_number, log)()
245
271
 
246
272
  lap(log, STAGE.checks_wait)
247
273
  const check_notes = read_coderabbit_skip_notes(snapshot)
@@ -249,7 +275,7 @@ async function run_review_checks(
249
275
  log_skip_notes(check_notes)
250
276
  const scan_notes = await run_comment_scans(input, context, log)
251
277
 
252
- return { notes: [...managed, ...check_notes, ...scan_notes], managed }
278
+ return { notes: [...managed, ...check_notes, ...scan_notes], managed, snapshot }
253
279
  }
254
280
 
255
281
  // **A tail re-run after a merge does not report twice**: where the issue
@@ -296,6 +322,8 @@ async function run_stages(input: FollowupInput, log: StageLog): Promise<string |
296
322
  managed_notes: checks.managed,
297
323
  is_merged: input.is_merged,
298
324
  is_completion_recorded,
325
+ checked: checks.snapshot,
326
+ wait_for_green: wait_for_green_of(input, context, issue_number, log),
299
327
  },
300
328
  log,
301
329
  )
@@ -319,7 +347,7 @@ async function run(input: FollowupInput): Promise<string | undefined> {
319
347
  throw error
320
348
  } finally {
321
349
  git_followup_stages.print_stages(log)
322
- await git_followup_stages.record_ci_wait(log)
350
+ await git_followup_stages.record_waits(log)
323
351
  }
324
352
  }
325
353
 
@@ -24,7 +24,7 @@ const USAGE =
24
24
  'Usage: josh fresh:run <pattern> | --spec <file.json> [--package-version <version>] [--log-dir <dir>] [--rebuild] | --list'
25
25
  // The scratch directory kit's distributed `.gitignore` already ignores, so a log is never committed
26
26
  // from kit or from a consumer toolkit.
27
- const DEFAULT_LOG_DIRECTORY = '.claude/tmp/fresh-machine'
27
+ const DEFAULT_LOG_DIRECTORY = '.josh/tmp/fresh-machine'
28
28
  const NO_GITHUB_TOKEN =
29
29
  'This scenario uses GitHub and `gh auth token` printed no token. Run `gh auth login` on this machine first.'
30
30
  const NO_CLAUDE_TOKEN = `This scenario uses Claude Code and neither the macOS keychain nor ${claude_token.VARIABLE} holds a token. ${claude_token.SETUP_HINT}`
@@ -4,13 +4,14 @@ import {
4
4
  mkdirSync,
5
5
  mkdtempSync,
6
6
  readdirSync,
7
- readFileSync,
8
7
  rmSync,
9
8
  writeFileSync,
10
9
  } from 'node:fs'
11
10
  import os from 'node:os'
12
11
  import path from 'node:path'
13
12
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
13
+ import { package_manifest } from '#scripts/lib/package-manifest'
14
+ import { npm_registry } from '#scripts/version/npm-registry'
14
15
  import { execa, type Options } from 'execa'
15
16
  import { z } from 'zod'
16
17
  import { fresh_machine_docker, type ContainerRun } from './fresh-machine-docker'
@@ -133,19 +134,18 @@ async function pack(pack_directory: string, write: Write): Promise<string> {
133
134
  }
134
135
 
135
136
  function package_name(): string {
136
- const manifest = readFileSync(path.join(PROJECT_ROOT, 'package.json'), 'utf8')
137
-
138
- return MANIFEST_SCHEMA.parse(JSON.parse(manifest)).name
137
+ return package_manifest.read_manifest(PROJECT_ROOT, MANIFEST_SCHEMA).name
139
138
  }
140
139
 
141
140
  // The published version is always written out in the log and the install command, so a run can be
142
141
  // repeated against the same release; without `--package-version` it is the registry's latest.
143
- async function published_version(requested: string | undefined): Promise<string> {
142
+ function published_version(requested: string | undefined): string {
144
143
  if (requested !== undefined) return requested
145
144
 
146
- const { stdout } = await execa(PNPM, ['view', package_name(), 'version'], { cwd: PROJECT_ROOT })
145
+ const answer = npm_registry.view(package_name(), 'version')
146
+ if (answer.exit_code !== 0) throw new Error('the registry did not answer the latest version')
147
147
 
148
- return stdout.trim()
148
+ return answer.stdout.trim()
149
149
  }
150
150
 
151
151
  async function container_run(
@@ -163,7 +163,7 @@ async function container_run(
163
163
  seed_directory: staged.seed_directory,
164
164
  pack_directory: staged.pack_directory,
165
165
  tarball: is_tarball ? await pack(staged.pack_directory, write) : undefined,
166
- package_version: is_tarball ? undefined : await published_version(request.package_version),
166
+ package_version: is_tarball ? undefined : published_version(request.package_version),
167
167
  secret_names: Object.keys(request.secrets),
168
168
  }
169
169
  }
@@ -12,7 +12,7 @@
12
12
  "printf '{ \"private\": true }\\n' > package.json",
13
13
  "cp \"$PACKAGE_TARBALL\" . && pnpm add -D --allow-build=esbuild --allow-build=unrs-resolver \"./$(basename \"$PACKAGE_TARBALL\")\"",
14
14
  "pnpm exec josh start --yes --github",
15
- "gh label list --limit 100 --json name --jq '.[].name' > \"$HOME/labels.txt\"; grep -xE 'auto-ok|needs-decision|needs-human-review|already-done|review-round2-skipped|bug' \"$HOME/labels.txt\"; test \"$(grep -cxE 'auto-ok|needs-decision|needs-human-review|already-done|review-round2-skipped|bug' \"$HOME/labels.txt\")\" -eq 6",
15
+ "gh label list --limit 100 --json name --jq '.[].name' > \"$HOME/labels.txt\"; grep -xE 'auto-ok|needs-decision|needs-human-review|already-done|bug' \"$HOME/labels.txt\"; test \"$(grep -cxE 'auto-ok|needs-decision|needs-human-review|already-done|bug' \"$HOME/labels.txt\")\" -eq 5",
16
16
  "curl -fsSL https://claude.ai/install.sh | bash && export PATH=\"$HOME/.local/bin:$PATH\" && claude --version",
17
17
  "gh issue create --title 'Add a heading to index.html' --body 'Add an h2 under the h1.' --label auto-ok --label run:lane",
18
18
  "timeout 60 pnpm josh backlogrun > \"$HOME/backlogrun.out\" 2>&1; cat \"$HOME/backlogrun.out\"; grep -q '^backlogrun: started' \"$HOME/backlogrun.out\"",
@@ -0,0 +1,58 @@
1
+ import type { MachineReading } from './machine-capacity'
2
+
3
+ // **The busy cores a waiting claim admits against are the mean of its last few seconds of readings**
4
+ // (joshuafolkken/kit#4238). One reading covers a 250 ms window, and a CPU near saturation swings across
5
+ // the threshold from one window to the next, so a claim judged on each reading alone would be admitted
6
+ // on a dip into load that is still there. A claim's readings are its own: each poll of one wait adds
7
+ // one, and its first poll judges on the one it has.
8
+ //
9
+ // **What is averaged is the load outside the ledger, each sample against the ledger of its own
10
+ // moment.** Averaging the raw busy cores and subtracting the ledger of now would count a claim released
11
+ // inside the window as external load: its cores would linger in the mean after leaving the ledger.
12
+
13
+ // Long enough to hold about ten polls of a waiting claim, short enough that a CPU freed a moment ago is
14
+ // admitted against within seconds.
15
+ const AVERAGE_WINDOW_MS = 3000
16
+
17
+ interface BusySample {
18
+ at: number
19
+ external_cores: number
20
+ }
21
+
22
+ // The samples still inside the window once `reading` taken at `now`, against a ledger holding
23
+ // `ledger_cores`, is added. An unread reading adds nothing: where the machine cannot be read, nothing
24
+ // is averaged.
25
+ function with_reading(
26
+ samples: ReadonlyArray<BusySample>,
27
+ reading: MachineReading,
28
+ ledger_cores: number,
29
+ now: number,
30
+ ): Array<BusySample> {
31
+ const kept = samples.filter((sample) => now - sample.at < AVERAGE_WINDOW_MS)
32
+ const { busy_cores } = reading
33
+
34
+ if (busy_cores === undefined) return kept
35
+
36
+ return [...kept, { at: now, external_cores: Math.max(0, busy_cores - ledger_cores) }]
37
+ }
38
+
39
+ // `reading` with its busy cores replaced by the mean load outside the ledger on top of the ledger's
40
+ // `ledger_cores` now, or unchanged when none were read.
41
+ function averaged(
42
+ reading: MachineReading,
43
+ samples: ReadonlyArray<BusySample>,
44
+ ledger_cores: number,
45
+ ): MachineReading {
46
+ if (reading.busy_cores === undefined || samples.length === 0) return reading
47
+
48
+ let total = 0
49
+
50
+ for (const sample of samples) total += sample.external_cores
51
+
52
+ return { ...reading, busy_cores: ledger_cores + total / samples.length }
53
+ }
54
+
55
+ const busy_average = { AVERAGE_WINDOW_MS, averaged, with_reading }
56
+
57
+ export type { BusySample }
58
+ export { busy_average }