@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
@@ -0,0 +1,70 @@
1
+ import { issue_cite } from '#scripts/issue/issue-cite'
2
+ import { RUN_STALLED_LABEL } from '#scripts/issue/issue-labels'
3
+ import { issue_park } from '#scripts/issue/issue-park'
4
+ import { telegram_notify } from '#scripts/notify/telegram-notify'
5
+ import { run_event_scope } from '#scripts/run/event/run-event-scope'
6
+ import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
7
+ import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
8
+ import { run_stalled } from '#scripts/run/park/run-stalled'
9
+
10
+ // How many times a stopped ship relaunches its lane child before the issue goes to a person. A child
11
+ // that keeps stopping — the same red check, a finding it cannot close — would otherwise relaunch
12
+ // without end, one ship's cost each time, with nobody told (joshuafolkken/kit#3999).
13
+ //
14
+ // **The count is the issue's `ship-stop` events since its last fresh dispatch**: a relaunch into the
15
+ // lane emits no `child-launch`, a dispatch does, so a re-dispatched issue starts a new budget. The
16
+ // current stop is emitted before the count is read, so it is part of it. Past the cap the issue is
17
+ // parked with `run:stalled`, which every offer and the lane broker already refuse to start.
18
+ // The whole stream is read, not the run's carry scope: the count scopes itself by issue and dispatch,
19
+ // and a lane child shipping with no carry record (`lane:dispatch` outside a run, or a run already
20
+ // ended) would otherwise read no events and relaunch without a cap.
21
+
22
+ // One dispatch's own stops in the measured week reached five once and four or fewer otherwise, so four
23
+ // relaunches leave a ship that converges alone and stop the one that does not.
24
+ const MAX_SHIP_STOP_RELAUNCHES = 4
25
+ const PARK_CAUSE = 'ship-stop cap'
26
+ const { CHILD_LAUNCH, PARK, SHIP_STOP } = run_event_stream.EVENT_KIND
27
+
28
+ function stops_since_dispatch(events: ReadonlyArray<RunEvent>, issue: string): number {
29
+ const own = events.filter((event) => run_event_scope.issue_named(event) === issue)
30
+ const dispatched = own.findLastIndex((event) => event.kind === CHILD_LAUNCH)
31
+
32
+ return own.slice(dispatched + 1).filter((event) => event.kind === SHIP_STOP).length
33
+ }
34
+
35
+ async function is_over(issue: string): Promise<boolean> {
36
+ const events = await run_event_stream_emit.all_events()
37
+
38
+ return stops_since_dispatch(events, issue) > MAX_SHIP_STOP_RELAUNCHES
39
+ }
40
+
41
+ function park_comment(issue: string, reason: string): string {
42
+ return [
43
+ `Parked by the \`josh ship\` supervisor: the ship stopped at \`${reason}\` after ${String(MAX_SHIP_STOP_RELAUNCHES)} relaunches of the lane child since its dispatch.`,
44
+ '',
45
+ `Read the stop with \`pnpm josh ship --log ${issue}\`, then ${run_stalled.next_step(issue)}.`,
46
+ ].join('\n')
47
+ }
48
+
49
+ // The label is what keeps the issue from being re-dispatched; without it the stop stays a plain stop,
50
+ // which `run:merge` books as an unanswered ship stop under its own outage cap.
51
+ async function park(issue: string, reason: string): Promise<boolean> {
52
+ const park_write = await issue_park.apply(issue, RUN_STALLED_LABEL, park_comment(issue, reason))
53
+
54
+ if (!park_write.is_labelled) return false
55
+
56
+ const cite = issue_cite.plain(issue)
57
+
58
+ await run_event_stream_emit.emit(PARK, run_stalled.park_event(issue, PARK_CAUSE))
59
+ await telegram_notify.warn({
60
+ issue_title: `Ship stop cap reached ${cite}`,
61
+ body: `The lane child stopped at ${reason} more than ${String(MAX_SHIP_STOP_RELAUNCHES)} times since its dispatch, so it was not relaunched and the issue is parked.`,
62
+ recovery: `Read pnpm josh ship --log ${issue}, then fix the cause and remove ${RUN_STALLED_LABEL} to offer it again.`,
63
+ })
64
+
65
+ return true
66
+ }
67
+
68
+ const run_ship_relaunch_cap = { MAX_SHIP_STOP_RELAUNCHES, is_over, park, stops_since_dispatch }
69
+
70
+ export { run_ship_relaunch_cap }
@@ -0,0 +1,61 @@
1
+ import { readFile, writeFile } from 'node:fs/promises'
2
+ import { git_branch } from '#scripts/git/git-branch'
3
+ import { git_command } from '#scripts/git/git-command'
4
+ import { removed_tests } from '#scripts/review/removed-tests'
5
+ import { removed_tests_check } from '#scripts/review/removed-tests-check'
6
+ import { run_ship_body_draft } from './run-ship-body-draft'
7
+
8
+ // **The tests a change removed, shown where a run passes before `josh ship`** — the end of a green
9
+ // `josh test:related`. Their disposition rows were first asked at the ship's preflight, after the
10
+ // pre-detach checks had run, and every lane that renamed a test stopped there and shipped again
11
+ // (joshuafolkken/kit#4563). The removed titles are `removed_tests_check.read()`'s, and the pending
12
+ // rows go into the branch's ship body draft, so the run only replaces each ending; the preflight still
13
+ // refuses a row left pending.
14
+
15
+ async function draft_of_branch(): Promise<string | undefined> {
16
+ const issue_number = git_branch.issue_from_branch(await git_command.branch())
17
+
18
+ if (issue_number === undefined) return undefined
19
+
20
+ return await run_ship_body_draft.existing(String(issue_number))
21
+ }
22
+
23
+ async function body_of(draft: string | undefined): Promise<string> {
24
+ return draft === undefined ? '' : await readFile(draft, 'utf8')
25
+ }
26
+
27
+ // An unreadable base lists nothing here — the preflight refuses on it — and outside a repository it
28
+ // keeps the branch, which git could not answer, from being asked at all.
29
+ async function removed_titles(): Promise<ReadonlyArray<string>> {
30
+ return (await removed_tests_check.read()) ?? []
31
+ }
32
+
33
+ function where(draft: string | undefined): string {
34
+ return draft === undefined
35
+ ? 'Put these rows into the pull request body'
36
+ : `Pending rows for them are in the ship body draft ${draft}`
37
+ }
38
+
39
+ function notice(titles: ReadonlyArray<string>, draft: string | undefined): string {
40
+ return [
41
+ `Removed tests — this change removes ${String(titles.length)} test(s) the ship body does not dispose of yet. ${where(draft)}; replace each ending, ${removed_tests.ROW_FORMAT}, or the \`josh ship\` preflight refuses:`,
42
+ ...titles.map((title) => ` - ${title}`),
43
+ ].join('\n')
44
+ }
45
+
46
+ async function surface(): Promise<void> {
47
+ const removed = await removed_titles()
48
+
49
+ if (removed.length === 0) return
50
+ const draft = await draft_of_branch()
51
+ const body = await body_of(draft)
52
+ const titles = removed_tests.undisposed(removed, body)
53
+
54
+ if (titles.length === 0) return
55
+ if (draft !== undefined) await writeFile(draft, removed_tests.with_pending_rows(body, titles))
56
+ console.info(notice(titles, draft))
57
+ }
58
+
59
+ const run_ship_removed_rows = { surface }
60
+
61
+ export { run_ship_removed_rows }
@@ -1,3 +1,4 @@
1
+ import { setTimeout as sleep } from 'node:timers/promises'
1
2
  import { agent_role_profile } from '#scripts/agent/agent-role-profile'
