@joshuafolkken/kit 1.1240.0 → 1.1370.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 (934) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +19 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +26 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +17 -28
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.vscode/tasks.json +14 -0
  42. package/CLAUDE.md +10 -61
  43. package/README.md +29 -47
  44. package/SECURITY.md +1 -1
  45. package/dist/CLAUDE.md +10 -61
  46. package/dist/commands/document-section-cli.js +42 -10
  47. package/dist/config-merge/index.js +11 -2
  48. package/dist/hooks/audit-provision.js +2 -2
  49. package/dist/hooks/batch-guard.js +7 -7
  50. package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-43G45XJF.js} +18 -20
  51. package/dist/hooks/{chunk-4TZVB44A.js → chunk-4TW4MQUL.js} +284 -362
  52. package/dist/hooks/{chunk-XZYKEM6J.js → chunk-76RK6E3H.js} +13 -11
  53. package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-DZWZ3DKY.js} +4 -4
  54. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  55. package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
  56. package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-KPM4YIIX.js} +8 -44
  57. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  58. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  59. package/dist/hooks/{chunk-QVSWU24O.js → chunk-NZBHG6FW.js} +7 -5
  60. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  61. package/dist/hooks/{chunk-KRBERBBI.js → chunk-R6CRQEAL.js} +4 -4
  62. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  63. package/dist/hooks/{chunk-WK2XSHSI.js → chunk-TLJYAGZK.js} +549 -874
  64. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  65. package/dist/hooks/codex-hook-adapter.js +26 -21
  66. package/dist/hooks/duplicate-read-guard.js +8 -8
  67. package/dist/hooks/format-edited.js +4 -4
  68. package/dist/hooks/inputs.json +216 -202
  69. package/dist/hooks/investigation-guard.js +8 -8
  70. package/dist/hooks/pretool-guard.js +15 -15
  71. package/dist/hooks/session-lang.js +406 -8
  72. package/dist/hooks/stop-guard.js +122 -187
  73. package/dist/josh.js +281 -94
  74. package/dist/version/index.js +15 -13
  75. package/eslint/base.js +43 -5
  76. package/eslint/rules/english-only-prose.js +3 -3
  77. package/eslint/rules/import.js +12 -0
  78. package/eslint/rules/namespace-object-export.js +2 -2
  79. package/package.json +16 -10
  80. package/pnpm-workspace.yaml +2 -4
  81. package/prompts/coding-standards.md +14 -48
  82. package/prompts/collaboration-workflow/file-edits.md +1 -1
  83. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  84. package/prompts/collaboration-workflow/issue-template.md +3 -10
  85. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  86. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  87. package/prompts/collaboration-workflow/overview.md +1 -1
  88. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  89. package/prompts/collaboration-workflow/principles.md +21 -3
  90. package/prompts/collaboration-workflow/report-format.md +16 -29
  91. package/prompts/collaboration-workflow/residency.md +1 -1
  92. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  93. package/prompts/collaboration-workflow/shell-body.md +3 -23
  94. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  95. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +3 -22
  98. package/prompts/review.md +15 -38
  99. package/prompts/testing-guide.md +2 -4
  100. package/scripts/adopt/adopt-logic.ts +5 -5
  101. package/scripts/adopt/adopt-toolkits.ts +4 -5
  102. package/scripts/adopt/adopt.ts +2 -3
  103. package/scripts/agent/agent-argv.ts +7 -7
  104. package/scripts/agent/agent-diagnostics.ts +2 -2
  105. package/scripts/agent/agent-exit-record.ts +1 -1
  106. package/scripts/agent/agent-headless.ts +1 -1
  107. package/scripts/agent/agent-launch-environment.ts +6 -1
  108. package/scripts/agent/agent-role-profile.ts +49 -22
  109. package/scripts/agent/agent-session-role.ts +32 -0
  110. package/scripts/agent/api-outage.ts +1 -1
  111. package/scripts/agent/claude-agent-argv.ts +4 -4
  112. package/scripts/agent/claude-result-event.ts +4 -4
  113. package/scripts/agent/codex-hooks.ts +2 -2
  114. package/scripts/agent/interactive-ask.ts +3 -6
  115. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  116. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  117. package/scripts/backlog/backlog-arrival.ts +54 -17
  118. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  119. package/scripts/backlog/backlog-budget.ts +17 -24
  120. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  121. package/scripts/backlog/backlog-drive-args.ts +5 -4
  122. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  123. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  124. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  125. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  126. package/scripts/backlog/backlog-drive-named.ts +39 -9
  127. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  128. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  129. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  130. package/scripts/backlog/backlog-drive.ts +43 -28
  131. package/scripts/backlog/backlog-idle.ts +88 -0
  132. package/scripts/backlog/backlog-named.ts +11 -15
  133. package/scripts/backlog/backlog-next.ts +26 -30
  134. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  135. package/scripts/backlog/backlog-offer.ts +7 -7
  136. package/scripts/backlog/backlog-overlap.ts +178 -0
  137. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  138. package/scripts/backlog/backlog-plan-read.ts +111 -0
  139. package/scripts/backlog/backlog-plan.ts +11 -10
  140. package/scripts/backlog/backlog-pool.ts +13 -14
  141. package/scripts/backlog/backlog-rank.ts +11 -11
  142. package/scripts/backlog/backlog-ready.ts +15 -10
  143. package/scripts/backlog/backlog-scope.ts +14 -15
  144. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  145. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  146. package/scripts/backlog/backlog-stalled.ts +5 -6
  147. package/scripts/backlog/backlog-waves.ts +4 -4
  148. package/scripts/backlog/backlogrun-args.ts +74 -0
  149. package/scripts/backlog/backlogrun-cli.ts +113 -0
  150. package/scripts/backlog/backlogrun-launch.ts +178 -0
  151. package/scripts/behavior/behavior-assertion.ts +6 -8
  152. package/scripts/behavior/behavior-cli.ts +1 -1
  153. package/scripts/behavior/behavior-rules.ts +3 -3
  154. package/scripts/build/build-claude-md.ts +4 -4
  155. package/scripts/build/build-codex-hooks.ts +2 -2
  156. package/scripts/build/build-commands.ts +1 -1
  157. package/scripts/build/build-hooks.ts +5 -5
  158. package/scripts/build/build.ts +1 -1
  159. package/scripts/build/hook-bundle-stamp.ts +109 -7
  160. package/scripts/build/local-bin.ts +2 -2
  161. package/scripts/cases/cases-cli.ts +1 -1
  162. package/scripts/cases/cases-logic.ts +2 -2
  163. package/scripts/ci/composite-actions.ts +1 -2
  164. package/scripts/ci/pr-classification.ts +2 -2
  165. package/scripts/claude/workflow-destination.ts +1 -1
  166. package/scripts/clone/clone-aggregate.ts +1 -1
  167. package/scripts/clone/clone-fingerprint.ts +1 -1
  168. package/scripts/clone/clone-scan-cli.ts +1 -1
  169. package/scripts/clone/clone-scan.ts +1 -1
  170. package/scripts/config-merge/index.ts +1 -1
  171. package/scripts/config-merge/json-format.ts +1 -3
  172. package/scripts/config-merge/patch-json-array.ts +90 -0
  173. package/scripts/config-merge/patch-json-key.ts +6 -3
  174. package/scripts/config-merge/patch-json-list.ts +1 -1
  175. package/scripts/cost-runtime/codex-usage.ts +1 -1
  176. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  177. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  178. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  179. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  180. package/scripts/cost-runtime/cost-cli.ts +14 -11
  181. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  182. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  183. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  184. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  185. package/scripts/cost-runtime/cost-usage.ts +6 -7
  186. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  187. package/scripts/cost-runtime/own-session.ts +1 -1
  188. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  189. package/scripts/delegation/delegation-cli.ts +4 -4
  190. package/scripts/delegation/delegation-policy.ts +13 -15
  191. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  192. package/scripts/delegation/fanout-cli.ts +1 -1
  193. package/scripts/delegation/fanout.ts +1 -1
  194. package/scripts/delegation/investigation-guard.ts +18 -22
  195. package/scripts/delegation/investigation-reads.ts +48 -238
  196. package/scripts/discovery/repo-discovery.ts +1 -1
  197. package/scripts/discovery/repo-map-logic.ts +1 -2
  198. package/scripts/discovery/repo-origin.ts +3 -3
  199. package/scripts/discovery/repo-party-cli.ts +2 -2
  200. package/scripts/discovery/repo-party.ts +2 -2
  201. package/scripts/doctor/doctor-consumer.ts +1 -1
  202. package/scripts/doctor/doctor-io.ts +6 -7
  203. package/scripts/doctor/doctor-logic.ts +1 -1
  204. package/scripts/doctor/doctor-ports.ts +1 -1
  205. package/scripts/doctor/doctor.ts +8 -9
  206. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  207. package/scripts/document/bash-output-cap.ts +5 -7
  208. package/scripts/document/capped-print-part.ts +1 -1
  209. package/scripts/document/capped-print.ts +1 -1
  210. package/scripts/document/document-byte-budget.ts +33 -64
  211. package/scripts/document/document-byte-check.ts +4 -4
  212. package/scripts/document/document-reachability.ts +7 -8
  213. package/scripts/document/document-read-cli.ts +2 -2
  214. package/scripts/document/document-scan.ts +26 -2
  215. package/scripts/document/document-section-cli.ts +6 -8
  216. package/scripts/document/document-section.ts +8 -12
  217. package/scripts/document/edit-files-cli.ts +3 -4
  218. package/scripts/document/entry-read-budget.ts +8 -70
  219. package/scripts/document/entry-read-set.ts +51 -34
  220. package/scripts/document/lane-child-read-set.ts +9 -9
  221. package/scripts/document/read-files-cli.ts +1 -2
  222. package/scripts/document/read-set-cli.ts +16 -19
  223. package/scripts/document/read-set-cost.ts +4 -4
  224. package/scripts/document/read-set-point-of-use.ts +28 -38
  225. package/scripts/document/read-set-pricing.ts +1 -1
  226. package/scripts/document/read-set-trim.ts +3 -3
  227. package/scripts/document/resident-budget.ts +8 -10
  228. package/scripts/epic/epic-add-body.ts +15 -18
  229. package/scripts/epic/epic-add-plan.ts +26 -28
  230. package/scripts/epic/epic-add.ts +32 -25
  231. package/scripts/epic/epic-audit-checks.ts +27 -37
  232. package/scripts/epic/epic-audit-cli.ts +21 -22
  233. package/scripts/epic/epic-audit-orphans.ts +16 -17
  234. package/scripts/epic/epic-audit-rationale.ts +10 -15
  235. package/scripts/epic/epic-audit-report.ts +2 -5
  236. package/scripts/epic/epic-audit.ts +18 -14
  237. package/scripts/epic/epic-body.ts +10 -10
  238. package/scripts/epic/epic-bundle-cli.ts +36 -34
  239. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  240. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  241. package/scripts/epic/epic-bundle-poll.ts +1 -1
  242. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  243. package/scripts/epic/epic-bundle.ts +19 -20
  244. package/scripts/epic/epic-busy.ts +44 -21
  245. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  246. package/scripts/epic/epic-chains.ts +18 -23
  247. package/scripts/epic/epic-classify.ts +11 -12
  248. package/scripts/epic/epic-cli-argv.ts +5 -6
  249. package/scripts/epic/epic-cli-remove.ts +9 -4
  250. package/scripts/epic/epic-cli.ts +38 -26
  251. package/scripts/epic/epic-close-comment.ts +14 -15
  252. package/scripts/epic/epic-close.ts +25 -29
  253. package/scripts/epic/epic-cross-repo.ts +18 -21
  254. package/scripts/epic/epic-decision.ts +14 -18
  255. package/scripts/epic/epic-fetch.ts +25 -31
  256. package/scripts/epic/epic-graph.ts +15 -17
  257. package/scripts/epic/epic-index.ts +14 -16
  258. package/scripts/epic/epic-issue.ts +9 -11
  259. package/scripts/epic/epic-label-age.ts +74 -0
  260. package/scripts/epic/epic-lane-offer.ts +35 -24
  261. package/scripts/epic/epic-nested.ts +1 -1
  262. package/scripts/epic/epic-next-read.ts +8 -8
  263. package/scripts/epic/epic-next-views.ts +12 -12
  264. package/scripts/epic/epic-next.ts +29 -33
  265. package/scripts/epic/epic-outside-blocker.ts +11 -10
  266. package/scripts/epic/epic-parse.ts +22 -24
  267. package/scripts/epic/epic-promote.ts +3 -2
  268. package/scripts/epic/epic-rank.ts +1 -1
  269. package/scripts/epic/epic-read.ts +10 -8
  270. package/scripts/epic/epic-reconcile.ts +8 -6
  271. package/scripts/epic/epic-reference.ts +5 -4
  272. package/scripts/epic/epic-relation-recheck.ts +10 -11
  273. package/scripts/epic/epic-relations.ts +9 -8
  274. package/scripts/epic/epic-remove-plan.ts +4 -5
  275. package/scripts/epic/epic-remove.ts +7 -5
  276. package/scripts/epic/epic-report.ts +18 -20
  277. package/scripts/epic/epic-run.ts +6 -5
  278. package/scripts/epic/epic-sections.ts +2 -2
  279. package/scripts/epic/epic-shape.ts +3 -3
  280. package/scripts/epic/epic-solo-stale.ts +3 -2
  281. package/scripts/epic/epic-solo.ts +8 -8
  282. package/scripts/epic/epic-triage.ts +5 -4
  283. package/scripts/epic/epic-validate.ts +8 -7
  284. package/scripts/epic/epic.ts +5 -5
  285. package/scripts/exports/unused-members-cli.ts +1 -1
  286. package/scripts/followup/followup-issue-number.ts +1 -2
  287. package/scripts/followup/git-followup-cleanup.ts +6 -7
  288. package/scripts/followup/git-followup-finish.ts +11 -13
  289. package/scripts/followup/git-followup-flush.ts +11 -7
  290. package/scripts/followup/git-followup-issue-close.ts +16 -13
  291. package/scripts/followup/git-followup-label.ts +9 -6
  292. package/scripts/followup/git-followup-merged.ts +1 -1
  293. package/scripts/followup/git-followup-pending.ts +7 -9
  294. package/scripts/followup/git-followup-stages.ts +28 -17
  295. package/scripts/followup/git-followup-workflow.ts +19 -21
  296. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  297. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  298. package/scripts/followup/git-pr-followup.ts +18 -17
  299. package/scripts/gate/core-admission.ts +2 -2
  300. package/scripts/gate/core-budget.ts +15 -26
  301. package/scripts/gate/gate-ledger.ts +114 -0
  302. package/scripts/gate/gate-log.ts +7 -9
  303. package/scripts/gate/gate-plan.ts +70 -35
  304. package/scripts/gate/gate-report.ts +14 -15
  305. package/scripts/gate/gate-skip.ts +11 -13
  306. package/scripts/gate/gate-steps.ts +5 -1
  307. package/scripts/gate/gate-tree.ts +3 -4
  308. package/scripts/gate/hook-gate-reuse.ts +9 -9
  309. package/scripts/gate/machine-capacity.ts +168 -30
  310. package/scripts/gate/pre-commit-type-check.ts +4 -4
  311. package/scripts/gate/project-checks.ts +12 -4
  312. package/scripts/gate/scoped-green.ts +11 -18
  313. package/scripts/gate/type-check-command.ts +2 -2
  314. package/scripts/gate/type-check-step.ts +4 -4
  315. package/scripts/gate/verification-gate.ts +53 -51
  316. package/scripts/gh/gh-spawn.ts +2 -2
  317. package/scripts/gh/git-ai-review-scan.ts +3 -2
  318. package/scripts/gh/git-gh-api-path.ts +10 -11
  319. package/scripts/gh/git-gh-exec.ts +43 -48
  320. package/scripts/gh/git-gh-failure.ts +6 -9
  321. package/scripts/gh/git-gh-helpers.ts +1 -1
  322. package/scripts/gh/git-gh-issue-list.ts +15 -19
  323. package/scripts/gh/git-gh-issue-read.ts +43 -60
  324. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  325. package/scripts/gh/git-gh-issue-write.ts +52 -40
  326. package/scripts/gh/git-gh-issue.ts +23 -24
  327. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  328. package/scripts/gh/git-gh-pr-read.ts +46 -50
  329. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  330. package/scripts/gh/git-gh-pr-review.ts +2 -2
  331. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  332. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  333. package/scripts/gh/git-gh-pr.ts +16 -16
  334. package/scripts/gh/git-gh-reachability.ts +11 -12
  335. package/scripts/gh/git-gh-repo.ts +2 -3
  336. package/scripts/gh/git-gh-rest-state.ts +1 -1
  337. package/scripts/gh/git-pr-ai-review.ts +6 -5
  338. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  339. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  340. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  341. package/scripts/gh/git-pr-checks.ts +20 -23
  342. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  343. package/scripts/gh/git-pr-confirmation.ts +5 -5
  344. package/scripts/gh/git-pr-managed-config.ts +7 -9
  345. package/scripts/gh/git-pr-messages.ts +1 -1
  346. package/scripts/gh/git-pr.ts +15 -16
  347. package/scripts/gh/github-issue-url.ts +8 -9
  348. package/scripts/git/base-tree.ts +66 -0
  349. package/scripts/git/change-base.ts +42 -2
  350. package/scripts/git/changed-file-scope.ts +5 -5
  351. package/scripts/git/changed-paths.ts +1 -2
  352. package/scripts/git/constants.ts +2 -2
  353. package/scripts/git/git-branch.ts +1 -1
  354. package/scripts/git/git-closes-keyword.ts +3 -3
  355. package/scripts/git/git-command.ts +53 -41
  356. package/scripts/git/git-common-directory.ts +3 -3
  357. package/scripts/git/git-diff-reads.ts +14 -15
  358. package/scripts/git/git-error.ts +1 -1
  359. package/scripts/git/git-execa-error.ts +1 -2
  360. package/scripts/git/git-issue.ts +10 -8
  361. package/scripts/git/git-location-environment.ts +3 -4
  362. package/scripts/git/git-ls-remote.ts +6 -8
  363. package/scripts/git/git-pre-push-hook.ts +11 -10
  364. package/scripts/git/git-preflight.ts +5 -5
  365. package/scripts/git/git-push-transport.ts +2 -2
  366. package/scripts/git/git-remote-branch.ts +1 -2
  367. package/scripts/git/git-schemas.ts +16 -23
  368. package/scripts/git/git-spawn-sync.ts +1 -1
  369. package/scripts/git/git-spawn.ts +37 -14
  370. package/scripts/git/git-ssh-keepalive.ts +12 -5
  371. package/scripts/git/git-staging.ts +7 -8
  372. package/scripts/git/git-workflow.ts +1 -1
  373. package/scripts/git/git-worktree.ts +35 -27
  374. package/scripts/git/gone-branch.ts +2 -2
  375. package/scripts/git/listing-cutoff.ts +1 -2
  376. package/scripts/git/lockfile-sync.ts +65 -0
  377. package/scripts/git/main-merge-guard.ts +1 -2
  378. package/scripts/git/main-merge.ts +7 -7
  379. package/scripts/git/main-sync.ts +23 -8
  380. package/scripts/git/parse-json-array.ts +18 -23
  381. package/scripts/git/repository-lock.ts +34 -2
  382. package/scripts/git/stash/git-stash.ts +4 -5
  383. package/scripts/git/stash/stash-orphans.ts +5 -3
  384. package/scripts/git/stash/stash-pop-args.ts +1 -1
  385. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  386. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  387. package/scripts/hooks/batch-guard.ts +11 -13
  388. package/scripts/hooks/check-commit-message.ts +12 -9
  389. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  390. package/scripts/hooks/edited-cspell.ts +3 -4
  391. package/scripts/hooks/format-edited-cli.ts +1 -1
  392. package/scripts/hooks/format-edited-file.ts +11 -17
  393. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  394. package/scripts/hooks/pre-push-unit.ts +10 -14
  395. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  396. package/scripts/hooks/pretool-guard.ts +93 -18
  397. package/scripts/hooks/reserved-run.ts +2 -2
  398. package/scripts/hooks/step-zero-notice.ts +1 -1
  399. package/scripts/hooks/stop-guard.ts +21 -10
  400. package/scripts/init/basic-path-migration.ts +2 -2
  401. package/scripts/init/claude-kit-only-settings.ts +2 -2
  402. package/scripts/init/claude-plugin-config.ts +2 -2
  403. package/scripts/init/distributed-paths.ts +4 -4
  404. package/scripts/init/hook-command-rewrite.ts +3 -3
  405. package/scripts/init/hook-launch.ts +5 -5
  406. package/scripts/init/init-actions.ts +13 -0
  407. package/scripts/init/init-ai-copy.ts +11 -11
  408. package/scripts/init/init-bootstrap.ts +3 -3
  409. package/scripts/init/init-copy-content.ts +4 -4
  410. package/scripts/init/init-logic-json-merge.ts +7 -9
  411. package/scripts/init/init-logic-migrate.ts +1 -1
  412. package/scripts/init/init-logic-templates.ts +1 -1
  413. package/scripts/init/init-logic-workspace.ts +4 -4
  414. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  415. package/scripts/init/init-logic.ts +19 -22
  416. package/scripts/init/init.ts +7 -7
  417. package/scripts/init/kit-base-preset.ts +1 -1
  418. package/scripts/init/kit-setup-state.ts +1 -1
  419. package/scripts/init/kit-written-paths.ts +1 -2
  420. package/scripts/init/package-manager-pin.ts +1 -1
  421. package/scripts/init/project-profile-cli.ts +1 -1
  422. package/scripts/init/project-profile.ts +3 -3
  423. package/scripts/init/session-language-environment.ts +1 -1
  424. package/scripts/init/start-exec.ts +3 -4
  425. package/scripts/init/start-plan.ts +2 -2
  426. package/scripts/init/start-setup-pr.ts +3 -2
  427. package/scripts/init/start-steps.ts +2 -2
  428. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  429. package/scripts/init/vscode-tasks.ts +62 -0
  430. package/scripts/issue/baseline-measure.ts +2 -2
  431. package/scripts/issue/behavior-change-lint.ts +2 -2
  432. package/scripts/issue/defect-rate-cli.ts +6 -7
  433. package/scripts/issue/defect-rate.ts +37 -27
  434. package/scripts/issue/git-next-issues.ts +9 -8
  435. package/scripts/issue/issue-auto-ok.ts +24 -11
  436. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  437. package/scripts/issue/issue-backlinks.ts +6 -6
  438. package/scripts/issue/issue-cite-cli.ts +20 -18
  439. package/scripts/issue/issue-cite.ts +18 -8
  440. package/scripts/issue/issue-closing-pr.ts +4 -4
  441. package/scripts/issue/issue-comment-cli.ts +6 -4
  442. package/scripts/issue/issue-file-cli.ts +52 -15
  443. package/scripts/issue/issue-file-fold.ts +155 -0
  444. package/scripts/issue/issue-file.ts +9 -6
  445. package/scripts/issue/issue-fold-cli.ts +14 -9
  446. package/scripts/issue/issue-fold.ts +23 -8
  447. package/scripts/issue/issue-labels.ts +34 -38
  448. package/scripts/issue/issue-lint-cli.ts +2 -2
  449. package/scripts/issue/issue-lint.ts +1 -1
  450. package/scripts/issue/issue-merged.ts +10 -4
  451. package/scripts/issue/issue-number-shape.ts +27 -0
  452. package/scripts/issue/issue-rank.ts +1 -1
  453. package/scripts/issue/issue-read-cli.ts +4 -5
  454. package/scripts/issue/issue-read.ts +4 -5
  455. package/scripts/issue/issue-reference.ts +5 -5
  456. package/scripts/issue/issue-release-cli.ts +17 -7
  457. package/scripts/issue/issue-release.ts +3 -3
  458. package/scripts/issue/issue-report-failures.ts +7 -4
  459. package/scripts/issue/issue-scout-cli.ts +11 -11
  460. package/scripts/issue/issue-scout-closed.ts +4 -4
  461. package/scripts/issue/issue-scout.ts +4 -5
  462. package/scripts/issue/issue-state-cli.ts +17 -10
  463. package/scripts/issue/issue-state.ts +12 -13
  464. package/scripts/issue/issue-wip.ts +7 -7
  465. package/scripts/issue/markdown-section.ts +3 -3
  466. package/scripts/issue/measure-rerun-cli.ts +10 -9
  467. package/scripts/issue/reproduction-measure.ts +3 -3
  468. package/scripts/issue/session-cite.ts +56 -0
  469. package/scripts/josh/agent-session-environment.ts +10 -8
  470. package/scripts/josh/cli-body.ts +2 -2
  471. package/scripts/josh/command-suggest.ts +1 -1
  472. package/scripts/josh/file-map-stamp.ts +20 -23
  473. package/scripts/josh/hook-decision.ts +24 -28
  474. package/scripts/josh/josh-command-map.ts +4 -1
  475. package/scripts/josh/josh-command-types.ts +30 -35
  476. package/scripts/josh/josh-commands-ai.ts +6 -6
  477. package/scripts/josh/josh-commands-backlog.ts +15 -3
  478. package/scripts/josh/josh-commands-clone.ts +1 -1
  479. package/scripts/josh/josh-commands-development.ts +25 -4
  480. package/scripts/josh/josh-commands-document.ts +3 -3
  481. package/scripts/josh/josh-commands-guard.ts +3 -3
  482. package/scripts/josh/josh-commands-issue.ts +4 -5
  483. package/scripts/josh/josh-commands-lane.ts +14 -4
  484. package/scripts/josh/josh-commands-lint.ts +1 -1
  485. package/scripts/josh/josh-commands-run.ts +20 -6
  486. package/scripts/josh/josh-commands-split.ts +1 -2
  487. package/scripts/josh/josh-commands-versioning.ts +5 -5
  488. package/scripts/josh/josh-commands-workflow.ts +30 -22
  489. package/scripts/josh/josh-environment-file.ts +1 -1
  490. package/scripts/josh/josh-in-process.ts +3 -3
  491. package/scripts/josh/josh-logic.ts +6 -7
  492. package/scripts/josh/josh-run.ts +3 -3
  493. package/scripts/josh/josh-verdict.ts +9 -12
  494. package/scripts/josh/josh.ts +3 -3
  495. package/scripts/josh/kit-only.ts +2 -2
  496. package/scripts/josh/path-decision.ts +3 -3
  497. package/scripts/josh/platform-temporary.ts +7 -5
  498. package/scripts/josh/process-identity.ts +24 -6
  499. package/scripts/josh/process-owner.ts +4 -4
  500. package/scripts/josh/session-language-cli.ts +53 -11
  501. package/scripts/josh/session-language.ts +1 -1
  502. package/scripts/josh/stamp-file.ts +48 -29
  503. package/scripts/josh/stamp-record.ts +57 -0
  504. package/scripts/lane/lane-await.ts +35 -11
  505. package/scripts/lane/lane-cache.ts +6 -6
  506. package/scripts/lane/lane-capacity.ts +32 -17
  507. package/scripts/lane/lane-child-invocation.ts +17 -15
  508. package/scripts/lane/lane-child-marker.ts +12 -12
  509. package/scripts/lane/lane-cli.ts +12 -13
  510. package/scripts/lane/lane-close.ts +6 -6
  511. package/scripts/lane/lane-dispatch.ts +61 -72
  512. package/scripts/lane/lane-environment.ts +5 -5
  513. package/scripts/lane/lane-guard-policy.ts +7 -21
  514. package/scripts/lane/lane-handoff.ts +2 -2
  515. package/scripts/lane/lane-install.ts +9 -10
  516. package/scripts/lane/lane-launch-cli.ts +13 -8
  517. package/scripts/lane/lane-ledger.ts +73 -11
  518. package/scripts/lane/lane-leftover.ts +2 -2
  519. package/scripts/lane/lane-limit-cli.ts +160 -0
  520. package/scripts/lane/lane-limit-override.ts +74 -0
  521. package/scripts/lane/lane-load.ts +19 -68
  522. package/scripts/lane/lane-measure-cli.ts +15 -25
  523. package/scripts/lane/lane-occupancy.ts +6 -4
  524. package/scripts/lane/lane-open.ts +20 -19
  525. package/scripts/lane/lane-output.ts +4 -3
  526. package/scripts/lane/lane-paths.ts +12 -11
  527. package/scripts/lane/lane-phase.ts +33 -0
  528. package/scripts/lane/lane-reap.ts +2 -2
  529. package/scripts/lane/lane-registry.ts +16 -15
  530. package/scripts/lane/lane-relaunch.ts +9 -9
  531. package/scripts/lane/lane-report.ts +5 -4
  532. package/scripts/lane/lane-resume.ts +2 -2
  533. package/scripts/lane/lane-sampler.ts +55 -0
  534. package/scripts/lane/lane-seed.ts +7 -7
  535. package/scripts/lane/lane-stage-stats.ts +135 -0
  536. package/scripts/lane/lane-start-point.ts +8 -11
  537. package/scripts/lane/lane-stats.ts +60 -15
  538. package/scripts/lane/lane-stray.ts +1 -1
  539. package/scripts/lane/lane-vacant.ts +1 -1
  540. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  541. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  542. package/scripts/lane/openai-review-broker.ts +2 -4
  543. package/scripts/lib/ancestor-directories.ts +1 -1
  544. package/scripts/lib/bounded-pool.ts +2 -2
  545. package/scripts/lib/buffered-process.ts +4 -6
  546. package/scripts/lib/caddy-logs.sh +0 -0
  547. package/scripts/lib/cli-flags.ts +39 -6
  548. package/scripts/lib/error-message.ts +1 -1
  549. package/scripts/lib/json-value.ts +17 -3
  550. package/scripts/lib/poll.ts +1 -1
  551. package/scripts/lib/status-icons.ts +3 -3
  552. package/scripts/lib/timed-fetch.ts +1 -1
  553. package/scripts/lib/timeouts.ts +1 -1
  554. package/scripts/lines/bytes-command.ts +3 -4
  555. package/scripts/lines/effective-limit.ts +25 -12
  556. package/scripts/lines/line-budget.ts +47 -55
  557. package/scripts/lines/line-targets.ts +6 -2
  558. package/scripts/lines/lines-command.ts +3 -3
  559. package/scripts/lint/cspell-cached.ts +1 -1
  560. package/scripts/lint/cycle-recheck.ts +122 -0
  561. package/scripts/lint/format.ts +1 -2
  562. package/scripts/lint/lint-parallel.ts +34 -19
  563. package/scripts/lint/lint-related-scope.ts +25 -15
  564. package/scripts/lint/lint-related.ts +6 -7
  565. package/scripts/managed-marker/index.ts +1 -1
  566. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  567. package/scripts/notify/git-notify.ts +9 -7
  568. package/scripts/notify/telegram-notify.ts +53 -37
  569. package/scripts/notify/telegram-test-logic.ts +3 -3
  570. package/scripts/notify/telegram-test.ts +45 -30
  571. package/scripts/observations/observation-ledger-home.ts +14 -8
  572. package/scripts/observations/observation-ledger-line.ts +3 -2
  573. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  574. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  575. package/scripts/observations/observation-ledger.ts +14 -15
  576. package/scripts/observations/observation-record-cli.ts +83 -0
  577. package/scripts/observations/observation-record.ts +91 -0
  578. package/scripts/observations/observations-flush-cli.ts +1 -1
  579. package/scripts/observations/observations-flush-landing.ts +7 -6
  580. package/scripts/observations/observations-flush.ts +26 -27
  581. package/scripts/overrides/overrides-check.ts +18 -8
  582. package/scripts/package/package-scout-cli.ts +1 -1
  583. package/scripts/package/package-scout-format.ts +2 -2
  584. package/scripts/package/package-scout.ts +1 -1
  585. package/scripts/propagate/propagate-git-failure.ts +1 -1
  586. package/scripts/propagate/propagate-git.ts +7 -7
  587. package/scripts/propagate/propagate-plan.ts +2 -2
  588. package/scripts/propagate/propagate-publish.ts +2 -3
  589. package/scripts/propagate/propagate-run.ts +5 -7
  590. package/scripts/propagate/propagate-select.ts +1 -1
  591. package/scripts/propagate/propagate-steps.ts +19 -20
  592. package/scripts/propagate/propagate-targets.ts +6 -10
  593. package/scripts/propagate/propagate.ts +5 -5
  594. package/scripts/refactor/import-graph.ts +1 -1
  595. package/scripts/refactor/refactor-lint.ts +4 -10
  596. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  597. package/scripts/refactor/refactor-scan.ts +2 -2
  598. package/scripts/refactor/refactor-targets.ts +1 -1
  599. package/scripts/release/github-release-cli.ts +25 -3
  600. package/scripts/release/github-release-runs.ts +1 -1
  601. package/scripts/release/release-cli.ts +21 -4
  602. package/scripts/release/release-history.ts +6 -10
  603. package/scripts/release/release-plan.ts +3 -3
  604. package/scripts/release/release-progress.ts +3 -4
  605. package/scripts/release/release-publish.ts +8 -9
  606. package/scripts/release/release-scope-cli.ts +8 -10
  607. package/scripts/release/release-tag.ts +6 -8
  608. package/scripts/release/release-worktree.ts +5 -5
  609. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  610. package/scripts/repo/auto-merge-setting.ts +1 -1
  611. package/scripts/repo/repo-setting.ts +4 -4
  612. package/scripts/repo/repository-labels.ts +1 -1
  613. package/scripts/repo/required-checks-logic.ts +3 -3
  614. package/scripts/repo/required-checks-report.ts +1 -1
  615. package/scripts/repo/ruleset-check-cli.ts +1 -1
  616. package/scripts/repo/ruleset-check.ts +1 -1
  617. package/scripts/report/report-format-reference.ts +26 -0
  618. package/scripts/report/report-lint-cli.ts +2 -2
  619. package/scripts/report/report-lint.ts +16 -2
  620. package/scripts/review/disposition-cli.ts +2 -2
  621. package/scripts/review/disposition-logic.ts +1 -1
  622. package/scripts/review/live-evidence.ts +9 -6
  623. package/scripts/review/review-attest-cli.ts +1 -2
  624. package/scripts/review/review-attest.ts +3 -3
  625. package/scripts/review/review-brief-cli.ts +19 -20
  626. package/scripts/review/review-brief.ts +29 -32
  627. package/scripts/review/review-checkout.ts +2 -2
  628. package/scripts/review/review-diff-parts.ts +3 -5
  629. package/scripts/review/review-diff-write.ts +1 -1
  630. package/scripts/review/review-finding-ledger.ts +7 -4
  631. package/scripts/review/review-findings-cli.ts +2 -2
  632. package/scripts/review/review-level.ts +4 -7
  633. package/scripts/review/review-record-cli.ts +73 -16
  634. package/scripts/review/review-record.ts +5 -4
  635. package/scripts/review/review-round2-cli.ts +2 -3
  636. package/scripts/review/review-round2.ts +13 -21
  637. package/scripts/review/review-stamps.ts +9 -71
  638. package/scripts/review/review-tree.ts +4 -5
  639. package/scripts/rules/bash-triggers.ts +4 -4
  640. package/scripts/rules/decision-oracle-batch.ts +5 -6
  641. package/scripts/rules/decision-oracle-stage.ts +1 -1
  642. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  643. package/scripts/rules/decision-oracle.ts +2 -2
  644. package/scripts/rules/delivered-rules.ts +61 -406
  645. package/scripts/rules/destructive-command.ts +2 -2
  646. package/scripts/rules/direct-filing.ts +4 -4
  647. package/scripts/rules/direct-pr-create.ts +2 -2
  648. package/scripts/rules/early-heartbeat.ts +15 -19
  649. package/scripts/rules/file-body.ts +5 -6
  650. package/scripts/rules/filing-cap.ts +6 -7
  651. package/scripts/rules/filing-offer.ts +1 -1
  652. package/scripts/rules/firing-point.ts +6 -6
  653. package/scripts/rules/gh-api.ts +2 -2
  654. package/scripts/rules/git-argv.ts +3 -3
  655. package/scripts/rules/git-force.ts +2 -2
  656. package/scripts/rules/hook-context-line.ts +31 -0
  657. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  658. package/scripts/rules/implementation-cut.ts +35 -32
  659. package/scripts/rules/index-guard.ts +2 -2
  660. package/scripts/rules/issue-citation.ts +7 -7
  661. package/scripts/rules/issue-comments.ts +21 -13
  662. package/scripts/rules/josh-git-bare.ts +2 -2
  663. package/scripts/rules/lane-background.ts +14 -16
  664. package/scripts/rules/lane-carry-conflict.ts +41 -5
  665. package/scripts/rules/lane-interactive-ask.ts +6 -9
  666. package/scripts/rules/lane-park.ts +12 -16
  667. package/scripts/rules/lane-split-park.ts +1 -2
  668. package/scripts/rules/lane-switch-main.ts +10 -13
  669. package/scripts/rules/last-prompt.ts +1 -1
  670. package/scripts/rules/oracle-consulted.ts +5 -5
  671. package/scripts/rules/oracle-firing.ts +6 -9
  672. package/scripts/rules/oracle-list-cli.ts +2 -2
  673. package/scripts/rules/permission-guards.ts +2 -2
  674. package/scripts/rules/piped-verification.ts +79 -9
  675. package/scripts/rules/poll-loop.ts +9 -11
  676. package/scripts/rules/pre-gate-cut.ts +33 -30
  677. package/scripts/rules/prior-comment-read.ts +3 -3
  678. package/scripts/rules/protected-files.ts +25 -13
  679. package/scripts/rules/raw-field-body.ts +3 -4
  680. package/scripts/rules/reply-language.ts +1 -1
  681. package/scripts/rules/rule-body-guard.ts +10 -12
  682. package/scripts/rules/rule-guard.ts +1 -1
  683. package/scripts/rules/rule-list.ts +51 -0
  684. package/scripts/rules/rule-registry-rows.ts +282 -0
  685. package/scripts/rules/rule-registry.ts +109 -0
  686. package/scripts/rules/rule-value-cache.ts +2 -2
  687. package/scripts/rules/rule-value-cli.ts +6 -4
  688. package/scripts/rules/rule-value.ts +61 -22
  689. package/scripts/rules/run-tail-rule.ts +11 -15
  690. package/scripts/rules/shell-body-trigger.ts +7 -7
  691. package/scripts/rules/shell-segments.ts +2 -4
  692. package/scripts/rules/stop-rules.ts +54 -41
  693. package/scripts/rules/tail-commands.ts +1 -1
  694. package/scripts/rules/test-declared-commit.ts +2 -2
  695. package/scripts/rules/third-party-write.ts +3 -3
  696. package/scripts/rules/worktree-guard.ts +12 -5
  697. package/scripts/run/add/run-add-cli.ts +165 -0
  698. package/scripts/run/add/run-add.ts +124 -0
  699. package/scripts/run/board/run-board-cli.ts +207 -0
  700. package/scripts/run/board/run-board-closed.ts +95 -0
  701. package/scripts/run/board/run-board-every.ts +60 -0
  702. package/scripts/run/board/run-board-fetch.ts +38 -0
  703. package/scripts/run/board/run-board-fit.ts +219 -0
  704. package/scripts/run/board/run-board-github.ts +162 -0
  705. package/scripts/run/board/run-board-header.ts +275 -0
  706. package/scripts/run/board/run-board-kind.ts +35 -0
  707. package/scripts/run/board/run-board-labels.ts +299 -0
  708. package/scripts/run/board/run-board-layout.ts +222 -0
  709. package/scripts/run/board/run-board-link.ts +31 -0
  710. package/scripts/run/board/run-board-machine.ts +198 -0
  711. package/scripts/run/board/run-board-notes.ts +103 -0
  712. package/scripts/run/board/run-board-phase.ts +136 -0
  713. package/scripts/run/board/run-board-plan.ts +129 -0
  714. package/scripts/run/board/run-board-read.ts +62 -0
  715. package/scripts/run/board/run-board-render-legend.ts +82 -0
  716. package/scripts/run/board/run-board-render-notes.ts +77 -0
  717. package/scripts/run/board/run-board-render-slot.ts +50 -0
  718. package/scripts/run/board/run-board-render.ts +407 -0
  719. package/scripts/run/board/run-board-scope.ts +17 -0
  720. package/scripts/run/board/run-board-screen.ts +43 -0
  721. package/scripts/run/board/run-board-span.ts +66 -0
  722. package/scripts/run/board/run-board-spin.ts +115 -0
  723. package/scripts/run/board/run-board-state.ts +113 -0
  724. package/scripts/run/board/run-board-status.ts +279 -0
  725. package/scripts/run/board/run-board-tick.ts +210 -0
  726. package/scripts/run/board/run-board-track.ts +22 -0
  727. package/scripts/run/board/run-board-usage-read.ts +255 -0
  728. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  729. package/scripts/run/board/run-board-usage-text.ts +80 -0
  730. package/scripts/run/board/run-board-usage.ts +165 -0
  731. package/scripts/run/carry/run-carry-added.ts +62 -0
  732. package/scripts/run/carry/run-carry-args.ts +25 -22
  733. package/scripts/run/carry/run-carry-change.ts +1 -1
  734. package/scripts/run/carry/run-carry-cli.ts +71 -48
  735. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  736. package/scripts/run/carry/run-carry-ended.ts +85 -0
  737. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  738. package/scripts/run/carry/run-carry-stash.ts +3 -2
  739. package/scripts/run/carry/run-carry-streak.ts +8 -10
  740. package/scripts/run/carry/run-carry.ts +85 -89
  741. package/scripts/run/cut/run-cut-args.ts +7 -7
  742. package/scripts/run/cut/run-cut-cli.ts +54 -36
  743. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  744. package/scripts/run/cut/run-cut-report.ts +37 -16
  745. package/scripts/run/cut/run-cut.ts +63 -77
  746. package/scripts/run/detached-launch.ts +35 -50
  747. package/scripts/run/entry/run-entry-cli.ts +48 -27
  748. package/scripts/run/entry/run-entry-stop.ts +7 -9
  749. package/scripts/run/entry/run-entry.ts +5 -6
  750. package/scripts/run/event/run-event-cli.ts +5 -6
  751. package/scripts/run/event/run-event-filed.ts +69 -0
  752. package/scripts/run/event/run-event-follow.ts +3 -3
  753. package/scripts/run/event/run-event-plan.ts +38 -0
  754. package/scripts/run/event/run-event-render.ts +9 -4
  755. package/scripts/run/event/run-event-scope.ts +47 -18
  756. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  757. package/scripts/run/event/run-event-stream.ts +171 -46
  758. package/scripts/run/event/run-event-watch.ts +4 -6
  759. package/scripts/run/hold/run-hold-cli.ts +65 -62
  760. package/scripts/run/hold/run-hold.ts +88 -46
  761. package/scripts/run/merge/run-merge-cli.ts +116 -77
  762. package/scripts/run/merge/run-merge-collect.ts +107 -0
  763. package/scripts/run/merge/run-merge-steps.ts +112 -65
  764. package/scripts/run/merge/run-merge-token.ts +30 -0
  765. package/scripts/run/merge/run-merge.ts +31 -22
  766. package/scripts/run/progress/run-progress-args.ts +4 -4
  767. package/scripts/run/progress/run-progress-cli.ts +39 -50
  768. package/scripts/run/progress/run-progress-clock.ts +25 -32
  769. package/scripts/run/progress/run-progress-config.ts +6 -9
  770. package/scripts/run/progress/run-progress-read.ts +9 -10
  771. package/scripts/run/progress/run-progress.ts +48 -53
  772. package/scripts/run/review/run-review-cli.ts +6 -6
  773. package/scripts/run/review/run-review-steps.ts +6 -6
  774. package/scripts/run/review/run-review.ts +9 -11
  775. package/scripts/run/run-cli-fault.ts +29 -0
  776. package/scripts/run/run-ending-cli.ts +3 -3
  777. package/scripts/run/run-ending.ts +10 -14
  778. package/scripts/run/run-halfrun-resume.ts +6 -8
  779. package/scripts/run/run-headless.ts +25 -12
  780. package/scripts/run/run-invocation.ts +17 -22
  781. package/scripts/run/run-label.ts +7 -5
  782. package/scripts/run/run-liveness-cli.ts +19 -6
  783. package/scripts/run/run-liveness.ts +27 -38
  784. package/scripts/run/run-next-cli.ts +5 -9
  785. package/scripts/run/run-next.ts +4 -5
  786. package/scripts/run/run-parent-cut-hook.ts +10 -12
  787. package/scripts/run/run-preflight.ts +25 -29
  788. package/scripts/run/run-prep-cli.ts +17 -13
  789. package/scripts/run/run-prep-locate.ts +4 -5
  790. package/scripts/run/run-prep.ts +7 -10
  791. package/scripts/run/run-prrun-resume.ts +2 -2
  792. package/scripts/run/run-report-cli.ts +4 -4
  793. package/scripts/run/run-report.ts +9 -14
  794. package/scripts/run/run-retrospective.ts +3 -3
  795. package/scripts/run/run-section.ts +42 -0
  796. package/scripts/run/run-stage-read.ts +2 -2
  797. package/scripts/run/run-stage.ts +6 -4
  798. package/scripts/run/run-status-cli.ts +7 -5
  799. package/scripts/run/run-status.ts +6 -7
  800. package/scripts/run/run-step-cli.ts +13 -15
  801. package/scripts/run/run-step.ts +58 -47
  802. package/scripts/run/run-stop-notify.ts +7 -8
  803. package/scripts/run/run-stranded-cli.ts +1 -1
  804. package/scripts/run/run-stranded-detect.ts +4 -4
  805. package/scripts/run/run-stranded.ts +11 -13
  806. package/scripts/run/run-tail-cli.ts +15 -16
  807. package/scripts/run/run-tail.ts +14 -33
  808. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  809. package/scripts/run/run-watcher-guard.ts +11 -12
  810. package/scripts/run/run-watcher-hook.ts +6 -12
  811. package/scripts/run/ship/run-ship-cli.ts +67 -33
  812. package/scripts/run/ship/run-ship-detach.ts +15 -13
  813. package/scripts/run/ship/run-ship-lock.ts +1 -1
  814. package/scripts/run/ship/run-ship-next.ts +7 -8
  815. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  816. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  817. package/scripts/run/ship/run-ship-probe.ts +4 -4
  818. package/scripts/run/ship/run-ship-return.ts +1 -1
  819. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  820. package/scripts/run/ship/run-ship-review.ts +12 -14
  821. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  822. package/scripts/run/ship/run-ship-stage.ts +80 -26
  823. package/scripts/run/ship/run-ship-steps.ts +26 -16
  824. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  825. package/scripts/run/ship/run-ship-sync.ts +9 -8
  826. package/scripts/run/ship/run-ship.ts +17 -32
  827. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  828. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  829. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  830. package/scripts/run/tidy/run-tidy.ts +4 -3
  831. package/scripts/run/wake/run-wake-cli.ts +27 -32
  832. package/scripts/run/wake/run-wake-describe.ts +24 -28
  833. package/scripts/run/wake/run-wake-driver.ts +14 -14
  834. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  835. package/scripts/run/wake/run-wake-loop.ts +9 -9
  836. package/scripts/run/wake/run-wake-restart.ts +4 -5
  837. package/scripts/run/wake/run-wake-session.ts +23 -27
  838. package/scripts/run/wake/run-wake.ts +57 -279
  839. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  840. package/scripts/safe-chain/pack-hook.ts +2 -2
  841. package/scripts/safe-chain/preinstall-command.ts +2 -2
  842. package/scripts/security/security-audit-logic.ts +1 -1
  843. package/scripts/security/security-audit-provision-logic.ts +1 -1
  844. package/scripts/security/security-audit-provision.ts +2 -2
  845. package/scripts/security/security-audit.ts +5 -5
  846. package/scripts/security/security-updates-logic.ts +2 -3
  847. package/scripts/security/security-updates.ts +2 -4
  848. package/scripts/self-sync-guard/index.ts +1 -1
  849. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  850. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  851. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  852. package/scripts/sonar/sonar-hotspots.ts +1 -1
  853. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  854. package/scripts/sonar/sonar-new-code.ts +1 -1
  855. package/scripts/sonar/sonar-project.ts +1 -1
  856. package/scripts/split/split-assess-cli.ts +1 -1
  857. package/scripts/split/split-assess.ts +3 -3
  858. package/scripts/sync/directory-copy-guard.ts +2 -3
  859. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  860. package/scripts/sync/managed-config-scope.ts +4 -4
  861. package/scripts/sync/plugin-skill-directories.ts +2 -2
  862. package/scripts/sync/reconcile-templates.ts +17 -8
  863. package/scripts/sync/removed-skill-manifest.ts +2 -3
  864. package/scripts/sync/sync-ai-files.ts +7 -7
  865. package/scripts/sync/sync-configs.ts +30 -3
  866. package/scripts/sync/sync-hook-safety.ts +2 -2
  867. package/scripts/sync/sync.ts +23 -10
  868. package/scripts/sync/synced-paths.ts +2 -1
  869. package/scripts/sync/workflow-pin-logic.ts +1 -1
  870. package/scripts/test/test-declared-changed.ts +4 -4
  871. package/scripts/test/test-declared-logic.ts +2 -3
  872. package/scripts/test/test-declared-match.ts +25 -4
  873. package/scripts/test/test-declared.ts +26 -9
  874. package/scripts/test/test-red-commit.ts +3 -2
  875. package/scripts/test/test-red-logic.ts +7 -14
  876. package/scripts/test/test-red.ts +12 -47
  877. package/scripts/test/test-related-scope.ts +2 -3
  878. package/scripts/test/test-related.ts +3 -3
  879. package/scripts/test/test-type-logic.ts +1 -2
  880. package/scripts/test/test-unit-guard.ts +13 -17
  881. package/scripts/test/unit-worker-share.ts +7 -8
  882. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  883. package/scripts/time-runtime/time-background.ts +17 -21
  884. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  885. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  886. package/scripts/time-runtime/time-bundles.ts +11 -12
  887. package/scripts/time-runtime/time-call-identity.ts +1 -1
  888. package/scripts/time-runtime/time-command-key.ts +2 -2
  889. package/scripts/time-runtime/time-density-hook.ts +8 -11
  890. package/scripts/time-runtime/time-density.ts +5 -5
  891. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  892. package/scripts/time-runtime/time-format.ts +5 -5
  893. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  894. package/scripts/time-runtime/time-instant.ts +1 -1
  895. package/scripts/time-runtime/time-markers.ts +15 -19
  896. package/scripts/time-runtime/time-phase-names.ts +3 -3
  897. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  898. package/scripts/time-runtime/time-round-trips.ts +20 -23
  899. package/scripts/time-runtime/time-shell.ts +8 -8
  900. package/scripts/time-runtime/time-single-check.ts +1 -2
  901. package/scripts/time-runtime/time-spans.ts +35 -40
  902. package/scripts/time-runtime/time-tool-call.ts +15 -16
  903. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  904. package/scripts/time-runtime/time-writes.ts +5 -5
  905. package/scripts/ui/ui-routes-cli.ts +1 -2
  906. package/scripts/ui/ui-routes.ts +1 -2
  907. package/scripts/version/bump-version.ts +1 -1
  908. package/scripts/version/fresh-metadata-cache.ts +2 -2
  909. package/scripts/version/latest-corepack.ts +26 -26
  910. package/scripts/version/latest-lane-guard.ts +1 -1
  911. package/scripts/version/latest-scope-cli.ts +2 -2
  912. package/scripts/version/latest-stamp.ts +1 -2
  913. package/scripts/version/latest-update.ts +2 -2
  914. package/scripts/version/npm-registry.ts +2 -2
  915. package/scripts/version/package-manager-version.ts +18 -0
  916. package/scripts/version/publishable-range-check.ts +2 -1
  917. package/scripts/version/publishable-range.ts +1 -1
  918. package/scripts/version/release-age.ts +11 -11
  919. package/scripts/version/release-hold.ts +2 -2
  920. package/scripts/version/safe-chain-version-update.ts +3 -3
  921. package/scripts/version/version-check-logic.ts +2 -3
  922. package/scripts/version/version-check.ts +1 -2
  923. package/scripts/version/version-command-config.ts +2 -2
  924. package/scripts/version/version-commands.ts +3 -3
  925. package/scripts/version/version-remote.ts +4 -4
  926. package/scripts/version/version-targets.ts +2 -2
  927. package/templates/gitignore +7 -0
  928. package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
  929. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  930. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  931. package/scripts/backlog/backlog-restructure.ts +0 -152
  932. package/scripts/rules/issue-fold-rule.ts +0 -72
  933. package/scripts/rules/wip-cap.ts +0 -63
  934. package/scripts/run/run-issue-number.ts +0 -19
