@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,73 @@
1
+ import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
2
+ import { shared_cache, type CacheSlot } from '#scripts/josh/shared-cache'
3
+ import { run_event_stream } from '#scripts/run/event/run-event-stream'
4
+ import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
5
+ import { z } from 'zod'
6
+ import { backlog_next } from './backlog-next'
7
+
8
+ // One `josh backlog:next` answer shared by every reader that asks it within a minute
9
+ // (joshuafolkken/kit#4550).
10
+ //
11
+ // **The drive's assignment and the arrival probe each ask every minute, and since a lane waiting on its
12
+ // merge frees its slot (joshuafolkken/kit#4483) a free slot is the usual state** — so both read the
13
+ // whole pool from GitHub every minute, for the same answer.
14
+ //
15
+ // **The key carries the newest event on the run's stream**, so a launch, a merge or a park — anything
16
+ // that can change what may start — is never answered from before it: the first ask after it reads
17
+ // again. Only an answer that read is kept; a failure or a `retry` is asked again by the next reader.
18
+
19
+ const SUCCESS_EXIT_CODE = 0
20
+
21
+ const NEXT_CACHE: CacheSlot = { prefix: 'josh-backlog-next-', ttl_ms: 60_000 }
22
+
23
+ const result_schema = z.object({
24
+ code: z.number(),
25
+ out: z.string(),
26
+ err: z.string().exactOptional(),
27
+ })
28
+
29
+ // The key a shared plan read is kept under: what was asked, and the newest event on the run's stream.
30
+ // `run:board`'s plan read keys by it too (joshuafolkken/kit#4558).
31
+ async function stream_key(scope: unknown): Promise<string> {
32
+ const target = await run_event_stream_emit.stream_target()
33
+ const last = target === undefined ? undefined : run_event_stream.read_last(target)
34
+
35
+ return JSON.stringify({ argv: scope, last })
36
+ }
37
+
38
+ function is_kept(result: JoshResult): boolean {
39
+ if (result.code !== SUCCESS_EXIT_CODE) return false
40
+
41
+ return !result.out.split('\n').includes(backlog_next.VERDICT_TOKENS.retry)
42
+ }
43
+
44
+ // A kept answer replays its explanation where the live one would have streamed it.
45
+ function replay(result: JoshResult, should_forward_stderr: boolean): JoshResult {
46
+ if (should_forward_stderr && result.err !== undefined && result.err !== '') {
47
+ console.error(result.err)
48
+ }
49
+
50
+ return result
51
+ }
52
+
53
+ async function read(
54
+ argv: ReadonlyArray<string>,
55
+ should_forward_stderr = false,
56
+ timeout_ms?: number,
57
+ ): Promise<JoshResult> {
58
+ const key = await stream_key(argv)
59
+ const now_ms = Date.now()
60
+ const kept = shared_cache.read(NEXT_CACHE, key, result_schema, now_ms)
61
+
62
+ if (kept !== undefined) return replay(kept, should_forward_stderr)
63
+
64
+ const result = await josh_command.josh_run(argv, should_forward_stderr, timeout_ms)
65
+
66
+ if (is_kept(result)) shared_cache.write(NEXT_CACHE, key, result, now_ms)
67
+
68
+ return result
69
+ }
70
+
71
+ const backlog_next_shared = { NEXT_CACHE, read, stream_key }
72
+
73
+ export { backlog_next_shared }
@@ -1,4 +1,3 @@
1
- import { fileURLToPath } from 'node:url'
2
1
  import { auto_ok_cli, type OptedInRead, type TrackingRead } from '#scripts/auto-ok/auto-ok-cli'
3
2
  import { repo_discovery } from '#scripts/discovery/repo-discovery'
4
3
  import { epic_bundle_gaps } from '#scripts/epic/epic-bundle-gaps'
@@ -13,11 +12,16 @@ import { epic_solo_stale } from '#scripts/epic/epic-solo-stale'
13
12
  import { epic_triage, type TriageVerdict } from '#scripts/epic/epic-triage'
14
13
  import { git_gh_command } from '#scripts/gh/git-gh-command'
15
14
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
15
+ import { issue_not_before } from '#scripts/issue/issue-not-before'
16
+ import { issue_not_before_label } from '#scripts/issue/issue-not-before-label'
17
+ import { session_cite } from '#scripts/issue/session-cite'
18
+ import { lane_state } from '#scripts/lane/lane-state'
16
19
  import { issue_citation } from '#scripts/rules/issue-citation'