2
3
  import { lane_child_invocation, type ShipStop } from '#scripts/lane/lane-child-invocation'
3
4
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
@@ -8,8 +9,12 @@ import { run_event_stream } from '#scripts/run/event/run-event-stream'
8
9
  import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
9
10
  import type { ShipSection } from './run-ship'
10
11
  import { run_ship_next, type ShipResume } from './run-ship-next'
12
+ import { run_ship_place } from './run-ship-place'
13
+ import { run_ship_probe } from './run-ship-probe'
14
+ import { run_ship_relaunch_cap } from './run-ship-relaunch-cap'
11
15
  import { run_ship_stage, type Stage } from './run-ship-stage'
12
16
  import type { ShipArguments } from './run-ship-steps'
17
+ import { run_ship_stop_cause } from './run-ship-stop-cause'
13
18
  import { run_ship_stop_context } from './run-ship-stop-context'
14
19
  import { run_ship_stop_text } from './run-ship-stop-text'
15
20
 
@@ -25,16 +30,26 @@ import { run_ship_stop_text } from './run-ship-stop-text'
25
30
  // effort because a fix is judgement. It is started before the supervisor exits, so the parent's
26
31
  // liveness poll never sees the lane empty. An OpenAI lane is left to its own supervisor, which starts
27
32
  // no successor without a cut, so its parent books the stop exactly as it books any ended child.
33
+ // The relaunches are capped: past the cap the issue is parked and a person told instead.
28
34
  //