@@ -10,9 +10,9 @@ import { cutoff_cause, cutoff_of, type ScanCutoff } from '#scripts/git/listing-c
10
10
  import { read_json_listing } from '#scripts/git/parse-json-array'
11
11
  import { git_next_issues } from '#scripts/issue/git-next-issues'
12
12
  import { AUTO_OK_LABEL } from '#scripts/issue/issue-labels'
13
+ import { session_cite } from '#scripts/issue/session-cite'
13
14
 
14
- // `josh auto-ok:next` — which issue outside the epic an unattended run picks up next
15
- // (joshuafolkken/kit#906).
15
+ // `josh auto-ok:next` — which issue outside the epic an unattended run picks up next.
16
16
  //
17
17
  // A command rather than a documented `gh` invocation, for the reason the label constant exists: the
18
18
  // name `auto-ok` is single-sourced in `scripts/issue/issue-labels.ts`, and a procedure that told an
@@ -33,29 +33,23 @@ const USAGE = `Usage: josh auto-ok:next [${EXCLUDE_FLAG} <issue-number>[,<issue-
33
33
  const NONE_TOKEN = 'none'
34
34
  // Wide enough that the cap is never what decides the order. The listing is newest first because
35
35
  // `git-gh-issue-list.ts` spells `sort=created&direction=desc` into every request rather than leaning
36
- // on REST's default (joshuafolkken/kit#1025), so a truncated listing drops the *oldest* opted-in
36
+ // on REST's default, so a truncated listing drops the *oldest* opted-in
37
37
  // issues — which is reported rather than silently ranked.
38
38
  const LISTING_LIMIT = 200
39
39
 
40
40
  // Two different gaps, told apart because they send a person to two different places. A listing that
41
41
  // never arrived is an access or connectivity problem; a listing that arrived in a shape the schema
42
42
  // rejects is the rows' fields having changed under the REST mapping in `git-gh-issue-rest.ts`, where
43
- // `gh auth status` is green and checking it wastes the one hint the message had to give
44
- // (joshuafolkken/kit#996).
45
- //
46
- // The second message named `gh --version` until joshuafolkken/kit#1069. The listing has been REST
47
- // since joshuafolkken/kit#1025 and `git-gh-issue-list.ts` builds the JSON this parser reads, so the
48
- // CLI's version cannot be what changed the row shape — the same misdirection the message below
49
- // already refuses to repeat for the blocker relations, left standing one constant above it.
43
+ // `gh auth status` is green and checking it wastes the one hint the message had to give. Neither
44
+ // names `gh --version`: the listing is REST and `git-gh-issue-list.ts` builds the JSON this parser
45
+ // reads, so the CLI's version cannot be what changed the row shape.
50
46
  const UNREADABLE_MESSAGE = `Could not read the \`${AUTO_OK_LABEL}\` listing. That is not "nothing is opted in" — check \`gh auth status\` and ask again.`