17
20
  import { backlog_defect_priority } from './backlog-defect-priority'
18
21
  import { backlog_overlap } from './backlog-overlap'
19
22
  import { backlog_pool } from './backlog-pool'
20
23
  import { backlog_rank, type GateScope } from './backlog-rank'
24
+ import { backlog_wait_cause } from './backlog-wait-cause'
21
25
 
22
26
  // `josh backlog:next` — what the whole opted-in backlog may run next.
23
27
  //
@@ -30,7 +34,6 @@ import { backlog_rank, type GateScope } from './backlog-rank'
30
34
  // `auto-ok:next`'s own listing and runnability rules, and the verdict comes from
31
35
  // `epic_report.decide_verdict` so it cannot drift from what `epic:next` means by the same word.
32
36
 
33
- const ARGV_OFFSET = 2
34
37
  const SUCCESS_EXIT_CODE = 0
35
38
  const FAILURE_EXIT_CODE = 1
36
39
 
@@ -130,6 +133,31 @@ function warn_gaps(context: PoolContext, has_answer: boolean): void {
130
133
  warn_epic_gap(context)
131
134
  }
132
135
 
136
+ // Why a row on the time side is not offered yet, when the reason is a declared start time or sample
137
+ // condition — the waits a reader cannot see from the labels or the blockers. A sample condition names
138
+ // its pull request as `#N`, linkified like the explanation.
139
+ function warn_not_before(context: PoolContext): void {
140
+ for (const issue of context.opted_in.issues) {
141
+ const reason = issue_not_before.waiting_reason(issue.body)
142
+
143
+ if (reason === undefined) continue
144
+
145
+ const cited = session_cite.issue(issue.number, undefined, context.repo)
146
+
147
+ console.error(`${cited} ${issue_citation.linkify(reason, context.repo)}`)
148
+ }
149
+ }
150
+
151
+ // Which waiting issues hold the backlog on a dependency chain or a start condition, read back by
152
+ // `backlog:offer` so a lane held by them is told apart in `lane:stats` (joshuafolkken/kit#4513).
153
+ function warn_wait_causes(result: EpicNextResult, context: PoolContext): void {
154
+ const causes = backlog_wait_cause.classify(result.waiting, context.repo)
155
+
156
+ for (const line of backlog_wait_cause.lines_of(causes)) {
157
+ console.error(issue_citation.linkify(line, context.repo))
158
+ }
159
+ }
160
+
133
161
  function report(result: EpicNextResult, context: PoolContext): number {
134
162
  warn_gaps(context, result.verdict === 'run')
135
163
  // The explanation names epics and children as `#N` (`tracked by epic #N`); linkified so the text a
@@ -139,8 +167,12 @@ function report(result: EpicNextResult, context: PoolContext): number {
139
167
  const explanation = epic_report.format_result(result, context.repo)
140
168
 
141
169
  console.error(issue_citation.linkify(explanation, context.repo))
170
+ warn_not_before(context)
142
171
 
143
- for (const token of tokens_of(result, context.repo)) console.info(token)
172
+ const tokens = tokens_of(result, context.repo)
173
+
174
+ if (tokens[0] === VERDICT_TOKENS.wait) warn_wait_causes(result, context)
175
+ for (const token of tokens) console.info(token)
144
176
 
145
177
  return SUCCESS_EXIT_CODE
146
178
  }
@@ -297,11 +329,15 @@ function standalone_keys(context: PoolContext): ReadonlySet<string> {
297
329
 
298
330
  // The running lanes still carry the pickup label, so the opted-in listing holds their bodies too —
299
331
  // which is what lets a candidate be held back from a path a running lane already declares.
300
- // `backlog:plan --waves` reads the same scope, so its first wave is this offer.
301
- function gate_scope(context: PoolContext): GateScope {
332
+ // `backlog:plan --waves` reads the same scope, so its first wave is this offer. Their lane state
333
+ // records name a paused holder in the wait it causes (joshuafolkken/kit#4270); they are local files.
334
+ async function gate_scope(context: PoolContext): Promise<GateScope> {
335
+ const { issues } = context.opted_in
336
+
302
337
  return {
303
338
  standalone: standalone_keys(context),
304
- declared: backlog_overlap.declared_of(context.opted_in.issues),
339
+ declared: backlog_overlap.declared_of(issues),
340
+ lanes: await lane_state.read_states(issues.map((issue) => String(issue.number))),
305
341
  }
306
342
  }
307
343
 
@@ -320,7 +356,7 @@ async function gate_solo(result: EpicNextResult, context: PoolContext): Promise<
320
356
 
321
357
  if (notice !== undefined) console.error(notice)
322
358
 
323
- const gated = backlog_rank.gate(result, read, repo, gate_scope(context))
359
+ const gated = backlog_rank.gate(result, read, repo, await gate_scope(context))
324
360
 
325
361
  if (gated.notice !== undefined) console.error(gated.notice)
326
362
 
@@ -393,6 +429,11 @@ async function context_of(
393
429
  }
394
430
 
395
431
  async function answer(opted_in: OptedIn, exclude: ReadonlyArray<number>): Promise<number> {
432
+ // The scan has every opted-in body and its labels already, so it keeps `not-before` in line with them
433
+ // and with every other issue the label is on — before any answer, so a drained backlog or a failed
434
+ // read still takes a passed label off.
435
+ await issue_not_before_label.sweep(opted_in.issues)
436
+
396
437
  if (opted_in.issues.length === 0) return report_none()
397
438
 
398
439
  const context = await context_of(opted_in, exclude)
@@ -422,13 +463,6 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
422
463
  return await answer(opted_in, options.exclude ?? [])
423
464
  }
424
465
 
425
- // `process.exitCode` rather than `process.exit()`, for the reason `auto-ok:next` records: the whole
426
- // contract is `answers=$(pnpm josh backlog:next)`, and exiting outright can cut the pipe before it
427
- // has drained.
428
- async function main(argv: ReadonlyArray<string>): Promise<void> {
429
- process.exitCode = await run(argv)
430
- }
431
-
432
466
  const backlog_next = {
433
467
  USAGE,
434
468
  REPO_UNREADABLE_MESSAGE,
@@ -441,7 +475,5 @@ const backlog_next = {
441
475
  run,
442
476
  }
443
477
 
444
- if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
445
-
446
478
  export { backlog_next }
447
479
  export type { BacklogVerdict, OptedIn, PoolContext }
@@ -0,0 +1,69 @@
1
+ import type { LaneInfo } from '#scripts/lane/lane-registry'
2
+ import type { LaneRecords } from '#scripts/lane/lane-state'
3
+
4
+ // The open lanes that hold a place under the lane limit — the one count `lane:limit`, the drive and
5
+ // `run:board` all subtract from it.
6
+ //
7
+ // **A lane with no child working in it holds no place, whatever it waits on** (joshuafolkken/kit#4107).
8
+ // The limit caps the load on the machine, and a lane whose child is gone puts none on it — parked,
9
+ // blocked by another issue, waiting on a decision, or left by an earlier run (joshuafolkken/kit#3967,
10
+ // #4028). Its tree, branch and port seat stay; when its issue is picked up again the drive seats it
11
+ // ahead of a fresh launch, inside the free lanes (`backlog-drive-seats.ts`).
12
+ //
13
+ // **A paused lane holds no place either** (joshuafolkken/kit#4201): a child `lane:pause` suspended
14
+ // puts no load on the machine until it is resumed. **Paused is the lane state record's answer alone**
15
+ // (joshuafolkken/kit#4270) — the `ps` state is not read — so a lane only `lane:pause` paused is
16
+ // uncounted. Its memory stays held, which the free-memory check reads as measured
17
+ // (`backlog-drive-memory.ts`); `lane:prune` still keeps it, since a child is there (`lane-spent.ts`).
18
+ //
19
+ // **A lane with no record is unknown, and keeps its place**, so the count errs toward fewer free
20
+ // lanes. **Whether a child is there at all is not the record's**:
21
+ // a child that parks or dies writes nothing, so only pgrep's own "no match" (`PROCESS_NONE`,
22
+ // `lane_spent.idle_lanes`) clears a lane, and a probe that did not answer keeps it. A stranded lane has
23
+ // no tree to work in and holds no place either. The reads stay local — no issue label is read —
24
+ // because the count gates the network read behind it (`backlog-ready.ts`).
25
+ //
26
+ // **A lane whose detached ship waits on its merge holds no place either** (joshuafolkken/kit#4466). The
27
+ // child ended at the hand-off, and while `josh followup` runs the supervisor only polls CI, CodeRabbit
28
+ // and the merge, so the slot is free for the next launch while every merge check still runs. The wait is
29
+ // unmarked while the followup stage merges and gates again (`run-ship-sync.ts`); a stop there counts
30
+ // the lane again, and past the limit the supervisor waits for a place before it relaunches the child
31
+ // (`run-ship-return.ts`). A named epic's offer discounts the same lanes (`epic-lane-offer.ts`).
32
+
33
+ // The issues whose lane has no child working in it (`lane_spent.idle_lanes`).
34
+ type IdleRead = (lanes: ReadonlyArray<LaneInfo>) => ReadonlyArray<string>
35
+ // Whether the lane of an issue has a detached ship waiting on its merge (`lane_handoff.merge_wait_reader`).
36
+ type MergeWaitRead = (issue: string) => boolean
37
+
38
+ function is_never_merge_waiting(): boolean {
39
+ return false
40
+ }
41
+
42
+ function occupied_lanes(
43
+ lanes: ReadonlyArray<LaneInfo>,
44
+ idle: IdleRead,
45
+ records: LaneRecords,
46
+ is_merge_waiting: MergeWaitRead = is_never_merge_waiting,
47
+ ): Array<LaneInfo> {
48
+ const live = lanes.filter((lane) => !lane.is_stranded)
49
+ const idle_issues = new Set(idle(live))
50
+
51
+ return live.filter(
52
+ (lane) =>
53
+ !idle_issues.has(lane.issue) &&
54
+ records.get(lane.issue)?.state !== 'paused' &&
55
+ !is_merge_waiting(lane.issue),
56
+ )
57
+ }
58
+
59
+ /** The issues of the live lanes in `lanes` that have no state record. */
60
+ function unknown_lanes(lanes: ReadonlyArray<LaneInfo>, records: LaneRecords): Array<string> {
61
+ return lanes
62
+ .filter((lane) => !lane.is_stranded && !records.has(lane.issue))
63
+ .map((lane) => lane.issue)
64
+ }
65
+
66
+ const backlog_occupied = { occupied_lanes, unknown_lanes }
67
+
68
+ export { backlog_occupied }
69
+ export type { IdleRead, MergeWaitRead }
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env tsx
2
- import { fileURLToPath } from 'node:url'
3
1
  import { josh_command } from '#scripts/josh/josh-run'
4
2
  import { cli_flags } from '#scripts/lib/cli-flags'
5
3
  import { json_value } from '#scripts/lib/json-value'
@@ -7,6 +5,7 @@ import { rule_value_cache } from '#scripts/rules/rule-value-cache'
7
5
  import { run_event_stream } from '#scripts/run/event/run-event-stream'
8
6
  import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
9
7
  import { z } from 'zod'
8
+ import { backlog_next_shared } from './backlog-next-shared'
10
9
  import { backlog_offer, type OfferAnswer } from './backlog-offer'
11
10
 
12
11
  // `josh backlog:offer` — one composite command for a `backlogrun` loop-head event.
@@ -21,7 +20,6 @@ import { backlog_offer, type OfferAnswer } from './backlog-offer'
21
20
  // and in the `--json` object; every explanation `backlog:next` and `backlog:budget` print is streamed
22
21
  // straight through to stderr.
23
22
 
24
- const ARGV_OFFSET = 2
25
23
  const SUCCESS_EXIT_CODE = 0
26
24
  const FAILURE_EXIT_CODE = 1
27
25
  const JSON_KEY = 'offer'
@@ -36,7 +34,6 @@ const EXHAUSTED_ANSWER = 'exhausted'
36
34
  const NO_RUNNING = 0
37
35
  const DRAIN_TEXT = 'backlog drained'
38
36
  const should_forward_stderr = true
39
- const COUNT_PATTERN = /^\d+$/u
40
37
 
41
38
  const USAGE =
42
39
  'Usage: josh backlog:offer --started <ISO-8601> [--active <ISO-8601>] [--merged <n>] [--running <n>] [--max <n>] [--idle <minutes>] [--retries <n>] [--exclude <n>[,<n>...]]... [--repo <owner/repo>] [--json]'
@@ -65,18 +62,10 @@ function read_values(argv: ReadonlyArray<string>): ParsedValues | undefined {
65
62
  return cli_flags.values_of(argv, OPTIONS)
66
63
  }
67
64
 
68
- function to_count(raw: string | undefined): number | undefined {
69
- if (raw === undefined || !COUNT_PATTERN.test(raw)) return undefined
70
-
71
- const parsed = Number(raw)
72
-
73
- return Number.isSafeInteger(parsed) ? parsed : undefined
74
- }
75
-
76
65
  // A count flag that was given but unreadable makes the invocation unreadable rather than defaulted —
77
66
  // the contract `backlog:budget` follows for its own counts.
78
67
  function count_of(raw: string | undefined): number | undefined {
79
- return raw === undefined ? DEFAULT_COUNT : to_count(raw)
68
+ return raw === undefined ? DEFAULT_COUNT : cli_flags.to_count(raw)
80
69
  }
81
70
 
82
71
  interface OfferCounts {
@@ -159,6 +148,8 @@ function emit(decision: BudgetRead, offer: OfferAnswer, is_json: boolean): numbe
159
148
  verdict,
160
149
  issues,
161
150
  answer: offer.answer,
151
+ cause: offer.cause,
152
+ waiting: offer.waiting,
162
153
  retries: offer.retries,
163
154
  reason,
164
155
  is_finish,
@@ -198,9 +189,9 @@ async function mark_drain(verdict: string, answer: string, running: number): Pro
198
189
  }
199
190
 
200
191
  async function decide(values: ParsedValues, counts: OfferCounts): Promise<number> {
201
- const next = await josh_command.josh_run(next_argv(values), should_forward_stderr)
192
+ const next = await backlog_next_shared.read(next_argv(values), should_forward_stderr)
202
193
  const offer = backlog_offer.answer_of(
203
- { code: next.code, tokens: to_tokens(next.out) },
194
+ { code: next.code, tokens: to_tokens(next.out), err: next.err },
204
195
  counts.running,
205
196
  counts.retries,
206
197
  )
@@ -239,10 +230,6 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
239
230
  return await decide(values, counts)
240
231
  }
241
232
 
242
- async function main(argv: ReadonlyArray<string>): Promise<void> {
243
- process.exitCode = await run(argv)
244
- }
245
-
246
233
  const backlog_offer_cli = {
247
234
  JSON_KEY,
248
235
  budget_argv,
@@ -252,7 +239,5 @@ const backlog_offer_cli = {
252
239
  run,
253
240
  }
254
241
 
255
- if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
256
-
257
242
  export { backlog_offer_cli }
258
243
  export type { ParsedValues }
@@ -0,0 +1,15 @@
1
+ const LIST_SEPARATOR = ','
2
+
3
+ // **A child in flight is never offered**, nor a settled one `backlog:next` still reads OPEN — merged, or
4
+ // withdrawn from this run (joshuafolkken/kit#4365). The drive builds this list from its state and the
5
+ // stall detector from the event stream (joshuafolkken/kit#4349); both go through here. Kept free of the
6
+ // drive's imports so a reader of the stream does not load it.
7
+ function exclude_of(settled: Iterable<string>, in_flight: Iterable<string>): ReadonlyArray<string> {
8
+ return [...new Set([...settled, ...in_flight])]
9
+ }
10
+
11
+ function exclude_argv(exclude: ReadonlyArray<string>): ReadonlyArray<string> {
12
+ return exclude.length === 0 ? [] : ['--exclude', exclude.join(LIST_SEPARATOR)]
13
+ }
14
+
15
+ export const backlog_offer_exclude = { exclude_argv, exclude_of }
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { backlog_offer_cli } from './backlog-offer-cli'
4
+
5
+ // The `josh backlog:offer` entry, kept apart from `backlog-offer-cli.ts` because other modules import
6
+ // that one: a bundle is one file, so a main guard there would fire for every command that carries it
7
+ // (joshuafolkken/kit#4186).
8
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
9
+ const ARGV_OFFSET = 2
10
+
11
+ process.exitCode = await backlog_offer_cli.run(process.argv.slice(ARGV_OFFSET))
12
+ }
@@ -1,6 +1,8 @@
1
+ import { epic_solo } from '#scripts/epic/epic-solo'
1
2
  import { issue_number_shape } from '#scripts/issue/issue-number-shape'
2
3
  import type { BacklogAnswer } from './backlog-budget'
3
4
  import { backlog_next } from './backlog-next'
5
+ import { backlog_wait_cause } from './backlog-wait-cause'
4
6
 
5
7
  // The mechanical half of `josh backlog:offer`: turn what `backlog:next`
6
8
  // answered — its stdout tokens and its exit code — into the one word `backlog:budget` is then asked
@@ -21,10 +23,15 @@ const NO_RETRIES = 0
21
23
 
22
24
  const TOKENS = backlog_next.VERDICT_TOKENS
23
25
 
24
- // `backlog:next`'s captured result: the exit code, and the trimmed stdout as one token per line.
26
+ const BLOCKED_ANSWER = 'blocked'
27
+ const SOLO_CAUSE = 'solo'
28
+
29
+ // `backlog:next`'s captured result: the exit code, the trimmed stdout as one token per line, and the
30
+ // stderr its explanations went to.
25
31
  interface NextRead {
26
32
  code: number
27
33
  tokens: ReadonlyArray<string>
34
+ err?: string | undefined
28
35
  }
29
36
 
30
37
  interface OfferAnswer {
@@ -32,6 +39,12 @@ interface OfferAnswer {
32
39
  issues: ReadonlyArray<string>
33
40
  // The consecutive-retry count after this ask — reset to zero by any answer that is not `retry`.
34
41
  retries: number
42
+ // Why a `wait` answer started nothing, where `backlog:next` said: `solo` for the `run:solo` gate,
43
+ // so `lane:stats` rows that wait apart from every other one (joshuafolkken/kit#4396); `chain`,
44
+ // `gate` or `chain+gate` for the waits `backlog-wait-cause.ts` names (joshuafolkken/kit#4513).
45
+ cause?: string
46
+ // The issues a `chain` / `gate` cause waited on, recorded with the hold.
47
+ waiting?: ReadonlyArray<number> | undefined
35
48
  }
36
49
 
37
50
  // The verdict words that map to one answer regardless of context. `wait` and `retry` are the two that
@@ -46,7 +59,7 @@ const VERDICT_ANSWERS: Readonly<Record<string, BacklogAnswer>> = {
46
59
  // `wait` is `blocked` while this run has children in flight and `exhausted` when it does not — the
47
60
  // mapping `backlog:budget` states, decided from the running count alone.
48
61
  function wait_answer(running: number): BacklogAnswer {
49
- return running > 0 ? 'blocked' : 'exhausted'
62
+ return running > 0 ? BLOCKED_ANSWER : 'exhausted'
50
63
  }
51
64
 
52
65
  // An unrecognized token is read as `unreadable` rather than guessed at: an answer the loop cannot
@@ -73,6 +86,24 @@ function is_numbers(tokens: ReadonlyArray<string>): boolean {
73
86
  return tokens.length > 0 && tokens.every((token) => issue_number_shape.is_issue_number(token))
74
87
  }
75
88
 
89
+ // What `backlog:next`'s stderr says a blocked wait was for: the `run:solo` gate's notice first, then
90
+ // the waiting issues' causes, or nothing when it names neither.
91
+ function blocked_cause(error: string): Pick<OfferAnswer, 'cause' | 'waiting'> {
92
+ if (epic_solo.is_solo_wait(error)) return { cause: SOLO_CAUSE }
93
+
94
+ const causes = backlog_wait_cause.parse(error)
95
+ const tag = backlog_wait_cause.tag_of(causes)
96
+
97
+ return tag === undefined ? {} : { cause: tag, waiting: backlog_wait_cause.numbers_of(causes) }
98
+ }
99
+
100
+ // A `wait` answer marked with its cause. An `exhausted` wait is marked too: the idle watch it opens
101
+ // holds a free lane as long as a `blocked` one, and a hold with nothing in flight here (a start date,
102
+ // or a blocker another session runs) is still that wait, not an empty backlog.
103
+ function with_cause(offer: OfferAnswer, token: string, error: string): OfferAnswer {
104
+ return token === TOKENS.wait ? { ...offer, ...blocked_cause(error) } : offer
105
+ }
106
+
76
107
  // **Read the exit code before the tokens.** Exit 1 is "the listing could not be read", which is never
77
108
  // an empty backlog — reading it as `none` would report an emptiness that was never seen, so it maps to
78
109
  // `unreadable`, and a stray stdout line on that path cannot be mistaken for an issue number.
@@ -85,7 +116,9 @@ function answer_of(read: NextRead, running: number, retries: number): OfferAnswe
85
116
  return { answer: 'candidates', issues: read.tokens, retries: NO_RETRIES }
86
117
  }
87
118
 
88
- return from_verdict(read.tokens[0] ?? '', running, retries)
119
+ const token = read.tokens[0] ?? ''
120
+
121
+ return with_cause(from_verdict(token, running, retries), token, read.err ?? '')
89
122
  }
90
123
 
91
124
  const backlog_offer = { RETRY_LIMIT, answer_of, verdict_answer, wait_answer }
@@ -2,6 +2,7 @@ import type { BusyRead } from '#scripts/epic/epic-busy'
2
2
  import type { EpicChild } from '#scripts/epic/epic-graph'
3
3
  import type { SoloSelection } from '#scripts/epic/epic-solo'
4
4
  import { session_cite } from '#scripts/issue/session-cite'
5
+ import { lane_state, type LaneRecords } from '#scripts/lane/lane-state'
5
6
 
6
7
  // Which candidates may not run side by side because their bodies declare overlapping paths.
7
8
  // joshuafolkken/kit#3221 held back only a path both bodies named beside a move, split, rename or
@@ -76,6 +77,8 @@ function overlaps(left: string, right: string): boolean {
76
77
  interface SeparateContext {
77
78
  read: BusyRead
78
79
  repo: string
80
+ // The holders' lane state records, so a clash names a paused holder (joshuafolkken/kit#4270).
81
+ lanes?: LaneRecords | undefined
79
82
  }
80
83
 
81
84
  // The path each of `holders` declares, mapped to the issue that holds it.
@@ -130,15 +133,29 @@ function running_clash(child: EpicChild, declared: Declared, holding: Holding):
130
133
  return clash_of(claims, paths_of(child, declared, holding.repo))
131
134
  }
132
135
 
133
- function clash_note(child: EpicChild, clash: Clash): string {
136
+ // Whether `waiting` declares a path `holder` declares — the overlap `separate` withholds it on.
137
+ function holds(declared: Declared, holder: number, waiting: number): boolean {
138
+ return clash_of(claims_of(declared, [holder]), declared.get(waiting) ?? new Set()) !== undefined
139
+ }
140
+
141
+ // ` — paused since 01:28 by lane:pause` for a holder whose lane is paused: it holds the path while
142
+ // nothing moves, so the wait lasts until someone resumes it.
143
+ function paused_tail(clash: Clash, lanes: LaneRecords): string {
144
+ const note = lane_state.paused_note(lanes.get(String(clash.holder)))
145
+
146
+ return note === undefined ? '' : ` — ${note}`
147
+ }
148
+
149
+ function clash_note(child: EpicChild, clash: Clash, lanes: LaneRecords): string {
134
150
  const waiting = session_cite.issue(child.number, undefined, child.repo)
135
151
  const holder = session_cite.issue(clash.holder, undefined, child.repo)
136
152
 
137
- return `${waiting} waits: its \`${clash.path}\` overlaps \`${clash.claimed}\`, which ${holder} declares.`
153
+ return `${waiting} waits: its \`${clash.path}\` overlaps \`${clash.claimed}\`, which ${holder} declares${paused_tail(clash, lanes)}.`
138
154
  }
139
155
 
140
156
  interface Walk {
141
157
  claims: Map<string, number>
158
+ lanes: LaneRecords
142
159
  offered: Array<EpicChild>
143
160
  withheld: Array<EpicChild>
144
161
  notes: Array<string>
@@ -155,7 +172,7 @@ function visit(walk: Walk, child: EpicChild, paths: ReadonlySet<string>): void {
155
172
  }
156
173
 
157
174
  walk.withheld.push(child)
158
- walk.notes.push(clash_note(child, clash))
175
+ walk.notes.push(clash_note(child, clash, walk.lanes))
159
176
  }
160
177
 
161
178
  function merged_notice(
@@ -176,6 +193,7 @@ function separate(
176
193
  ): SoloSelection {
177
194
  const walk: Walk = {
178
195
  claims: running_claims(declared, context.read),
196
+ lanes: context.lanes ?? new Map(),
179
197
  offered: [],
180
198
  withheld: [],
181
199
  notes: [],
@@ -189,7 +207,7 @@ function separate(
189
207
  return { offered: walk.offered, withheld, ...(notice !== undefined && { notice }) }
190
208
  }
191
209
 
192
- const backlog_overlap = { declared_of, declared_paths, running_clash, separate }
210
+ const backlog_overlap = { declared_of, declared_paths, holds, running_clash, separate }
193
211
 
194
212
  export { backlog_overlap }
195
213
  export type { Clash, Declared }
@@ -4,6 +4,7 @@ import type { EpicNextResult } from '#scripts/epic/epic-report'
4
4
  import { git_gh_command } from '#scripts/gh/git-gh-command'
5
5
  import { open_issue_schema, type OpenIssueData } from '#scripts/git/git-schemas'
6
6
  import { read_json_listing } from '#scripts/git/parse-json-array'
7
+ import { issue_sample_gate } from '#scripts/issue/issue-sample-gate'
7
8
  import { backlog_next, type OptedIn } from './backlog-next'
8
9
  import type { PlanContext } from './backlog-plan'
9
10
  import type { GateScope } from './backlog-rank'
@@ -60,7 +61,7 @@ async function classify(
60
61
  repo: context.repo,
61
62
  exclude,
62
63
  tracked: epic_index.withheld_children(context.tracking.index, context.opted_in.issues),
63
- scope: backlog_next.gate_scope(context),
64
+ scope: await backlog_next.gate_scope(context),
64
65
  }
65
66
  }
66
67
 
@@ -74,7 +75,10 @@ async function fetch_open(): Promise<OpenListing | undefined> {
74
75
 
75
76
  const read = read_json_listing(json, open_issue_schema)
76
77
 
77
- return read.kind === 'read' ? { rows: read.rows, is_capped } : undefined
78
+ if (read.kind !== 'read') return undefined
79
+ await issue_sample_gate.prime(read.rows.map((row) => row.body))
80
+
81
+ return { rows: read.rows, is_capped }
78
82
  }
79
83
 
80
84
  // A cut listing cannot say an issue is closed, only that it was not read — so the blocker filter is
@@ -4,7 +4,12 @@ import { epic_report, type EpicNextResult } from '#scripts/epic/epic-report'
4
4
  import { epic_solo } from '#scripts/epic/epic-solo'
5
5
  import { epic_triage } from '#scripts/epic/epic-triage'
6
6
  import { issue_cite } from '#scripts/issue/issue-cite'
7
- import { has_label_name, IN_PROGRESS_LABEL, RUN_SOLO_LABEL } from '#scripts/issue/issue-labels'
7
+ import {
8
+ has_label_name,
9
+ IN_PROGRESS_LABEL,
10
+ PARKED_LABELS,
11
+ RUN_SOLO_LABEL,
12
+ } from '#scripts/issue/issue-labels'
8
13
  import type { OutOfScopeRow } from './backlog-scope'
9
14
 
10
15
  // The plan a person reads before a `backlogrun` starts.
@@ -30,8 +35,9 @@ const ONLY_NAMED_HEADING =
30
35
  const READY_HEADING =
31
36
  'Ready now — each takes a free lane in its repository, so these may run in parallel:'
32
37
  const WAITING_HEADING = 'Waiting — each names what it is waiting on:'
33
- const HUMAN_HEADING =
34
- 'Waiting on a person (`needs-decision`) — resolve these before the run starts:'
38
+ // Every park label (`PARKED_LABELS`) puts a child here, so the heading names none and each row names
39
+ // its own: a `run:stalled` row read as `needs-decision` sends a person to decide a mechanical failure.
40
+ const HUMAN_HEADING = 'Waiting on a person — resolve these before the run starts:'
35
41
  const SCOPE_HEADING = 'Out of scope — open, but the backlog will not run these:'
36
42
  // `epic_report`'s own words for the same condition, so the plan and the run name it identically.
37
43
  const UNUSABLE_HEADING = 'The dependency graph is unusable, so there is no plan:'
@@ -150,6 +156,14 @@ function child_lines(
150
156
  return children.map((child) => row_of(child, context, note(child)))
151
157
  }
152
158
 
159
+ // The park labels a child carries, so its row says what the person is asked for.
160
+ function park_note(child: EpicChild): string {
161
+ return [...PARKED_LABELS]
162
+ .filter((label) => has_label_name(child.labels, label))
163
+ .map((label) => `\`${label}\``)
164
+ .join(', ')
165
+ }
166
+
153
167
  // A section whose rows say nothing beyond naming the issue: being under the heading is the whole
154
168
  // statement.
155
169
  function no_note(): string {
@@ -239,7 +253,7 @@ function format_plan(
239
253
  '',
240
254
  section(WAITING_HEADING, waiting_lines(result.waiting, context)),
241
255
  '',
242
- section(HUMAN_HEADING, child_lines(result.blocked_on_people, context, no_note)),
256
+ section(HUMAN_HEADING, child_lines(result.blocked_on_people, context, park_note)),
243
257
  '',
244
258
  section(SCOPE_HEADING, scope_lines(out_of_scope, context.repo)),
245
259
  ].join('\n')