@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
@@ -7,12 +7,7 @@ import type { EpicView } from '#scripts/epic/epic-next-views'
7
7
  import { epic_outside_blocker } from '#scripts/epic/epic-outside-blocker'
8
8
  import type { OpenIssueData } from '#scripts/git/git-schemas'
9
9
  import { git_next_issues } from '#scripts/issue/git-next-issues'
10
- import {
11
- ALREADY_DONE_LABEL,
12
- EPIC_LABEL,
13
- has_any_label,
14
- NEEDS_DECISION_LABEL,
15
- } from '#scripts/issue/issue-labels'
10
+ import { EPIC_LABEL, has_any_label, PARKED_LABELS } from '#scripts/issue/issue-labels'
16
11
 
17
12
  // The candidate pool `josh backlog:next` answers from.
18
13
  //
@@ -25,11 +20,12 @@ import {
25
20
 
26
21
  const EPIC_LABELS: ReadonlySet<string> = new Set([EPIC_LABEL])
27
22
  // The labels that put a withheld row in the "needs a person" bucket rather than the "waiting on
28
- // time" one. `already-done` belongs with `needs-decision` because no amount of waiting moves it: the
29
- // work is merged and the close is Tier C, so a person is the only thing that resolves it.
23
+ // time" one are the park labels (`PARKED_LABELS`). `already-done` and `run:stalled` belong with
24
+ // `needs-decision` because no amount of waiting moves them: the work is merged and the close is Tier C,
25
+ // or a mechanical cause has to be fixed, so a person is the only thing that resolves it.
30
26
  // Read as `time`, it would be reported as something that resolves itself
31
- // and nobody would ever be told to close it.
32
- const DECISION_LABELS: ReadonlySet<string> = new Set([NEEDS_DECISION_LABEL, ALREADY_DONE_LABEL])
27
+ // and nobody would ever be told to act on it.
28
+ const DECISION_LABELS: ReadonlySet<string> = PARKED_LABELS
33
29
 
34
30
  // What decides whether a standalone row is offered: the children an opted-in epic is going to offer
35
31
  // instead, the ones the caller has named as done, and the repository the rows belong to.
@@ -140,6 +136,9 @@ function settle_standalone(
140
136
  // `epic_issue.blocker_references_of` is the epic side's own resolution —
141
137
  // `repository_url` when the node names one, this repository only as the fallback an unqualified
142
138
  // relation has always meant — and it is reused rather than repeated.
139
+ //
140
+ // The body rides along as an epic child's does, so a declared start time (`issue-not-before.ts`)
141
+ // reaches the classification and the board's waiting row for a standalone row too (#4014).
143
142
  function to_child(issue: OpenIssueData, repo: string): EpicChild {
144
143
  return {
145
144
  number: issue.number,
@@ -147,6 +146,7 @@ function to_child(issue: OpenIssueData, repo: string): EpicChild {
147
146
  state: 'OPEN',
148
147
  labels: (issue.labels ?? []).map((label) => label.name),
149
148
  blocked_by: epic_issue.blocker_references_of(issue, repo),
149
+ body: issue.body,
150
150
  }
151
151
  }
152
152
 
@@ -4,6 +4,7 @@ import { epic_rank } from '#scripts/epic/epic-rank'
4
4
  import type { EpicNextResult } from '#scripts/epic/epic-report'
5
5
  import { epic_solo, type SoloGate, type SoloSelection } from '#scripts/epic/epic-solo'
6
6
  import { git_next_issues } from '#scripts/issue/git-next-issues'
7
+ import type { LaneRecords } from '#scripts/lane/lane-state'
7
8
  import { backlog_overlap, type Declared } from './backlog-overlap'
8
9
 
9
10
  // What the backlog offers, in the order it is decided: rank, then the
@@ -82,15 +83,21 @@ interface OfferInput {
82
83
  // The paths each issue declares; two candidates whose paths overlap are not offered together.
83
84
  // Absent, nothing is separated.
84
85
  declared?: Declared
86
+ // The issues' lane state records; a clash with a paused holder says so. Absent, none is named.
87
+ lanes?: LaneRecords
85
88
  }
86
89
 
87
90
  // The overlap separation runs before the cap, for the reason the gate does: the cap only ever
88
91
  // removes what would otherwise be offered.
89
92
  function select(input: OfferInput): SoloSelection {
90
93
  const ranked = rank(input.candidates, input.pool)
91
- const { read, repo } = input
94
+ const { read, repo, lanes } = input
92
95
  const gated = epic_solo.select(ranked, read, repo)
93
- const separated = backlog_overlap.separate(gated, input.declared ?? new Map(), { read, repo })
96
+ const separated = backlog_overlap.separate(gated, input.declared ?? new Map(), {
97
+ read,
98
+ repo,
99
+ lanes,
100
+ })
94
101
 
95
102
  return cap(separated, input.standalone)
96
103
  }
@@ -98,6 +105,7 @@ function select(input: OfferInput): SoloSelection {
98
105
  interface GateScope {
99
106
  standalone: ReadonlySet<string>
100
107
  declared: Declared
108
+ lanes?: LaneRecords
101
109
  }
102
110
 
103
111
  // `backlog:next`'s gate: `epic_solo.gate` with this selection in place of its bare one.
@@ -1,11 +1,22 @@
1
1
  import { git_gh_command } from '#scripts/gh/git-gh-command'
2
2
  import { issue_cite } from '#scripts/issue/issue-cite'
3
- import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
3
+ import type { JoshResult } from '#scripts/josh/josh-run'
4
4
  import { lane_capacity } from '#scripts/lane/lane-capacity'
5
+ import { lane_process_table, type TableRead } from '#scripts/lane/lane-process-table'
5
6
  import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
7
+ import { lane_snapshot_trace } from '#scripts/lane/lane-snapshot-trace'
8
+ import { lane_spent } from '#scripts/lane/lane-spent'
9
+ import { lane_state } from '#scripts/lane/lane-state'
6
10
  import type { RunCarry } from '#scripts/run/carry/run-carry'
11
+ import { run_event_scope } from '#scripts/run/event/run-event-scope'
12
+ import { run_event_stream } from '#scripts/run/event/run-event-stream'
13
+ import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
7
14
  import { run_headless } from '#scripts/run/run-headless'
8
15
  import { run_invocation } from '#scripts/run/run-invocation'
16
+ import { backlog_drive_restore } from './backlog-drive-restore'
17
+ import { backlog_next_shared } from './backlog-next-shared'
18
+ import { backlog_occupied } from './backlog-occupied'
19
+ import { backlog_offer_exclude } from './backlog-offer-exclude'
9
20
  import { backlog_stalled } from './backlog-stalled'
10
21
 
11
22
  // The ready line reports runnable work to the driving backlogrun parent on a watcher wake.
@@ -18,28 +29,101 @@ interface ReadyReading {
18
29
  free_lanes: number
19
30
  }
20
31
 
32
+ // How many open lanes hold a place under the limit, how many hold a port seat, and the ones with no
33
+ // lane state record.
34
+ interface LaneUse {
35
+ occupied: number
36
+ seated: number
37
+ unknown: ReadonlyArray<string>
38
+ }
39
+
40
+ // The lanes that hold a place under the limit, read once for every count drawn from them.
41
+ interface LaneRoom {
42
+ occupied: ReadonlyArray<LaneInfo>
43
+ // The open lanes no child is working in, read from the same snapshot.
44
+ idle: ReadonlyArray<string>
45
+ // The open lanes with no lane state record, counted as holding a place until one is written.
46
+ unknown: ReadonlyArray<string>
47
+ use: LaneUse
48
+ }
49
+
50
+ interface LaneCount {
51
+ limit: number
52
+ free: number
53
+ }
54
+
21
55
  interface ReadyPorts {
22
56
  free_lane_count: () => Promise<number>
23
57
  ready_issues: () => Promise<ReadonlyArray<string>>
24
58
  }
25
59
 
26
- // The lanes in use: the open worktrees an interruption has not stranded. `josh lane:limit` prints it.
27
- async function live_lane_count(): Promise<number> {
28
- return lane_registry.live_count(await lane_registry.list_lanes())
60
+ // The lanes that hold a place under the limit (`backlog-occupied.ts`), the idle ones and the unknown
61
+ // ones. Paused is each lane's state record's answer; every lane's idle reading is drawn from one
62
+ // asynchronous process snapshot, so the count never blocks its caller's event loop
63
+ // (joshuafolkken/kit#4241, #4245); `run:board` passes the snapshot its redraw already read (#4246).
64
+ async function occupancy_of(
65
+ open: ReadonlyArray<LaneInfo>,
66
+ table: TableRead,
67
+ ): Promise<Omit<LaneRoom, 'use'>> {
68
+ const rows = await table()
69
+ const issues = open.map((lane) => lane.issue)
70
+ const trace = { process_trace: await lane_snapshot_trace.traces_of(issues, rows) }
71
+ const records = await lane_state.read_states(issues)
72
+ const is_merge_waiting = await lane_snapshot_trace.merge_waits_of(issues, rows)
73
+ const occupied = backlog_occupied.occupied_lanes(
74
+ open,
75
+ (live) => lane_spent.idle_lanes(live, trace),
76
+ records,
77
+ is_merge_waiting,
78
+ )
79
+ const unknown = backlog_occupied.unknown_lanes(open, records)
80
+
81
+ return { occupied, idle: lane_spent.idle_lanes(open, trace), unknown }
29
82
  }
30
83
 
31
- // Free lanes beside `lanes`, `undefined` where the limit could not be read: the count `lane:limit`
32
- // prints, and the one `run:board` draws, so the two never answer apart.
33
- async function free_lanes_beside(lanes: ReadonlyArray<LaneInfo>): Promise<number | undefined> {
84
+ // The open lanes as the free count reads them: those that hold a place under the limit, and every
85
+ // open one, since an uncounted lane still holds its port seat.
86
+ async function lane_room(
87
+ lanes?: ReadonlyArray<LaneInfo>,
88
+ table: TableRead = lane_process_table.read_table,
89
+ ): Promise<LaneRoom> {
90
+ const open = lanes ?? (await lane_registry.list_lanes())
91
+ const occupancy = await occupancy_of(open, table)
92
+ const seated = open.filter((lane) => !lane.is_stranded).length
93
+
94
+ const use = { occupied: occupancy.occupied.length, seated, unknown: occupancy.unknown }
95
+
96
+ return { ...occupancy, use }
97
+ }
98
+
99
+ async function lane_use(lanes?: ReadonlyArray<LaneInfo>): Promise<LaneUse> {
100
+ const room = await lane_room(lanes)
101
+
102
+ return room.use
103
+ }
104
+
105
+ function free_of(limit: number, use: LaneUse): number {
106
+ return lane_capacity.free_lanes(limit, use.occupied, use.seated)
107
+ }
108
+
109
+ // The limit and the free lanes in `room`, `undefined` where the limit could not be read: the count
110
+ // `lane:limit` prints, and the one `run:board` draws, so the two never answer apart.
111
+ async function count_in(room: LaneRoom): Promise<LaneCount | undefined> {
34
112
  const limit = await lane_capacity.lane_limit()
35
113
 
36
114
  if (limit.kind !== 'limit') return undefined
37
115
 
38
- return lane_capacity.free_lanes(limit.limit, lane_registry.live_count(lanes))
116
+ return { limit: limit.limit, free: free_of(limit.limit, room.use) }
117
+ }
118
+
119
+ async function free_lanes_beside(lanes: ReadonlyArray<LaneInfo>): Promise<number | undefined> {
120
+ const count = await count_in(await lane_room(lanes))
121
+
122
+ return count?.free
39
123
  }
40
124
 
41
125
  async function free_under(limit: number): Promise<number> {
42
- return lane_capacity.free_lanes(limit, await live_lane_count())
126
+ return free_of(limit, await lane_use())
43
127
  }
44
128
 
45
129
  // Free lanes right now: the limit less the live lanes. An unreadable limit reads as no free lane — the
@@ -48,9 +132,10 @@ async function free_under(limit: number): Promise<number> {
48
132
  //
49
133
  // **Occupancy is the local worktree count, not the dispatch budget's busy read.** `epic-lane-offer`
50
134
  // measures occupancy with `epic_busy.occupied_lanes`, a network read of in-progress issue labels; this
51
- // counts live worktrees instead, deliberately — it runs on the cheap-first path where the costly read
52
- // (`backlog:next`) is gated behind a free lane, so a network read here would defeat that design. The
53
- // two can diverge, but only toward over-counting live lanes → fewer free lanes, the safe direction.
135
+ // counts the worktrees that hold a place instead (`backlog-occupied.ts`), deliberately — it runs on the
136
+ // cheap-first path where the costly read (`backlog:next`) is gated behind a free lane, so a network
137
+ // read here would defeat that design. The two can diverge, but only toward over-counting live lanes →
138
+ // fewer free lanes, the safe direction.
54
139
  async function free_lane_count(): Promise<number> {
55
140
  return (await free_lanes_beside(await lane_registry.list_lanes())) ?? NO_FREE
56
141
  }
@@ -58,12 +143,24 @@ async function free_lane_count(): Promise<number> {
58
143
  // **The drive's count throws on an unreadable limit**. The drive launches no
59
144
  // more than this count, so the safe-direction zero above would leave it launching nothing and reporting
60
145
  // nothing for good; a bad setting is the hard error `lane_capacity` says it is, ending the drive loudly.
61
- async function drive_free_lane_count(): Promise<number> {
146
+ async function drive_limit(): Promise<number> {
62
147
  const limit = await lane_capacity.lane_limit()
63
148
 
64
149
  if (limit.kind !== 'limit') throw new Error(limit.problem)
65
150
 
66
- return await free_under(limit.limit)
151
+ return limit.limit
152
+ }
153
+
154
+ async function drive_free_lane_count(): Promise<number> {
155
+ return await free_under(await drive_limit())
156
+ }
157
+
158
+ // The drive's room under the limit alone, for resuming a kept lane, which already holds its port seat.
159
+ async function drive_limit_room(): Promise<number> {
160
+ const limit = await drive_limit()
161
+ const use = await lane_use()
162
+
163
+ return lane_capacity.limit_room(limit, use.occupied)
67
164
  }
68
165
 
69
166
  // **A `--only` run has no pool to drain**. `backlog:next` lists the opted-in
@@ -74,13 +171,32 @@ function drains_pool(carry: RunCarry | undefined): boolean {
74
171
  return carry === undefined || !run_invocation.has_only(carry.invocation)
75
172
  }
76
173
 
174
+ // The offer's own exclusion, read off this run's stream: a merged child `backlog:next` still reads OPEN,
175
+ // or one in flight, is no ready work (joshuafolkken/kit#4349). Scoped to this invocation, as the drive's
176
+ // list is: the stream is the repository's log, so an earlier run's merge or unsettled launch would
177
+ // otherwise hide a reopened issue for good.
178
+ async function stream_exclude(carry: RunCarry | undefined): Promise<ReadonlyArray<string>> {
179
+ const target = await run_event_stream_emit.stream_target()
180
+
181
+ if (target === undefined || carry === undefined) return []
182
+
183
+ const scope = run_event_scope.scope_of({ kind: 'carried', carry })
184
+ const events = run_event_scope.scoped_events(run_event_stream.read_events(target), scope) ?? []
185
+
186
+ return backlog_drive_restore.offer_exclude(events)
187
+ }
188
+
77
189
  // The `backlog:next` read, or `undefined` for a `--only` run, which answers none before paying for the
78
190
  // network read. A bounded read keeps stderr piped: the arrival probe reads once
79
191
  // a minute, and a forwarded refusal would fill the watcher's output.
80
192
  async function read_backlog_next(timeout_ms?: number): Promise<JoshResult | undefined> {
81
- if (!drains_pool(await run_headless.current_carry())) return undefined
193
+ const carry = await run_headless.current_carry()
194
+
195
+ if (!drains_pool(carry)) return undefined
196
+
197
+ const argv = ['backlog:next', ...backlog_offer_exclude.exclude_argv(await stream_exclude(carry))]
82
198
 
83
- return await josh_command.josh_run(['backlog:next'], timeout_ms === undefined, timeout_ms)
199
+ return await backlog_next_shared.read(argv, timeout_ms === undefined, timeout_ms)
84
200
  }
85
201
 
86
202
  // The runnable issues for this checkout, read the way a loop reads them: `backlog:next`'s numeric lines.
@@ -172,8 +288,11 @@ const backlog_ready = {
172
288
  print_offer_hint,
173
289
  free_lane_count,
174
290
  free_lanes_beside,
175
- live_lane_count,
291
+ count_in,
292
+ lane_room,
293
+ lane_use,
176
294
  drive_free_lane_count,
295
+ drive_limit_room,
177
296
  drains_pool,
178
297
  print_ready_line,
179
298
  read_ready,
@@ -182,4 +301,4 @@ const backlog_ready = {
182
301
  }
183
302
 
184
303
  export { backlog_ready }
185
- export type { ReadyPorts, ReadyReading }
304
+ export type { LaneCount, LaneRoom, LaneUse, ReadyPorts, ReadyReading }
@@ -1,12 +1,14 @@
1
- import { telegram_notify } from '#scripts/notify/telegram-notify'
1
+ import { lane_ledger, type LedgerEntry } from '#scripts/lane/lane-ledger'
2
2
  import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
3
3
  import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
4
4
  import { backlog_ready, type ReadyPorts } from './backlog-ready'
5
5
  import { backlog_stalled, type StallReading, type StallVerdict } from './backlog-stalled'
6
6
 
7
7
  // The I/O half of the stall detector: it gathers the three counts the pure
8
- // judge in `backlog-stalled.ts` weighs, then — on a stall — leaves the marker and sends the one
9
- // notification. `stop-guard.ts` wires it into the Stop hook, so it runs at each loop boundary; the CLI
8
+ // judge in `backlog-stalled.ts` weighs, then — on a stall — leaves the marker `run:step` reads as
9
+ // `backlog:next`. It sends no Telegram (joshuafolkken/kit#4015): a stall resolves itself at the next
10
+ // dispatch, so the person it reached had nothing to do; the idle notification `backlog:drive` sends
11
+ // when nothing is left to dispatch is the one that wants a hand. `stop-guard.ts` wires it into the Stop hook, so it runs at each loop boundary; the CLI
10
12
  // exposes the same call for a person to run by hand.
11
13
  //
12
14
  // **Cheap first.** The costly read is `backlog:next`, a subprocess that hits the network. The two local
@@ -14,26 +16,39 @@ import { backlog_stalled, type StallReading, type StallVerdict } from './backlog
14
16
  // is one `git worktree list`. Neither the lane count nor the backlog read is made unless the cheaper
15
17
  // condition ahead of it already holds, so an ordinary stop — a run not idle, or with no free lane —
16
18
  // costs a single file read and nothing more.
19
+ //
20
+ // **A stall is aged from when work and a lane first met** (joshuafolkken/kit#4349). Each probe records,
21
+ // on the lane ledger, whether offerable work and a free lane coexist — only when that changes — and the
22
+ // wait runs from the observation that opened the current episode. The dispatch age stays the cheap
23
+ // gate: the wait can never exceed it.
17
24
 
18
25
  const NO_FREE = 0
19
26
  const NO_READY = 0
20
27
  const NO_AGE = 0
21
28
 
22
- // The recovery line names the command that resolves the stall — the same one `run:step` points a stalled
23
- // run at — so the person the notification reaches has the fix in hand.
24
- const STALL_RECOVERY = 'Dispatch the ready work with `pnpm josh backlog:next`.'
25
-
26
- // The seams a test replaces: the stream target and its events, the clock, the two counts, and the two
27
- // side effects. The defaults are the real readers; a test hands fakes so the gather and report logic run
28
- // without a git tree, a network or a wall clock.
29
+ // The seams a test replaces: the stream target and its events, the clock, the two counts, the ledger,
30
+ // and the marker. The defaults are the real readers; a test hands fakes so the gather and report logic
31
+ // run without a git tree, a network or a wall clock.
29
32
  interface DetectPorts {
30
33
  resolve_target: () => Promise<string | undefined>
31
34
  read_events: (target: string) => ReadonlyArray<RunEvent>
32
35
  now_ms: () => number
33
36
  free_lane_count: () => Promise<number>
34
37
  ready_count: () => Promise<number>
38
+ read_ledger: () => Promise<ReadonlyArray<LedgerEntry>>
39
+ mark_offerable: (is_offerable: boolean) => Promise<void>
35
40
  emit_stall: (text: string) => Promise<boolean>
36
- notify_stalled: (body: string) => Promise<boolean>
41
+ }
42
+
43
+ interface Counts {
44
+ ready_count: number
45
+ free_lanes: number
46
+ }
47
+
48
+ // The dispatch reference the episode is bounded by, and the probe's own time.
49
+ interface Clock {
50
+ reference_ms: number
51
+ now_ms: number
37
52
  }
38
53
 
39
54
  // The free-lane and runnable-issue reads are `backlog-ready.ts`'s — the watcher's ready line reads the
@@ -55,8 +70,15 @@ async function real_emit_stall(text: string): Promise<boolean> {
55
70
  return await run_event_stream_emit.emit_once_since(STALL, text, CHILD_LAUNCH)
56
71
  }
57
72
 
58
- async function real_notify_stalled(body: string): Promise<boolean> {
59
- return await telegram_notify.stalled({ body, recovery: STALL_RECOVERY })
73
+ // A test run has no ledger (`lane_ledger.target`), so it reads as empty there.
74
+ async function read_real_ledger(): Promise<ReadonlyArray<LedgerEntry>> {
75
+ const path = await lane_ledger.target()
76
+
77
+ return path === undefined ? [] : lane_ledger.read_entries(path)
78
+ }
79
+
80
+ async function real_mark_offerable(is_offerable: boolean): Promise<void> {
81
+ await lane_ledger.record_offerable(is_offerable)
60
82
  }
61
83
 
62
84
  function ports_over(ready: ReadyPorts): DetectPorts {
@@ -66,26 +88,64 @@ function ports_over(ready: ReadyPorts): DetectPorts {
66
88
  now_ms: () => Date.now(),
67
89
  free_lane_count: ready.free_lane_count,
68
90
  ready_count: ready_count_of(ready),
91
+ read_ledger: read_real_ledger,
92
+ mark_offerable: real_mark_offerable,
69
93
  emit_stall: real_emit_stall,
70
- notify_stalled: real_notify_stalled,
71
94
  }
72
95
  }
73
96
 
74
97
  const DEFAULT_PORTS: DetectPorts = ports_over(backlog_ready.DEFAULT_PORTS)
75
98
 
76
- function ok_reading(dispatch_age_ms: number): StallReading {
77
- return { ready_count: NO_READY, free_lanes: NO_FREE, dispatch_age_ms }
99
+ function ok_reading(): StallReading {
100
+ return { ready_count: NO_READY, free_lanes: NO_FREE, waiting_ms: NO_AGE }
78
101
  }
79
102
 
80
- // The idle-and-past-threshold branch, where the costly reads finally happen: count the free lanes, and
81
- // only if one is free read the backlog. A full pool short-circuits before the network call — a stall
82
- // needs a lane to go into.
83
- async function probe_reading(ports: DetectPorts, dispatch_age_ms: number): Promise<StallReading> {
103
+ // Count the free lanes, and only if one is free read the backlog. A full pool short-circuits before the
104
+ // network call — a stall needs a lane to go into.
105
+ async function read_counts(ports: DetectPorts): Promise<Counts> {
84
106
  const free_lanes = await ports.free_lane_count()
85
107
 
86
- if (free_lanes <= NO_FREE) return { ready_count: NO_READY, free_lanes, dispatch_age_ms }
108
+ if (free_lanes <= NO_FREE) return { ready_count: NO_READY, free_lanes }
109
+
110
+ return { ready_count: await ports.ready_count(), free_lanes }
111
+ }
112
+
113
+ function has_both(counts: Counts): boolean {
114
+ return counts.ready_count > NO_READY && counts.free_lanes > NO_FREE
115
+ }
116
+
117
+ // How long both have held: from the observation that opened the episode, or zero where this probe opens
118
+ // or closes one — and records that change.
119
+ async function waiting_ms(
120
+ ports: DetectPorts,
121
+ entries: ReadonlyArray<LedgerEntry>,
122
+ clock: Clock,
123
+ is_offerable: boolean,
124
+ ): Promise<number> {
125
+ const opened_ms = backlog_stalled.open_offerable_ms(entries, clock.reference_ms)
126
+
127
+ if (is_offerable === (opened_ms !== undefined)) return clock.now_ms - (opened_ms ?? clock.now_ms)
87
128
 
88
- return { ready_count: await ports.ready_count(), free_lanes, dispatch_age_ms }
129
+ await ports.mark_offerable(is_offerable)
130
+
131
+ return NO_AGE
132
+ }
133
+
134
+ // The idle-and-past-threshold branch, where the costly reads finally happen.
135
+ async function probe_reading(ports: DetectPorts, clock: Clock): Promise<StallReading> {
136
+ const counts = await read_counts(ports)
137
+ const entries = await ports.read_ledger()
138
+ const waited = await waiting_ms(ports, entries, clock, has_both(counts))
139
+
140
+ return { ...counts, waiting_ms: waited, hold: backlog_stalled.open_hold(entries) }
141
+ }
142
+
143
+ // The dispatch reference and the probe's time, or `undefined` when the stream has nothing to age against.
144
+ function clock_of(ports: DetectPorts, target: string): Clock | undefined {
145
+ const now_ms = ports.now_ms()
146
+ const age = backlog_stalled.dispatch_age_ms(ports.read_events(target), now_ms)
147
+
148
+ return age === undefined ? undefined : { reference_ms: now_ms - age, now_ms }
89
149
  }
90
150
 
91
151
  // The reading that decides the verdict, assembled cheap-condition-first. `undefined` is the unreadable
@@ -96,25 +156,38 @@ async function gather(ports: DetectPorts, threshold_ms: number): Promise<StallRe
96
156
 
97
157
  if (target === undefined) return undefined
98
158
 
99
- const age = backlog_stalled.dispatch_age_ms(ports.read_events(target), ports.now_ms())
159
+ const clock = clock_of(ports, target)
100
160
 
101
- if (age === undefined) return ok_reading(NO_AGE)
102
- if (age <= threshold_ms) return ok_reading(age)
161
+ if (clock === undefined || clock.now_ms - clock.reference_ms <= threshold_ms) return ok_reading()
103
162
 
104
- return await probe_reading(ports, age)
163
+ return await probe_reading(ports, clock)
105
164
  }
106
165
 
107
- // The marker and the notification, both once per stall episode. `emit_stall` refuses a second until a
108
- // dispatch has intervened, and its `false` is what holds the notification back too — so a stall
109
- // polled every stop reaches the person once, not once a turn.
110
- async function report(ports: DetectPorts, reading: StallReading): Promise<void> {
111
- const text = backlog_stalled.describe(reading)
166
+ // The watcher's once-a-minute arrival probe records the same observation from the reading it already
167
+ // made, so an episode opens within a probe interval of work meeting a lane — not at the first stop past
168
+ // the dispatch-age gate, which would hide up to one threshold of the wait. Best-effort, like the check.
169
+ async function observe_offerable(
170
+ is_offerable: boolean,
171
+ ports: DetectPorts = DEFAULT_PORTS,
172
+ ): Promise<void> {
173
+ try {
174
+ const target = await ports.resolve_target()
175
+ const clock = target === undefined ? undefined : clock_of(ports, target)
112
176
 
113
- if (await ports.emit_stall(text)) await ports.notify_stalled(text)
177
+ if (clock !== undefined) await waiting_ms(ports, await ports.read_ledger(), clock, is_offerable)
178
+ } catch {
179
+ // A failed observation is dropped: the next probe records it, and the watcher's loop must not break.
180
+ }
181
+ }
182
+
183
+ // The marker, once per stall episode: `emit_stall` refuses a second until a dispatch has intervened, so a
184
+ // stall polled every stop lands on the stream once, not once a turn.
185
+ async function report(ports: DetectPorts, reading: StallReading): Promise<void> {
186
+ await ports.emit_stall(backlog_stalled.describe(reading))
114
187
  }
115
188
 
116
- // Read the three conditions, print nothing, and on a stall leave the marker and notify. The verdict is
117
- // returned for the CLI to print; the side effects are the report's.
189
+ // Read the three conditions, print nothing, and on a stall leave the marker. The verdict is returned for
190
+ // the CLI to print; the side effect is the report's.
118
191
  async function detect_and_report(
119
192
  ports: DetectPorts = DEFAULT_PORTS,
120
193
  threshold_ms: number = backlog_stalled.STALL_THRESHOLD_MS,
@@ -127,7 +200,7 @@ async function detect_and_report(
127
200
  return verdict
128
201
  }
129
202
 
130
- // Best-effort for the Stop hook: the detector is a report, so a failure to gather or notify is dropped
203
+ // Best-effort for the Stop hook: the detector is a report, so a failure to gather or mark is dropped
131
204
  // rather than raised into the stop decision it rides alongside.
132
205
  async function run_stall_check(ready: ReadyPorts = backlog_ready.DEFAULT_PORTS): Promise<void> {
133
206
  try {
@@ -137,7 +210,7 @@ async function run_stall_check(ready: ReadyPorts = backlog_ready.DEFAULT_PORTS):
137
210
  }
138
211
  }
139
212
 
140
- const backlog_stalled_detect = { detect_and_report, run_stall_check }
213
+ const backlog_stalled_detect = { detect_and_report, observe_offerable, run_stall_check }
141
214
 
142
215
  export { backlog_stalled_detect }
143
216
  export type { DetectPorts }