51
47
  const UNEXPECTED_SHAPE_MESSAGE = `Read the \`${AUTO_OK_LABEL}\` listing but could not parse it. That is not "nothing is opted in" — the rows came back in a shape this command does not recognize, so check the fields it asks for and the REST field mapping in \`scripts/gh/git-gh-issue-rest.ts\` rather than your authentication.`
52
48
  // The blocker relations failing takes the whole listing with them, and `issue_list` swallows
53
49
  // the error — so the read looks exactly like an access failure and sends the reader to
54
- // `gh auth status`, which is green. That is the misdirection joshuafolkken/kit#996 added the message
55
- // above to remove, walked straight back in by the field the same change started asking for
56
- // (joshuafolkken/kit#1005).
50
+ // `gh auth status`, which is green — the misdirection the message above exists to remove.
57
51
  //
58
- // The listing is REST now, so the cause is no longer `gh`'s version: the relations come from each
52
+ // The cause is not `gh`'s version either: the relations come from each
59
53
  // issue's own `dependencies/blocked_by` endpoint, and it is those requests — not the CLI — that the
60
54
  // probe has just shown to be the difference. Naming `gh --version` here would send a reader on a
61
55
  // current `gh` to the one place the answer is not.
@@ -63,12 +57,12 @@ const UNEXPECTED_SHAPE_MESSAGE = `Read the \`${AUTO_OK_LABEL}\` listing but coul
63
57
  // It names both causes rather than asserting one. The probe separates "the relations" from "the
64
58
  // listing", and it cannot separate a host that does not serve dependencies from a rate limit reached
65
59
  // by the one-request-per-blocked-issue pass — so claiming the first would be the same misdirection
66
- // in a new place (joshuafolkken/kit#1025).
60
+ // in a new place.
67
61
  const BLOCKERS_UNREADABLE_MESSAGE = `Could not read the \`${AUTO_OK_LABEL}\` listing, though the same listing reads once the blocker relations are dropped from it — so it is reading the relations that failed, not your authentication. That is one \`dependencies/blocked_by\` request per opted-in issue declaring a blocker: either this GitHub host does not serve issue dependencies, or those requests are being rate limited. Ask again, and check the host if it persists.`