29
35
  // A ship run in an agent's own turn is not supervised and hands nothing back: its report is already in
30
36
  // front of the agent that ran it.
31
37
 
32
38
  const OPENAI_PROVIDER = 'openai'
39
+ // A minute of polling, long enough for the supervisor's 5-second lane scan to reopen a server.
40
+ const SERVING_POLL_MS = 1000
41
+ const SERVING_POLLS = 60
33
42
 
34
- type ReturnOutcome = 'relaunched' | 'recorded'
43
+ type ReturnOutcome = 'relaunched' | 'recorded' | 'parked' | 'redispatch'
35
44
 
36
- function stop_text(issue: string, stage: Stage, resume: ShipResume): string {
37
- return run_ship_stop_text.format(issue, run_ship_stage.stop_reason(stage, resume.conflicts))
45
+ // The failed stage's output, and its standard output alone where the stage kept it apart.
46
+ type StageOutput = Pick<ShipSection, 'body' | 'out'>
47
+
48
+ function stop_text(issue: string, stage: Stage, resume: ShipResume, output: StageOutput): string {
49
+ const reason = run_ship_stage.stop_reason(stage, resume.conflicts)
50
+ const cause = run_ship_stop_cause.cause_of(stage, { ...resume, ...output })
51
+
52
+ return run_ship_stop_text.format(issue, reason, cause)
38
53
  }
39
54
 
40
55
  function can_relaunch(lane: LaneInfo | undefined): lane is LaneInfo {
@@ -68,56 +83,125 @@ function relaunched(lane: LaneInfo, stop: ShipStop): ReturnOutcome {
68
83
  // **A served lane's child is relaunched by its broker, not from here**: this supervisor descends from the
69
84
  // child's Bash tool, which Claude Code starts without the token, so a child started here could not sign
70
85
  // in where the token is the only credential (joshuafolkken/kit#3817).
71
- async function brokered(lane: LaneInfo, stop: ShipStop): Promise<ReturnOutcome> {
86
+ async function ask_broker(lane: LaneInfo, stop: ShipStop): Promise<boolean> {
72
87
  const answer = await lane_session_broker.request(lane.directory, lane.issue, {
73
88
  kind: 'relaunch',
74
89
  stop,
75
90
  })
76
91
 
77
- if (answer.is_success) return 'relaunched'
92
+ if (!answer.is_success) note(`the lane broker did not start the lane child — ${answer.reason}`)
78
93
 
79
- note(
80
- `the lane child could not be relaunched: the lane broker did not start it — ${answer.reason}`,
81
- )
94
+ return answer.is_success
95
+ }
96
+
97
+ // The session of a broker serving the lane within the wait, other than `previous` — one that stopped
98
+ // serving is reopened by the supervisor's next lane scan (`claude-lane-broker.ts`).
99
+ async function await_server(lane: LaneInfo, previous?: string): Promise<string | undefined> {
100
+ for (let polled = 0; polled < SERVING_POLLS; polled += 1) {
101
+ const session = lane_session_broker.serving_session(lane.directory, lane.issue)
102
+ if (session !== undefined && session !== previous) return session
103
+
104
+ // eslint-disable-next-line no-await-in-loop -- polling: each check waits on the scan the previous one missed
105
+ await sleep(SERVING_POLL_MS)
106
+ }
107
+
108
+ return undefined
109
+ }
110
+
111
+ // **A relaunch the broker failed is asked once more, of a new broker only, then handed to the driver**: a
112
+ // stop left recorded waited hours for the stall detector (joshuafolkken/kit#4344). The broker that failed
113
+ // may still be starting the first relaunch, so asking it again could start a second child beside it.
114
+ // Once this supervisor exits, the driver's next poll reads the stop as unanswered and re-dispatches the
115
+ // issue (`run-merge-ship.ts`).
116
+ async function brokered(lane: LaneInfo, stop: ShipStop, server: string): Promise<ReturnOutcome> {
117
+ if (await ask_broker(lane, stop)) return 'relaunched'
118
+
119
+ const next = await await_server(lane, server)
120
+
121
+ if (next !== undefined && (await ask_broker(lane, stop))) return 'relaunched'
122
+
123
+ note('the lane child could not be relaunched: the driver re-dispatches the issue')
124
+
125
+ return 'redispatch'
126
+ }
127
+
128
+ // A child that stopped more often than the cap allows is parked instead of relaunched
129
+ // (`run-ship-relaunch-cap.ts`); a park the label refused leaves the stop recorded, as before.
130
+ async function parked(issue: string, stage: Stage, resume: ShipResume): Promise<ReturnOutcome> {
131
+ const reason = run_ship_stage.stop_reason(stage, resume.conflicts)
132
+
133
+ if (await run_ship_relaunch_cap.park(issue, reason)) return 'parked'
134
+
135
+ note('the lane child was not relaunched past the ship-stop cap, and the park label was refused')
82
136
 
83
137
  return 'recorded'
84
138
  }
85
139
 
86
- // `output` is the failed stage's own output: the relaunched child's prompt carries its tail.
87
- async function return_control(
140
+ // `output` is the failed stage's own output: the relaunched child's prompt carries the body's tail, and
141
+ // the stop is classified on its standard output (`run-ship-stop-cause.ts`).
142
+ async function stopped(
88
143
  issue: string,
89
144
  stage: Stage,
90
145
  resume: ShipResume,
91
- output: string,
146
+ output: StageOutput,
92
147
  ): Promise<ReturnOutcome> {
93
148
  await run_event_stream_emit.emit(
94
149
  run_event_stream.EVENT_KIND.SHIP_STOP,
95
- stop_text(issue, stage, resume),
150
+ stop_text(issue, stage, resume, output),
96
151
  )
97
152
 
98
153
  const lane = await lane_to_relaunch(issue)
99
154
 
100
155
  if (lane === undefined) return 'recorded'
101
156
 
102
- const stop = { stage, ...resume, context: await run_ship_stop_context.build(issue, output) }
157
+ if (await run_ship_relaunch_cap.is_over(issue)) return await parked(issue, stage, resume)
158
+ // A followup stop waits for a lane place, keeping the ship-stop prompt and the relaunch cap a driver
159
+ // re-dispatch would lose (`run-ship-place.ts`).
160
+ await run_ship_place.await_place(lane, stage)
161
+
162
+ const context = await run_ship_stop_context.build(issue, output.body)
163
+ const stop = { stage, ...resume, context }
164
+ // **A broker that stopped serving before the stop is waited for**: one that died during the review left
165
+ // the lane unserved at the stop, and a child started here cannot sign in on a token (joshuafolkken/kit#4344).
166
+ const server = await await_server(lane)
167
+
168
+ return server === undefined ? relaunched(lane, stop) : await brokered(lane, stop, server)
169
+ }
170
+
171
+ async function return_control(
172
+ issue: string,
173
+ stage: Stage,
174
+ resume: ShipResume,
175
+ output: string,
176
+ ): Promise<ReturnOutcome> {
177
+ return await stopped(issue, stage, resume, { body: output })
178
+ }
179
+
180
+ type FailedSection = Pick<ShipSection, 'body' | 'out' | 'conflicts' | 'cause'>
181
+
182
+ // The section's conflicts and the cause its review round tagged, only where it has them.
183
+ function stopped_resume(resume: ShipResume, failed: FailedSection | undefined): ShipResume {
184
+ const { conflicts, cause } = failed ?? {}
103
185
 
104
- return lane_session_broker.is_serving(lane.directory, issue)
105
- ? await brokered(lane, stop)
106
- : relaunched(lane, stop)
186
+ return {
187
+ ...resume,
188
+ ...(conflicts !== undefined && { conflicts }),
189
+ ...(cause !== undefined && { cause }),
190
+ }
107
191
  }
108
192
 
109
- // The stopped ship's arguments and its failed section, as `return_control` takes them: the section's
110
- // conflicts ride on the resume, its body is the output the prompt carries.
193
+ // The stopped ship's arguments and its failed section, as `stopped` takes them: the section's conflicts
194
+ // and tagged cause ride on the resume, its body and standard output are the stage's output. A stale
195
+ // review rides on it too, so the relaunched child re-detaches with `--review` (joshuafolkken/kit#4221).
111
196
  async function hand_back(
112
197
  args: ShipArguments,
113
198
  stage: Stage,
114
- failed: Pick<ShipSection, 'body' | 'conflicts'> | undefined,
199
+ failed: FailedSection | undefined,
115
200
  ): Promise<ReturnOutcome> {
116
- const resume = run_ship_next.resume_of(args)
117
- const conflicts = failed?.conflicts
118
- const stopped = conflicts === undefined ? resume : { ...resume, conflicts }
201
+ const is_review_stale = await run_ship_probe.read_review_stale()
202
+ const resume = { ...run_ship_next.resume_of(args), is_review_stale }
119
203
 
120
- return await return_control(args.number, stage, stopped, failed?.body ?? '')
204
+ return await stopped(args.number, stage, stopped_resume(resume, failed), failed ?? { body: '' })
121
205
  }
122
206
 
123
207
  const run_ship_return = { hand_back, return_control }
@@ -1,14 +1,13 @@
1
- import { agent_argv, type AgentArgv } from '#scripts/agent/agent-argv'
2
- import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
3
- import { PROJECT_ROOT } from '#scripts/init/init-paths'
4
- import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
1
+ import type { JoshResult } from '#scripts/josh/josh-run'
5
2
  import { stamp_file } from '#scripts/josh/stamp-file'
6
- import { lane_child_marker } from '#scripts/lane/lane-child-marker'
7
- import { lane_session_broker } from '#scripts/lane/lane-session-broker'
3
+ import { lane_ledger } from '#scripts/lane/lane-ledger'
4
+ import { review_interaction } from '#scripts/review/review-interaction'
8
5
  import { review_record } from '#scripts/review/review-record'
9
- import { detached_launch } from '#scripts/run/detached-launch'
6
+ import { review_round2 } from '#scripts/review/review-round2'
10
7
  import { run_ship_review, type RoundOutcome, type ScoredVerdict } from './run-ship-review'
11
- import { run_ship_scoped, type Phase } from './run-ship-scoped'
8
+ import { run_ship_reviewer, type Round } from './run-ship-reviewer'
9
+ import { run_ship_scoped } from './run-ship-scoped'
10
+ import { run_ship_stop_cause } from './run-ship-stop-cause'
12
11
  import type { StepResult } from './run-ship-sync'
13
12
 
14
13
  // The side effects of `josh ship --review`: the round-1 review — open, launch, join, attest and
@@ -17,7 +16,8 @@ import type { StepResult } from './run-ship-sync'
17
16
  //
18
17
  // 1. `run:review` starts the gate detached and mints the brief — the nonce `review:attest` checks.
19
18
  // 2. the reviewer is launched the way `run:wake` launches a session — `agent_argv` under the reviewer
20
- // profile, `detached_launch.launch_attached` to wait for its exit — handed the brief by path.
19
+ // profile, `detached_launch.launch_attached` to wait for its exit — handed the brief by path
20
+ // (`run-ship-reviewer.ts`).
21
21
  // 3. `run:review --join` blocks a verdict over a red gate; `review:attest --check` refuses a review
22
22
  // that read another checkout; `review:record` writes the round the merge gate reads.
23
23
  //
@@ -36,19 +36,15 @@ import type { StepResult } from './run-ship-sync'
36
36
  // unreadable findings file, a High or an unfixed Medium in round 1, and anything but a clean round 2 —
37
37
  // recorded first, because the round was attested, then routed back.
38
38
 
39
- const SUCCESS_EXIT_CODE = 0
40
- const FAILURE_EXIT_CODE = 1
41
- const should_forward_stderr = true
42
39
  const RUN_REVIEW = 'run:review'
43
- const ATTEST_CHECK = ['review:attest', '--check']
44
- const ROUND_TWO_DECISION = ['review:round2', '--round-1-closed']
45
- const ROUND_TWO_BRIEF = ['review:brief', '--round', '2']
46
- const ROUND_TWO_REQUIRED = 'required'
47
- const ROUND_ONE = '1'
48
- const ROUND_TWO = '2'
40
+ const ROUND_TWO_DECISION = ['review:round2', '--round-1-closed', '--json']
41
+ const REVIEW_BRIEF = 'review:brief'
42
+ const ROUND_TWO_BRIEF = [REVIEW_BRIEF, '--round', '2']
43
+ const INTERACTION_FLAG = '--interaction'
44
+ const INTERACTION_BRIEF = [REVIEW_BRIEF, INTERACTION_FLAG]
45
+ const UNREADABLE_DECISION_NOTE = 'review:round2 printed no decision josh ship can read:'
49
46
  const COMMENT_FLAG = '--comment'
50
47
 
51
- type Round = typeof ROUND_ONE | typeof ROUND_TWO
52
48
  const FIXED_JOIN_NOTE =
53
49
  'the round-1 gate read the tree before the review fixes — drained, not judged; the gate re-runs once the tree is fixed.'
54
50
  const ROUND_TWO_SKIPPED_NOTE = 'round 2 not due — nothing left to verify; shipping on.'
@@ -58,99 +54,21 @@ const ROUND_ONE_RECORDED_NOTE =
58
54
  // The scoped pair's precondition, met by the supervisor itself rather than stopped on,
59
55
  // single-sourced with the preflight and gate stages.
60
56
  const { run_phases, scoped_pair } = run_ship_scoped
61
-
62
- type PromptOf = (brief_path: string, findings_path: string, issue: string) => string
63
-
64
- function failure(out: string): JoshResult {
65
- return { code: FAILURE_EXIT_CODE, out }
66
- }
67
-
68
- function paths(): { brief: string; findings: string; log: string } {
69
- return lane_session_broker.review_paths(PROJECT_ROOT)
70
- }
71
-
72
- async function josh(argv: ReadonlyArray<string>): Promise<JoshResult> {
73
- return await josh_command.josh_run(argv, should_forward_stderr)
74
- }
75
-
76
- function note(text: string): void {
77
- process.stderr.write(`${text}\n`)
78
- }
79
-
80
- // Under the round's reviewer profile — the same model and effort (`JOSH_REVIEWER_*` included) the
81
- // chain's subagent is given — and waited on, so the join below runs only once the review has finished.
82
- // Each call is its own process, so round 2 is a fresh session by construction.
83
- async function run_direct_session(
84
- argv: AgentArgv,
85
- profile: AgentProfile,
86
- log_path: string,
87
- round: Round,
88
- ): Promise<JoshResult> {
89
- const request = { argv, cwd: PROJECT_ROOT, log_path, profile }
90
-
91
- note(agent_role_profile.describe_review(Number(round), profile))
92
- const result = await detached_launch.launch_attached(request, note)
93
-
94
- if (result.kind === 'failed') return failure(`reviewer could not start: ${result.note}`)
95
- if (result.exit_code !== SUCCESS_EXIT_CODE) return failure(`reviewer failed — log: ${log_path}`)
96
-
97
- return { code: SUCCESS_EXIT_CODE, out: '' }
98
- }
99
-
100
- // A lane child's reviewer is started by the lane's broker: an OpenAI lane's always, since a nested Codex
101
- // cannot write outside its sandbox, and a Claude lane's whenever the `run:wake` supervisor serves it, since this
102
- // ship was started from the child's Bash tool and so never received a token-only credential
103
- // (joshuafolkken/kit#3817). A Claude lane nobody serves starts the reviewer itself, as before.
104
- function is_brokered(profile: AgentProfile, issue: string): boolean {
105
- if (!lane_child_marker.is_child_of(PROJECT_ROOT)) return false
106
-
107
- return profile.provider === 'openai' || lane_session_broker.is_serving(PROJECT_ROOT, issue)
108
- }
109
-
110
- async function run_session(
111
- prompt: string,
112
- log_path: string,
113
- issue: string,
114
- round: Round,
115
- ): Promise<JoshResult> {
116
- const built = agent_argv.review_in(prompt, Number(round), PROJECT_ROOT)
117
- if (built.kind === 'rejected') return failure(`reviewer profile rejected: ${built.note}`)
118
-
119
- if (!is_brokered(built.profile, issue)) {
120
- return await run_direct_session(built.argv, built.profile, log_path, round)
121
- }
122
-
123
- const answer = await lane_session_broker.request(PROJECT_ROOT, issue, { kind: 'review', round })
124
-
125
- return answer.is_success
126
- ? { code: SUCCESS_EXIT_CODE, out: '' }
127
- : failure(`isolated reviewer failed: ${answer.reason}`)
128
- }
129
-
130
- // The brief goes to a file and the previous round's findings are removed, so a reviewer that writes
131
- // nothing reads as unfinished rather than as the last round's verdict.
132
- async function launch_reviewer(
133
- brief: string,
134
- prompt_of: PromptOf,
135
- issue: string,
136
- round: Round,
137
- ): Promise<JoshResult> {
138
- const target = paths()
139
-
140
- stamp_file.write_text_stamp(target.brief, brief)
141
- stamp_file.remove_stamp(target.findings)
142
-
143
- return await run_session(
144
- prompt_of(target.brief, target.findings, issue),
145
- target.log,
146
- issue,
147
- round,
148
- )
149
- }
150
-
151
- function current_verdict(): ReturnType<typeof run_ship_review.read_verdict> {
152
- return run_ship_review.read_verdict(stamp_file.read_stamp_text(paths().findings))
153
- }
57
+ const { CAUSE } = run_ship_stop_cause
58
+ const {
59
+ attest_phase,
60
+ current_verdict,
61
+ failure,
62
+ josh,
63
+ note,
64
+ paths,
65
+ reviewed,
66
+ ROUND_ONE,
67
+ ROUND_TWO,
68
+ SUCCESS_EXIT_CODE,
69
+ tagged,
70
+ tagged_phase,
71
+ } = run_ship_reviewer
154
72
 
155
73
  // A red join blocks unless the reviewer fixed findings in place: the background gate then read the
156
74
  // tree before the fixes, so its verdict describes a tree that no longer exists. The join still ran to
@@ -180,57 +98,42 @@ function record_flags(round: Round, outcome: RoundOutcome): ReadonlyArray<string
180
98
  return round === ROUND_TWO && outcome.is_passing ? [COMMENT_FLAG] : []
181
99
  }
182
100
 
101
+ // `kind` is the record's own flags — `--interaction` for the interaction review's `- ri:` line.
183
102
  async function record_and_route(
184
103
  issue: string,
185
104
  round: Round,
186
105
  outcome_of: (verdict: ScoredVerdict) => RoundOutcome,
106
+ kind: ReadonlyArray<string> = [],
187
107
  ): Promise<JoshResult> {
188
108
  const verdict = current_verdict()
189
109
 
190
- if (verdict.kind === run_ship_review.VERDICT.INVALID) return failure(verdict.note)
110
+ if (verdict.kind === run_ship_review.VERDICT.INVALID) return failure(verdict.note, CAUSE.INFRA)
191
111
 
192
112
  const outcome = outcome_of(verdict)
193
- const flags = record_flags(round, outcome)
113
+ const flags = [...kind, ...record_flags(round, outcome)]
194
114
  const recorded = await josh(['review:record', '--issue', issue, ...flags, ...verdict.specs])
195
115
 
196
- if (recorded.code !== SUCCESS_EXIT_CODE) return recorded
116
+ if (recorded.code !== SUCCESS_EXIT_CODE) return tagged(CAUSE.CHECK, recorded)
197
117
 
198
118
  const out = [...verdict.report, outcome.note].join('\n')
199
119
 
200
- return outcome.is_passing ? { code: SUCCESS_EXIT_CODE, out } : failure(out)
201
- }
202
-
203
- // A brief-minting command, then a reviewer handed what it printed.
204
- function reviewed(
205
- open: ReadonlyArray<string>,
206
- prompt_of: PromptOf,
207
- issue: string,
208
- round: Round,
209
- ): ReadonlyArray<Phase> {
210
- const opened = { brief: '' }
211
-
212
- return [
213
- async () => {
214
- const result = await josh(open)
215
-
216
- opened.brief = result.out
217
-
218
- return result
219
- },
220
- async () => await launch_reviewer(opened.brief, prompt_of, issue, round),
221
- ]
120
+ return outcome.is_passing ? { code: SUCCESS_EXIT_CODE, out } : failure(out, CAUSE.FINDING)
222
121
  }
223
122
 
224
123
  // Fixes made in place are counted only once the scoped pair is green on the fixed tree. The reviewer is
225
124
  // asked to leave it green; this is the check that it did, and a fix it could not get green is routed as
226
125
  // the finding it still is — recorded, then stopped before the gate and the commit take it in.
227
- async function round_one_record(issue: string): Promise<JoshResult> {
126
+ async function round_one_record(issue: string, kind?: ReadonlyArray<string>): Promise<JoshResult> {
228
127
  const is_fixed = current_verdict().kind === run_ship_review.VERDICT.FIXED
229
128
  const checked = is_fixed ? await scoped_pair() : undefined
230
129
  const is_verified = checked === undefined || checked.code === SUCCESS_EXIT_CODE
231
130
 
232
- return await record_and_route(issue, ROUND_ONE, (verdict) =>
233
- is_verified ? run_ship_review.round_one_outcome(verdict) : run_ship_review.UNVERIFIED_OUTCOME,
131
+ return await record_and_route(
132
+ issue,
133
+ ROUND_ONE,
134
+ (verdict) =>
135
+ is_verified ? run_ship_review.round_one_outcome(verdict) : run_ship_review.UNVERIFIED_OUTCOME,
136
+ kind,
234
137
  )
235
138
  }
236
139
 
@@ -245,35 +148,86 @@ function skipped(out: string): StepResult {
245
148
  // **A recorded round 1 is not run again**. A ship relaunched with `--review`
246
149
  // after a round-1 stop would otherwise review the whole change a second time as round 1 — a new Medium
247
150
  // there stops it again, and round 2 after the commit makes a third. The fix delta is round 2's to
248
- // verify, and `round_two_stage` asks whether it is due after the commit.
249
- async function review_stage(issue: string): Promise<StepResult> {
151
+ // verify, and `round_two_stage` asks whether it is due after the commit — unless the issue changed after
152
+ // that round's brief: the recorded round then never read it, and `josh followup` refuses the merge on it
153
+ // (joshuafolkken/kit#4221).
154
+ async function round_one_stage(issue: string, is_stale: boolean): Promise<StepResult> {
250
155
  const recorded = await review_record.check(Number(issue))
251
156
 
252
- if (recorded.status === 'ok') return skipped(ROUND_ONE_RECORDED_NOTE)
157
+ if (!is_stale && recorded.status === 'ok') return skipped(ROUND_ONE_RECORDED_NOTE)
253
158
 
254
159
  return await run_phases([
255
- scoped_pair,
160
+ tagged_phase(CAUSE.CHECK, scoped_pair),
256
161
  ...reviewed([RUN_REVIEW], run_ship_review.reviewer_prompt, issue, ROUND_ONE),
257
- join_gate,
258
- async () => await josh(ATTEST_CHECK),
162
+ tagged_phase(CAUSE.CHECK, join_gate),
163
+ attest_phase,
259
164
  async () => await round_one_record(issue),
260
165
  ])
261
166
  }
262
167
 
168
+ // The interaction review (joshuafolkken/kit#4276): after round 1, over a change to the run tooling,
169
+ // scoped pair → `review:brief --interaction` → reviewer → attest → `review:record --interaction`. Its
170
+ // fixes are verified as round 1's are; no join, since round 1 already drained the gate.
171
+ async function interaction_stage(issue: string): Promise<StepResult> {
172
+ return await run_phases([
173
+ tagged_phase(CAUSE.CHECK, scoped_pair),
174
+ ...reviewed(INTERACTION_BRIEF, run_ship_review.reviewer_prompt, issue, ROUND_ONE),
175
+ attest_phase,
176
+ async () => await round_one_record(issue, [INTERACTION_FLAG]),
177
+ ])
178
+ }
179
+
180
+ // Round 1, then the interaction review where it is due and not yet recorded — so a relaunched ship
181
+ // whose round 1 is recorded still owes it. The first stop is returned as it is.
182
+ async function review_stage(issue: string, is_stale = false): Promise<StepResult> {
183
+ const first = await round_one_stage(issue, is_stale)
184
+
185
+ if (
186
+ first.code !== SUCCESS_EXIT_CODE ||
187
+ (await review_interaction.status(Number(issue))) !== 'missing'
188
+ ) {
189
+ return first
190
+ }
191
+
192
+ const second = await interaction_stage(issue)
193
+
194
+ if (second.code !== SUCCESS_EXIT_CODE) return second
195
+
196
+ return { code: SUCCESS_EXIT_CODE, out: [first.out, second.out].join('\n') }
197
+ }
198
+
263
199
  // The round-2 verification pass, after the commit so it runs beside CI: due only when the round-1 fix
264
200
  // delta says so, then scoped pair → brief → fresh reviewer → attest → record.
201
+ //
202
+ // **The decision is read as JSON and recorded in the lane ledger before it is acted on**, so
203
+ // `josh lane:stats` can count the period's round-2 runs and skips by their reason code
204
+ // (joshuafolkken/kit#4064). Output it cannot parse stops the ship rather than guessing a verdict.
265
205
  async function round_two_stage(issue: string): Promise<StepResult> {
266
206
  const decision = await josh(ROUND_TWO_DECISION)
267
- const answer = decision.out.trim()
268
207
 
269
- if (decision.code !== SUCCESS_EXIT_CODE) return decision
208
+ if (decision.code !== SUCCESS_EXIT_CODE) return tagged(CAUSE.CHECK, decision)
209
+
210
+ const answer = review_round2.parse_json(decision.out)
270
211
 
271
- if (answer !== ROUND_TWO_REQUIRED) return skipped(`${answer}\n${ROUND_TWO_SKIPPED_NOTE}`)
212
+ if (answer === undefined) {
213
+ return failure(`${UNREADABLE_DECISION_NOTE}\n${decision.out}`, CAUSE.CHECK)
214
+ }
215
+
216
+ note(answer.reason)
217
+ await lane_ledger.record_round_two({
218
+ issue: Number(issue),
219
+ verdict: answer.verdict,
220
+ code: answer.code,
221
+ })
222
+
223
+ if (answer.verdict !== review_round2.REQUIRED_VERDICT) {
224
+ return skipped(`${answer.verdict}\n${ROUND_TWO_SKIPPED_NOTE}`)
225
+ }
272
226
 
273
227
  return await run_phases([
274
- scoped_pair,
228
+ tagged_phase(CAUSE.CHECK, scoped_pair),
275
229
  ...reviewed(ROUND_TWO_BRIEF, run_ship_review.verification_prompt, issue, ROUND_TWO),
276
- async () => await josh(ATTEST_CHECK),
230
+ attest_phase,
277
231
  async () => await record_and_route(issue, ROUND_TWO, run_ship_review.round_two_outcome),
278
232
  ])
279
233
  }