68
62
  // Said once the answer is known, so it never claims there is an answer below when there is not.
69
63
  // Either cutoff only ever drops the *oldest* opted-in issues, the listing being newest first, so the
70
64
  // consequence is one sentence — but the two cite different numbers and a reader who wants the
71
- // listing widened reaches for a different knob for each (joshuafolkken/kit#1067).
65
+ // listing widened reaches for a different knob for each.
72
66
  const TRUNCATED_BY_LIMIT = `hit the ${String(LISTING_LIMIT)}-issue cap`
73
67
  const TRUNCATED_WITH_ANSWER =
74
68
  '; the answer below is opted in, but it may not be the highest-priority one.'
@@ -81,8 +75,8 @@ function truncated_cause(cutoff: ScanCutoff): string | undefined {
81
75
 
82
76
  const NONE_OPTED_IN_MESSAGE = `No open issue carries \`${AUTO_OK_LABEL}\`.`
83
77
  // The epic listing failing is not "no epic tracks anything". Read that way, every child of every
84
- // epic reads as a standalone candidate and the pickup hands one back out of its epic's order — the
85
- // single failure joshuafolkken/kit#1633 is about, arriving with exit 0 and nothing said.
78
+ // epic reads as a standalone candidate and the pickup hands one back out of its epic's order,
79
+ // arriving with exit 0 and nothing said.
86
80
  const EPICS_UNREADABLE_MESSAGE = `Could not read the epic listing, so which issues an epic already tracks is unknown. That is not "no epic tracks anything" — an opted-in child would be handed back outside its epic's order, so no answer is given. Check \`gh auth status\` and ask again.`
87
81
  const CLOSED_STATE = 'CLOSED'
88
82
  const NO_CUTOFF: ScanCutoff = 'none'
@@ -91,12 +85,12 @@ const NO_CUTOFF: ScanCutoff = 'none'
91
85
  // effect asynchronously, so for a few seconds after a merge the issue is still listed as open —
92
86
  // which is why `prioritize` takes this number at all, and why a pickup loop that never passes it
93
87
  // leaves an already-merged issue to be excluded only by the `in-progress` label it happens to still
94
- // carry (joshuafolkken/kit#906).
88
+ // carry.
95
89
  interface NextOptions {
96
90
  // Every number the caller asked to skip. A pickup loop passes the ones it has already run this
97
91
  // session, not just the last: `closes #N` can fail to fire — a reference dropped from a PR body —
98
92
  // and the `in-progress` label the procedure itself calls an unreliable guard is then the only
99
- // thing standing between the loop and running an issue twice (joshuafolkken/kit#996).
93
+ // thing standing between the loop and running an issue twice.
100
94
  exclude?: ReadonlyArray<number>
101
95
  usage?: string
102
96
  }
@@ -134,7 +128,7 @@ function parse_pair(argv: ReadonlyArray<string>, index: number): ReadonlyArray<n
134
128
  // argument.
135
129
  //
136
130
  // `usage` is a parameter so a second command with the same `--exclude` grammar reuses this rather
137
- // than copying the loop — `josh backlog:next` does (joshuafolkken/kit#1630). Only the line printed on
131
+ // than copying the loop — `josh backlog:next` does. Only the line printed on
138
132
  // a bad argument differs between them, and a caller that passes nothing gets this command's own.
139
133
  function parse_options(argv: ReadonlyArray<string>, usage: string = USAGE): NextOptions {
140
134
  const exclude: Array<number> = []
@@ -150,23 +144,22 @@ function parse_options(argv: ReadonlyArray<string>, usage: string = USAGE): Next
150
144
 
151
145
  // Every open issue carrying the label, or which of two gaps stopped the read. Neither gap is an
152
146
  // empty listing: reading a failed read as "none" ends the run reporting a confident absence built on
153
- // a response nobody parsed (joshuafolkken/kit#950). They stay apart from each other because the zod
147
+ // a response nobody parsed. They stay apart from each other because the zod
154
148
  // rejection `parse_json_array_or_undefined` deliberately rethrows means the listing's *fields*
155
- // changed, not that the caller's authentication lapsed (joshuafolkken/kit#996).
149
+ // changed, not that the caller's authentication lapsed.
156
150
  type OptedInRead =
157
151
  | { kind: 'read'; issues: Array<OpenIssueData>; cutoff: ScanCutoff }
158
152
  | { kind: 'unreadable' }
159
153
  | { kind: 'unexpected_shape' }
160
154
  | { kind: 'blockers_unreadable' }
161
155
 
162
- // The two gaps `read_json_listing` names, carried through unchanged. Since joshuafolkken/kit#1025
163
- // `raw` is the JSON `git-gh-issue-list.ts` assembles from the REST rows rather than a CLI's stdout,
156
+ // The two gaps `read_json_listing` names, carried through unchanged. `raw` is the JSON `git-gh-issue-list.ts` assembles from the REST rows rather than a CLI's stdout,
164
157
  // so a transport failure — a rate limit, a dropped connection — never reaches this parser at all:
165
158
  // `issue_list` catches it into `json === undefined` and `classify_failed_read` decides what it
166
159
  // was. What does reach here is the rethrown zod rejection, meaning the listing arrived and its
167
160
  // *fields* were not what was asked for. `unreadable` is passed on rather than folded away because
168
- // reading a gap as an empty listing is the confident absence kit#950 exists to prevent, and this is
169
- // not the place to make that assumption.
161
+ // reading a gap as an empty listing is a confident absence built on a response nobody parsed, and
162
+ // this is not the place to make that assumption.
170
163
  function parse_listing(raw: string, is_capped: boolean): OptedInRead {
171
164
  const read = read_json_listing(raw, open_issue_schema)
172
165
  if (read.kind !== 'read') return { kind: read.kind }
@@ -180,8 +173,7 @@ function parse_listing(raw: string, is_capped: boolean): OptedInRead {
180
173
 
181
174
  // Whether the *identical* listing reads once `blockedBy` is dropped from it. Named for what it
182
175
  // answers rather than for what it implies, because the two are opposite: a `true` here means the
183
- // field was the problem, and an earlier spelling returned the failure instead — correct only because
184
- // its one call site inverted it back (joshuafolkken/kit#1005).
176
+ // field was the problem.
185
177
  //
186
178
  // **Only the field list changes.** Varying the limit as well would let a rate limit or a timeout that
187
179
  // a smaller request happens to survive read as the blocker relations failing, on a host that serves
@@ -200,8 +192,7 @@ async function reads_without_blocked_by(): Promise<boolean> {
200
192
  // success of that form is not enough on its own: a network blip or a passing rate limit on the first
201
193
  // read clears by the time the probe runs, and the run would then send someone whose host serves
202
194
  // dependencies perfectly well to look at it. `issue_list` swallows the underlying error, so
203
- // repeating the original read is what separates a transient failure from a standing one
204
- // (joshuafolkken/kit#1005).
195
+ // repeating the original read is what separates a transient failure from a standing one.
205
196
  async function classify_failed_read(): Promise<OptedInRead> {
206
197
  if (!(await reads_without_blocked_by())) return { kind: 'unreadable' }
207
198
 
@@ -226,14 +217,12 @@ async function fetch_opted_in(): Promise<OptedInRead> {
226
217
  // relation `epic:next` builds its graph from, and each blocker's state comes back alongside its
227
218
  // number, so no blocker needs a read of its own.
228
219
  //
229
- // The relations are not in the listing response at all since joshuafolkken/kit#1025 — REST serves
230
- // them from each issue's own dependencies endpoint — so this pickup pays one extra request per row
220
+ // The relations are not in the listing response at all — REST serves them from each issue's own dependencies endpoint — so this pickup pays one extra request per row
231
221
  // whose own dependency summary does not report exactly zero blockers, and nothing for the rest.
232
222
  //
233
223
  // An unattended run must not start an issue whose prerequisite is still open: `auto-ok` is applied
234
- // by a person to an issue they judged needs no decision, which says nothing about ordering, and the
235
- // pickup previously consulted only the `epic` / `in-progress` / `needs-decision` labels
236
- // (joshuafolkken/kit#996). A blocker with no state reads as standing — the safe direction, since the
224
+ // by a person to an issue they judged needs no decision, which says nothing about ordering.
225
+ // A blocker with no state reads as standing — the safe direction, since the
237
226
  // cost is deferring an issue rather than implementing one out of order.
238
227
  // `nodes` is a page — fifty under GraphQL, one hundred under REST. When `totalCount` says there are
239
228
  // more, the ones outside the page are unknown, and unknown reads as standing — the same direction
@@ -248,7 +237,7 @@ function is_page_complete(blocked_by: OpenIssueData['blockedBy']): boolean {
248
237
 
249
238
  // `epic_issue.normalize_state` rather than a second spelling of it: the epic commands already read
250
239
  // GitHub's state casing through one function, and "is this blocker closed" is the question it
251
- // answers (joshuafolkken/kit#862). A blocker reported without a state reads as standing.
240
+ // answers. A blocker reported without a state reads as standing.
252
241
  function is_closed(blocker: { state?: string | undefined }): boolean {
253
242
  return epic_issue.normalize_state(blocker.state ?? '') === CLOSED_STATE
254
243
  }
@@ -261,21 +250,20 @@ function is_unblocked(issue: OpenIssueData): boolean {
261
250
 
262
251
  // Which issues an epic already tracks, or that the epic listing could not be read.
263
252
  //
264
- // **The question is membership, not a label** (joshuafolkken/kit#1633). An epic's child carries none
253
+ // **The question is membership, not a label**. An epic's child carries none
265
254
  // of `epic` / `in-progress` / `needs-decision`, so the label comparison inside `prioritize` never
266
- // saw one — and `auto-ok` on a child put that child in the standalone candidate set, where the
255
+ // sees one — and `auto-ok` on a child would put that child in the standalone candidate set, where the
267
256
  // epic's `blockedBy` ordering is never consulted. The epics themselves are still found by the `epic`
268
257
  // label, exactly as `epic:bundle` finds them, so this does not survive an epic that never received
269
- // it — what it removes is the *child's* labels deciding, which is the half that was failing.
258
+ // it — what it removes is the *child's* labels deciding.
270
259
  //
271
- // **The whole index is carried rather than its key set** (joshuafolkken/kit#1668). Which epic tracks
260
+ // **The whole index is carried rather than its key set**. Which epic tracks
272
261
  // a child decides both whether the standalone half withholds it — `epic_index.withheld_children` —
273
- // and, when it is withheld, the number `backlog:plan` names as the reason. Flattening to a `Set`
274
- // here threw that number away, so the plan reported a listing cap it had never reached.
262
+ // and, when it is withheld, the number `backlog:plan` names as the reason.
275
263
  //
276
- // **And every tracking epic, not one winner** (joshuafolkken/kit#1694). Two epics can name the same
264
+ // **And every tracking epic, not one winner**. Two epics can name the same
277
265
  // child, and a map of one epic per child keeps whichever came last — so an opted-in epic that came
278
- // earlier vanished, and the child was offered standalone *and* through that epic.
266
+ // earlier would vanish, and the child be offered standalone *and* through that epic.
279
267
  type TrackingRead =
280
268
  | { kind: 'read'; index: ReadonlyMap<number, ReadonlyArray<number>>; cutoff: ScanCutoff }
281
269
  | { kind: 'epics_unreadable' }
@@ -313,8 +301,7 @@ async function fetch_tracking(count: number): Promise<TrackingRead> {
313
301
  // The pickup *order* is `git_next_issues.order` itself, not a copy of it: the ranking `prioritize`
314
302
  // shows, with the `epic` / `in-progress` / `needs-decision` exclusions, before its display cap.
315
303
  //
316
- // The two are no longer the same *set*, and deliberately so: since joshuafolkken/kit#996 the pickup
317
- // also drops a candidate whose prerequisite is still open, while `🗒 Next issues` shows every open
304
+ // The two are not the same *set*, and deliberately so: the pickup also drops a candidate whose prerequisite is still open, while `🗒 Next issues` shows every open
318
305
  // issue and leaves the judgement to the person reading it. So the display can name an issue this
319
306
  // command refuses — a person can see a blocked issue is next and decide to start it anyway, and an
320
307
  // unattended run must not.
@@ -326,20 +313,19 @@ async function fetch_tracking(count: number): Promise<TrackingRead> {
326
313
  // `prioritize`'s capped one, which would answer `none` whenever its first rows happen to be blocked
327
314
  // while a runnable issue sits below them. They are applied **after** the ranking, not before it: the
328
315
  // dependents key counts the issues waiting on a row, and a waiting issue is by definition blocked —
329
- // filtered first, every row would count zero and the key would never decide anything
330
- // (joshuafolkken/kit#2928).
316
+ // filtered first, every row would count zero and the key would never decide anything.
331
317
  //
332
318
  // The `🗒 Next issues` display is deliberately *not* filtered this way; `git-next-issues.ts` records
333
319
  // why, and the short version is that a person can see a blocked issue and choose to start it anyway
334
- // while an unattended run cannot (joshuafolkken/kit#1005).
320
+ // while an unattended run cannot.
335
321
  //
336
322
  // A child of an epic that is itself opted in is dropped here for the same reason and by the same
337
323
  // rule: that epic's declared order sequences its children, and it is going to offer them, so a
338
- // standalone offer would skip the order and hand the same issue over twice (joshuafolkken/kit#1633).
339
- // **A child of an epic that is *not* opted in is no longer dropped** — no path would ever offer it,
340
- // which made a person's `auto-ok` on the child silently inert, and the order it does have is carried
341
- // by the native `blockedBy` relations `is_unblocked` already refuses to run past
342
- // (joshuafolkken/kit#1668). `tracked` is the narrowed set `epic_index.withheld_children` builds, not
324
+ // standalone offer would skip the order and hand the same issue over twice.
325
+ // **A child of an epic that is *not* opted in is kept** — no path would otherwise offer it, which
326
+ // would make a person's `auto-ok` on the child silently inert, and the order it does have is carried
327
+ // by the native `blockedBy` relations `is_unblocked` already refuses to run past.
328
+ // `tracked` is the narrowed set `epic_index.withheld_children` builds, not
343
329
  // every tracked child; this function only applies it.
344
330
  function is_runnable(
345
331
  issue: OpenIssueData,
@@ -370,7 +356,7 @@ function none_reason(count: number): string {
370
356
 
371
357
  // Said only when the cap actually bit, and worded from the answer rather than before it: the one run
372
358
  // where truncation matters is the one where everything listed was excluded, and announcing "the
373
- // answer below is opted in" there contradicted the `none` that followed (joshuafolkken/kit#996).
359
+ // answer below is opted in" there contradicted the `none` that followed.
374
360
  function truncation_note(cutoff: ScanCutoff, has_answer: boolean): string | undefined {
375
361
  const cause = truncated_cause(cutoff)
376
362
  if (cause === undefined) return undefined
@@ -414,14 +400,14 @@ function report(context: PickupContext): number {
414
400
  return SUCCESS_EXIT_CODE
415
401
  }
416
402
 
417
- console.error(`#${String(next.number)} ${next.title}`)
403
+ console.error(session_cite.issue(next.number, next.title))
418
404
  console.info(String(next.number))
419
405
 
420
406
  return SUCCESS_EXIT_CODE
421
407
  }
422
408
 
423
409
  // The second listing runs only once the first one has an answer to filter, and its failure is
424
- // reported rather than folded into "no epic tracks anything" (joshuafolkken/kit#1633).
410
+ // reported rather than folded into "no epic tracks anything".
425
411
  async function answer(
426
412
  read: { issues: Array<OpenIssueData>; cutoff: ScanCutoff },
427
413
  exclude?: ReadonlyArray<number>,
@@ -444,7 +430,7 @@ async function answer(
444
430
  }
445
431
 
446
432
  // The gap that stopped the read decides the message, so a changed field list does not send anyone to
447
- // `gh auth status` (joshuafolkken/kit#996).
433
+ // `gh auth status`.
448
434
  const READ_FAILURE_MESSAGES = {
449
435
  unreadable: UNREADABLE_MESSAGE,
450
436
  unexpected_shape: UNEXPECTED_SHAPE_MESSAGE,
@@ -474,7 +460,7 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
474
460
  // `process.exitCode` rather than `process.exit()`: the answer is written with `console.info`, and on
475
461
  // macOS a write to a pipe is asynchronous — `process.exit()` can tear the process down before it has
476
462
  // drained, and this command's whole contract is `answer=$(pnpm josh auto-ok:next)`. The same shape
477
- // is already in `scripts/cost-runtime/cost-cli.ts`, which met the truncation first (joshuafolkken/kit#996).
463
+ // is already in `scripts/cost-runtime/cost-cli.ts`, which met the truncation first.
478
464
  async function main(argv: ReadonlyArray<string>): Promise<void> {
479
465
  process.exitCode = await run(argv)
480
466
  }
@@ -0,0 +1,34 @@
1
+ import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
2
+ import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
3
+
4
+ // Whether `pnpm josh run:add` handed the run an issue since the watcher started.
5
+ // The arrival probe reads the backlog once a minute, and a `--only` run's pool is empty by definition, so
6
+ // an added issue would otherwise wait for the minute — or never wake a `--only` parent at all. The event
7
+ // stream is a local file, so this is read on every tick rather than on the probe's interval.
8
+
9
+ type EventReader = () => Promise<ReadonlyArray<RunEvent>>
10
+
11
+ async function read_stream(): Promise<ReadonlyArray<RunEvent>> {
12
+ const target = await run_event_stream_emit.stream_target()
13
+
14
+ return target === undefined ? [] : run_event_stream.read_events(target)
15
+ }
16
+
17
+ function has_added_since(events: ReadonlyArray<RunEvent>, since_ms: number): boolean {
18
+ return events.some(
19
+ (event) => event.kind === run_event_stream.EVENT_KIND.ADD && Date.parse(event.at) >= since_ms,
20
+ )
21
+ }
22
+
23
+ // A stream that cannot be read is no addition: the probe's own backlog read is still the fallback.
24
+ async function is_added_since(since_ms: number, read: EventReader = read_stream): Promise<boolean> {
25
+ try {
26
+ return has_added_since(await read(), since_ms)
27
+ } catch {
28
+ return false
29
+ }
30
+ }
31
+
32
+ const backlog_arrival_added = { has_added_since, is_added_since }
33
+
34
+ export { backlog_arrival_added }
@@ -1,28 +1,30 @@
1
1
  import { epic_triage } from '#scripts/epic/epic-triage'
2
2
  import type { JoshResult } from '#scripts/josh/josh-run'
3
+ import { lane_limit_override } from '#scripts/lane/lane-limit-override'
3
4
  import { COMMAND_TIMEOUT_MS } from '#scripts/lib/timeouts'
4
5
  import { run_headless } from '#scripts/run/run-headless'
6
+ import { backlog_arrival_added } from './backlog-arrival-added'
5
7
  import { backlog_next } from './backlog-next'
6
8
  import { backlog_ready, type ReadyPorts, type ReadyReading } from './backlog-ready'
7
9
  import { backlog_stalled } from './backlog-stalled'
8
10
 
9
- // The arrival probe a `backlogrun` parent's `--wait` watcher runs while children are in flight
10
- // (joshuafolkken/kit#2503). An issue opted in with `auto-ok` mid-run was picked up only when the parent
11
- // next woke — a child's merge, or the progress interval — and in practice the ten-minute stall detector
12
- // became the pick-up: #2493 waited 10.5 minutes, and the person got a ⏳ notification for it.
11
+ // The arrival probe a `backlogrun` parent's `--wait` watcher runs while children are in flight.
12
+ // Without it, an issue opted in with `auto-ok` mid-run is picked up only when the parent
13
+ // next wakes — a child's merge, or the progress interval — so in practice the ten-minute stall detector
14
+ // becomes the pick-up, and the person gets a ⏳ notification for the wait.
13
15
  //
14
16
  // **The watcher's exit is the only thing that wakes a live parent**, so the probe rides it: once a
15
17
  // minute it reads the backlog the pick-up line reads (`backlog_ready.read_ready`, cheap first — a full
16
18
  // pool answers without the network read), and an issue runnable now that was not runnable when the
17
19
  // watcher started ends the wait. The exit prints the `ready #N` line as every exit does, and that line
18
- // is what sends the parent to `backlog:offer`. The stall detector goes back to being the safety net.
20
+ // is what sends the parent to `backlog:offer`. The stall detector stays the safety net.
19
21
  //
20
22
  // **"New" is measured against the watcher's own start**, so one issue wakes the parent once: the next
21
23
  // `--wait` the parent starts takes the pool as it stands then — the woken issue included, dispatched or
22
24
  // not — as its baseline. A reading that fails is not an arrival; the probe says nothing and reads again
23
25
  // a minute later. A baseline that cannot be read is never read as empty — an empty one would wake the
24
26
  // parent for the whole pool — but it is not given up on either: the scheduled report no longer ends the
25
- // wait (joshuafolkken/kit#3102), so an inert probe would leave the parent without a wake until `--hours`. The
27
+ // wait, so an inert probe would leave the parent without a wake until `--hours`. The
26
28
  // probe reads the baseline again each minute until one answers.
27
29
  //
28
30
  // **Every read is bounded.** The probe is awaited inside the watcher's tick loop, so a `gh` call that
@@ -54,7 +56,7 @@ function answered_issues(result: JoshResult | undefined): ReadonlyArray<string>
54
56
  }
55
57
 
56
58
  // `triage` names no number, yet the parent has work — so it is read as one token, which a reading
57
- // sees as an arrival (joshuafolkken/kit#2779).
59
+ // sees as an arrival.
58
60
  if (backlog_stalled.needs_triage(result.out)) return [epic_triage.TRIAGE_VERDICT]
59
61
 
60
62
  return backlog_stalled.ready_tokens(result.out)
@@ -64,20 +66,32 @@ async function bounded_ready_issues(): Promise<ReadonlyArray<string>> {
64
66
  return answered_issues(await backlog_ready.read_backlog_next(COMMAND_TIMEOUT_MS))
65
67
  }
66
68
 
67
- const ARRIVAL_PORTS: ReadyPorts = {
69
+ // The backlog reads, plus whether `run:add` handed the run an issue since a given instant.
70
+ interface ArrivalPorts extends ReadyPorts {
71
+ is_added_since: (since_ms: number) => Promise<boolean>
72
+ }
73
+
74
+ const ARRIVAL_PORTS: ArrivalPorts = {
68
75
  free_lane_count: backlog_ready.free_lane_count,
69
76
  ready_issues: bounded_ready_issues,
77
+ is_added_since: backlog_arrival_added.is_added_since,
70
78
  }
71
79
 
72
80
  interface ArrivalProbe {
73
81
  has_arrived: (now_ms: number) => Promise<boolean>
74
82
  }
75
83
 
76
- // Runnable now, not runnable at the start, and a lane free to take it.
77
- function arrivals(baseline: ReadonlySet<string>, reading: ReadyReading): ReadonlyArray<string> {
84
+ // Runnable now, not runnable at the start, and a lane free to take it. **A raised lane limit makes the
85
+ // whole pool new**: the issues the baseline holds were waiting for a lane, and
86
+ // the raise — unlike a merge — wakes nothing else, so the room it made would sit idle until a merge.
87
+ function arrivals(
88
+ baseline: ReadonlySet<string>,
89
+ reading: ReadyReading,
90
+ is_raised: boolean,
91
+ ): ReadonlyArray<string> {
78
92
  if (reading.free_lanes <= NO_FREE) return []
79
93
 
80
- return reading.issues.filter((issue) => !baseline.has(issue))
94
+ return is_raised ? reading.issues : reading.issues.filter((issue) => !baseline.has(issue))
81
95
  }
82
96
 
83
97
  // The baseline is the whole runnable pool, free lane or not: an issue that was waiting for a lane is not
@@ -132,10 +146,11 @@ async function retry_baseline(
132
146
  // The next-probe instant is set before any read is awaited. A baseline that did not answer is read again
133
147
  // at the next probe instead of the reading, and the first one that answers is the baseline from then on
134
148
  // — never an arrival itself, since it is the pool as it stands.
135
- function probe_of(
149
+ function pool_probe_of(
136
150
  initial: ReadonlySet<string> | undefined,
137
151
  first_ms: number,
138
152
  ports: ReadyPorts,
153
+ is_raised: () => boolean,
139
154
  ): ArrivalProbe {
140
155
  let next_ms = first_ms
141
156
  // At most one entry, held in a list so the baseline that answers after an await is added rather than
@@ -153,25 +168,47 @@ function probe_of(
153
168
 
154
169
  const reading = await read_reading(ports)
155
170
 
156
- return reading !== undefined && arrivals(baseline, reading).length > NONE
171
+ return reading !== undefined && arrivals(baseline, reading, is_raised()).length > NONE
172
+ }
173
+
174
+ return { has_arrived }
175
+ }
176
+
177
+ // An issue `run:add` handed the run since the watcher started wakes the parent at the next tick, ahead
178
+ // of the pool probe's minute.
179
+ function probe_of(
180
+ initial: ReadonlySet<string> | undefined,
181
+ started_ms: number,
182
+ ports: ArrivalPorts,
183
+ is_raised: () => boolean,
184
+ ): ArrivalProbe {
185
+ const pool = pool_probe_of(initial, started_ms + PROBE_INTERVAL_MS, ports, is_raised)
186
+
187
+ async function has_arrived(now_ms: number): Promise<boolean> {
188
+ if (await ports.is_added_since(started_ms)) return true
189
+
190
+ return await pool.has_arrived(now_ms)
157
191
  }
158
192
 
159
193
  return { has_arrived }
160
194
  }
161
195
 
162
196
  // Inert outside a driving `backlogrun` parent — a `fullrun` watcher has no pool to pick from — and there
163
- // it reads nothing at all.
197
+ // it reads nothing at all. The raise watch starts with the probe, so only a raise after it wakes.
164
198
  async function start(
165
199
  now_ms: number,
166
- ports: ReadyPorts = ARRIVAL_PORTS,
200
+ ports: ArrivalPorts = ARRIVAL_PORTS,
167
201
  is_parent: () => Promise<boolean> = run_headless.is_backlog_parent,
202
+ watch_raise: () => Promise<() => boolean> = lane_limit_override.watch_raise,
168
203
  ): Promise<ArrivalProbe> {
169
204
  if (!(await is_parent_safely(is_parent))) return INERT
170
205
 
171
- return probe_of(await read_baseline(ports), now_ms + PROBE_INTERVAL_MS, ports)
206
+ const is_raised = await watch_raise()
207
+
208
+ return probe_of(await read_baseline(ports), now_ms, ports, is_raised)
172
209
  }
173
210
 
174
211
  const backlog_arrival = { PROBE_INTERVAL_MS, answered_issues, arrivals, start }
175
212
 
176
- export type { ArrivalProbe }
213
+ export type { ArrivalPorts, ArrivalProbe }
177
214
  export { backlog_arrival }
@@ -2,7 +2,13 @@
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { path_decision } from '#scripts/josh/path-decision'
4
4
  import { cli_flags } from '#scripts/lib/cli-flags'
5
- import { backlog_budget, type BacklogAnswer, type BudgetInput } from './backlog-budget'
5
+ import {
6
+ backlog_budget,
7
+ type BacklogAnswer,
8
+ type BudgetDecision,
9
+ type BudgetInput,
10
+ } from './backlog-budget'
11
+ import { backlog_idle } from './backlog-idle'
6
12
 
7
13
  // The thin half of `josh backlog:budget` (joshuafolkken/kit#1632): read the loop's state off the
8
14
  // command line, hand it to the pure decision, print the verdict on stdout and the reason on stderr
@@ -12,6 +18,7 @@ const ARGV_OFFSET = 2
12
18
  const SUCCESS_EXIT_CODE = 0
13
19
  const FAILURE_EXIT_CODE = 1
14
20
  const JSON_KEY = 'budget'
21
+ const EXHAUSTED_ANSWER: BacklogAnswer = 'exhausted'
15
22
 
16
23
  const USAGE = `Usage: josh backlog:budget --answer <${backlog_budget.ANSWERS.join('|')}> --started <ISO-8601> [--active <ISO-8601>, required unless the watch is off] [--merged <count>] [--running <count>] [--max <count>] [--idle <minutes>, 0 to turn the watch off] [--json]`
17
24
 
@@ -158,6 +165,29 @@ function build_input(values: ParsedValues, now_ms: number): BudgetInput | undefi
158
165
  return input_of(values, { answer, now_ms, started_at_ms })
159
166
  }
160
167
 
168
+ // The idle window, carried only on the watch an empty backlog opens — the one `idle_decision` reaches,
169
+ // not the draining watch a reached bound returns while children still run — so `backlog:offer` can
170
+ // record when that wait ends (joshuafolkken/kit#3430).
171
+ function idle_of(input: BudgetInput, verdict: string): string | undefined {
172
+ const is_idle_watch =
173
+ verdict === backlog_budget.WATCH_VERDICT &&
174
+ input.answer === EXHAUSTED_ANSWER &&
175
+ backlog_budget.is_finish(input)
176
+ const window = is_idle_watch ? backlog_idle.window_of(input) : undefined
177
+
178
+ return window === undefined ? undefined : backlog_idle.text_of(window)
179
+ }
180
+
181
+ function print_json(input: BudgetInput, decision: BudgetDecision): void {
182
+ const { verdict, reason } = decision
183
+ const idle = idle_of(input, verdict)
184
+ const is_finish = backlog_budget.is_finish(input)
185
+
186
+ console.info(
187
+ JSON.stringify({ [JSON_KEY]: verdict, reason, is_finish, ...(idle !== undefined && { idle }) }),
188
+ )
189
+ }
190
+
161
191
  function refuse(): number {
162
192
  console.error(USAGE)
163
193
 
@@ -173,17 +203,15 @@ function run(argv: ReadonlyArray<string>, now_ms: number = Date.now()): number {
173
203
 
174
204
  if (input === undefined) return refuse()
175
205
 
176
- const { verdict, reason } = backlog_budget.decide(input)
206
+ const decision = backlog_budget.decide(input)
177
207
 
178
208
  if (values.json === true) {
179
- console.info(
180
- JSON.stringify({ [JSON_KEY]: verdict, reason, is_finish: backlog_budget.is_finish(input) }),
181
- )
209
+ print_json(input, decision)
182
210
 
183
211
  return SUCCESS_EXIT_CODE
184
212
  }
185
213
 
186
- path_decision.print_decision(JSON_KEY, verdict, reason, false)
214
+ path_decision.print_decision(JSON_KEY, decision.verdict, decision.reason, false)
187
215
 
188
216
  return SUCCESS_EXIT_CODE
189
217
  }
@@ -1,38 +1,32 @@
1
- // `josh backlog:budget` — whether a `backlogrun` may start more work, keep watching, or finish
2
- // (joshuafolkken/kit#1632).
1
+ // `josh backlog:budget` — whether a `backlogrun` may start more work, keep watching, or finish.
3
2
  //
4
- // `backlog:next` says what may start; it says nothing about when the run itself should end. Before
5
- // this existed a `backlogrun` had exactly two endings and neither could be declared in advance: it
6
- // finished the moment the backlog read empty, so an issue a person opted in three minutes later
7
- // needed a whole new session, or it ran to the 8-hour whole-run bound, which is a limit on waiting
8
- // rather than a statement of scale.
3
+ // `backlog:next` says what may start; it says nothing about when the run itself should end. Without
4
+ // this a run would finish the moment the backlog read empty, so an issue a person opted in minutes
5
+ // later would need a whole new session.
9
6
  //
10
- // **The idle watch is on by default and the maximum is not** (joshuafolkken/kit#1676). A
11
- // `backlogrun` with neither flag given watches an empty backlog for `DEFAULT_IDLE_MINUTES` before it
12
- // finishes, and takes as many issues as the backlog holds. `--idle 0` is how the watch is turned off.
7
+ // **The idle watch is on by default and the maximum is not.** A `backlogrun` with neither flag given
8
+ // watches an empty backlog for `DEFAULT_IDLE_MINUTES` before it finishes, and takes as many issues as
9
+ // the backlog holds. `--idle 0` is how the watch is turned off.
13
10
  //
14
11
  // The decision is a command's rather than the loop's own arithmetic, for the reason `josh delegate`
15
12
  // and `josh review:level` are commands: a count and an elapsed time kept in an agent's head are a
16
- // one-shot judgement, and joshuafolkken/kit#1460 measured exactly that failure — a threshold asked
17
- // once and then never again while the run walked past it eight times.
13
+ // one-shot judgement — a threshold asked once and then never again while the run walks past it.
18
14
 
19
15
  const MS_PER_MINUTE = 60_000
20
16
  const MINUTES_PER_HOUR = 60
21
- // `backlogrun-progress.md` → "Waiting, and never waiting forever" carried this as prose only. Held here it is
22
- // the same bound, decided the same way as the two new ones rather than by an agent reading a clock.
17
+ // The whole-run bound, decided here like the idle watch and the maximum rather than by an agent reading
18
+ // a clock.
23
19
  const WHOLE_RUN_BUDGET_HOURS = 8
24
20
  const WHOLE_RUN_BUDGET_MINUTES = WHOLE_RUN_BUDGET_HOURS * MINUTES_PER_HOUR
25
21
  const WHOLE_RUN_BUDGET_MS = WHOLE_RUN_BUDGET_MINUTES * MS_PER_MINUTE
26
22
 
27
- // **The default idle watch, and why it is this number** (joshuafolkken/kit#1676). The documents used
28
- // 30 as an example, and an example is not a reason; these three are.
23
+ // **The default idle watch, and why it is this number.**
29
24
  //
30
25
  // - **Below it the watch is a coin flip.** What it waits for is a person noticing the run has gone
31
26
  // quiet, filing an issue and applying `auto-ok`. Ten minutes does not reliably outlast that.
32
27
  // - **Above it the run pays for nothing.** At `IDLE_POLL_MINUTES` a 30-minute watch is six asks —
33
28
  // about one child's worth of turns, spent while the run holds no working tree and no lane.
34
- // - **It is about the length of one child** — 12 to 28 minutes measured on joshuafolkken/kit#1477 —
35
- // so a run that has emptied its backlog waits roughly as long as one more issue would have taken.
29
+ // - **It is about the length of one child** — 12 to 28 minutes measured — so a run that has emptied its backlog waits roughly as long as one more issue would have taken.
36
30
  const DEFAULT_IDLE_MINUTES = 30
37
31
  const DEFAULT_IDLE_MS = DEFAULT_IDLE_MINUTES * MS_PER_MINUTE
38
32
 
@@ -51,10 +45,10 @@ const TRIAGE_VERDICT = 'triage'
51
45
 
52
46
  // `run` — start what `backlog:next` offered. `watch` — sleep the polling interval and ask again,
53
47
  // except while something of the run's own is in flight, where the wake is the progress watcher's exit
54
- // and the interval is only a floor (`backlogrun.md` → "The wake exists only while something is in
55
- // flight").
48
+ // and the interval is only a floor (`docs/maintainers/backlogrun-driver.md` → "Waiting while
49
+ // something is in flight").
56
50
  // `stop` — report and finish. `triage` — judge the untriaged issues `backlog:next` named, then ask
57
- // again (joshuafolkken/kit#2779); it is the parent's to act on, so `backlog:drive` hands it back.
51
+ // again; it is the parent's to act on, so `backlog:drive` hands it back.
58
52
  type BudgetVerdict =
59
53
  typeof RUN_VERDICT | typeof WATCH_VERDICT | typeof STOP_VERDICT | typeof TRIAGE_VERDICT
60
54
 
@@ -141,8 +135,7 @@ function idle_watch_reason(left_ms: number): string {
141
135
  return `The backlog is empty and the idle watch has about ${to_minutes(left_ms)} minutes left. Release the working tree, ask again in ${next_ask_minutes(left_ms)} minutes, and restart the watch the moment a candidate appears.`
142
136
  }
143
137
 
144
- // **A watch that opens while children are still in lanes is not the idle watch's ordinary shape**, and
145
- // it became reachable the moment the watch was turned on by default (joshuafolkken/kit#1676): the
138
+ // **A watch that opens while children are still in lanes is not the idle watch's ordinary shape**: the
146
139
  // backlog can answer `exhausted` while this run's own children are still merging. Two things the
147
140
  // sentence above would get wrong there — the working tree is still held, because the hold is released
148
141
  // at the *last* child's merge, and a five-minute poll would leave a merge unnoticed for five minutes.
@@ -237,7 +230,7 @@ function idle_decision(input: BudgetInput): BudgetDecision {
237
230
  // Whether a `stop` for this input is the run finishing — the idle watch ending on an empty backlog —
238
231
  // rather than stopping on something a person must act on: a parked backlog, an unreadable listing, the
239
232
  // maximum or the whole-run bound. The two end the carry record differently (`--end` against
240
- // `--end --stopped`), and `backlog:drive` reads which one from here (joshuafolkken/kit#2508).
233
+ // `--end --stopped`), and `backlog:drive` reads which one from here.
241
234
  function is_finish(input: BudgetInput): boolean {
242
235
  return stop_reason(input) === undefined && max_decision(input) === undefined
243
236
  }