@joshuafolkken/kit 1.1471.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -20,8 +20,10 @@ interface ClassifiedFindings {
20
20
  infos: ReadonlyArray<ClassifiedFinding>
21
21
  }
22
22
 
23
- const CLAUDE_AUTHORS: ReadonlySet<string> = new Set(['claude', 'claude[bot]'])
24
- const CODERABBIT_AUTHORS: ReadonlySet<string> = new Set(['coderabbitai', 'coderabbitai[bot]'])
23
+ // Only the app accounts (`type: Bot`): a bare `claude` / `coderabbitai` is an ordinary user login
24
+ // anyone could register, and its comment is not an AI review.
25
+ const CLAUDE_AUTHORS: ReadonlySet<string> = new Set(['claude[bot]'])
26
+ const CODERABBIT_AUTHORS: ReadonlySet<string> = new Set(['coderabbitai[bot]'])
25
27
 
26
28
  const CLAUDE_BLOCKER_HEADINGS: ReadonlyArray<RegExp> = [
27
29
  /^#{2,4}\s+Issues\b/mu,
@@ -28,6 +28,13 @@ function issue_api_path(issue_number: string, repo?: string): string {
28
28
  return `${issues_api_path(repo)}/${issue_number}`
29
29
  }
30
30
 
31
+ // One issue's labels — a pull request is an issue to this endpoint. Named here because the label
32
+ // writes and reads in `git-gh-issue-write.ts` and the CI classification read in `pr-classification.ts`
33
+ // all address it.
34
+ function issue_labels_api_path(issue_number: string, repo?: string): string {
35
+ return `${issue_api_path(issue_number, repo)}/labels`
36
+ }
37
+
31
38
  // The dependency relations, which REST serves from their own endpoint rather than inside the issue.
32
39
  // Named here because three call sites address it — the read in `git-gh-issue-read.ts` and both
33
40
  // writes in `git-gh-issue-write.ts`.
@@ -90,6 +97,12 @@ function commit_status_api_path(commit_sha: string, repo?: string): string {
90
97
  return `${commit_api_path(commit_sha, repo)}/status`
91
98
  }
92
99
 
100
+ // The rules that apply to one branch, from every ruleset that targets it — readable without the
101
+ // admin access the classic branch protection endpoint needs.
102
+ function branch_rules_api_path(branch_name: string, repo?: string): string {
103
+ return `${repo_api_path(repo)}/rules/branches/${branch_name}`
104
+ }
105
+
93
106
  // A single tag reference. REST answers 404 when the tag does not exist, which is the whole of the
94
107
  // question the release command's tag watch asks.
95
108
  function tag_reference_api_path(tag: string, repo?: string): string {
@@ -109,6 +122,7 @@ const git_gh_api_path = {
109
122
  release_by_tag_api_path,
110
123
  issues_api_path,
111
124
  issue_api_path,
125
+ issue_labels_api_path,
112
126
  blocked_by_api_path,
113
127
  issue_comments_api_path,
114
128
  pulls_api_path,
@@ -119,6 +133,7 @@ const git_gh_api_path = {
119
133
  commit_api_path,
120
134
  commit_check_runs_api_path,
121
135
  commit_status_api_path,
136
+ branch_rules_api_path,
122
137
  }
123
138
 
124
139
  export { git_gh_api_path, FULL_PAGE_QUERY }
@@ -0,0 +1,73 @@
1
+ import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
2
+ import { z } from 'zod'
3
+ import { FULL_PAGE_QUERY, git_gh_api_path } from './git-gh-api-path'
4
+ import { git_gh_exec } from './git-gh-exec'
5
+
6
+ // The status check contexts the base branch's rules require, which is what lets the merge gate tell
7
+ // a pull request held only by a slow optional check — GitHub's default-setup `CodeQL` — from one
8
+ // still waiting on a check that guards the merge (joshuafolkken/kit#4351).
9
+ //
10
+ // **An empty answer keeps the gate strict, so every gap folds into it.** With no required context
11
+ // known, `git-pr-checks-eval.ts` waits for `CLEAN` exactly as it did before, so a repository with no
12
+ // ruleset, a token the endpoint answers 403 to, or a rate limit costs the wait time it always did and
13
+ // never a merge past a check nobody declared optional.
14
+
15
+ const REQUIRED_STATUS_CHECKS_RULE = 'required_status_checks'
16
+
17
+ const required_check_schema = z.looseObject({ context: z.string() })
18
+
19
+ const rule_parameters_schema = z.looseObject({
20
+ required_status_checks: z.array(required_check_schema).optional(),
21
+ })
22
+
23
+ const branch_rule_schema = z.looseObject({
24
+ type: z.string(),
25
+ parameters: rule_parameters_schema.nullish(),
26
+ })
27
+
28
+ type BranchRule = z.infer<typeof branch_rule_schema>
29
+
30
+ // A branch's rules do not change while one command waits on a pull request, so a read is remembered
31
+ // for the life of the command; one that failed is not, and the next poll asks again.
32
+ const required_contexts_by_branch = new Map<string, Array<string>>()
33
+
34
+ function forget_branch_rules(): void {
35
+ required_contexts_by_branch.clear()
36
+ }
37
+
38
+ function to_required_contexts(rules: ReadonlyArray<BranchRule>): Array<string> {
39
+ return rules
40
+ .filter((rule) => rule.type === REQUIRED_STATUS_CHECKS_RULE)
41
+ .flatMap((rule) => rule.parameters?.required_status_checks ?? [])
42
+ .map((check) => check.context)
43
+ }
44
+
45
+ async function fetch_required_contexts(branch_name: string): Promise<Array<string> | undefined> {
46
+ const raw_json = await git_gh_exec.exec_gh_api({
47
+ path: `${git_gh_api_path.branch_rules_api_path(branch_name)}${FULL_PAGE_QUERY}`,
48
+ should_paginate: true,
49
+ })
50
+ const rules = parse_json_array_or_undefined(raw_json, branch_rule_schema)
51
+
52
+ return rules === undefined ? undefined : to_required_contexts(rules)
53
+ }
54
+
55
+ async function read_required_contexts(branch_name: string | undefined): Promise<Array<string>> {
56
+ if (branch_name === undefined) return []
57
+ const cached = required_contexts_by_branch.get(branch_name)
58
+ if (cached !== undefined) return cached
59
+
60
+ try {
61
+ const contexts = await fetch_required_contexts(branch_name)
62
+ if (contexts === undefined) return []
63
+ required_contexts_by_branch.set(branch_name, contexts)
64
+
65
+ return contexts
66
+ } catch {
67
+ return []
68
+ }
69
+ }
70
+
71
+ const git_gh_branch_rules = { read_required_contexts }
72
+
73
+ export { git_gh_branch_rules, read_required_contexts, forget_branch_rules }
@@ -19,7 +19,8 @@ const ETAG_HEADER = /^etag: *(?<etag>[^\r\n]+)/imu
19
19
  type ConditionalRead =
20
20
  | { kind: 'unchanged' }
21
21
  | { kind: 'changed'; etag: string | undefined; body: string }
22
- | { kind: 'unreadable' }
22
+ // `cause` is gh's own failure where there was one, for a caller that reports it.
23
+ | { kind: 'unreadable'; cause?: unknown }
23
24
 
24
25
  const UNCHANGED: ConditionalRead = { kind: 'unchanged' }
25
26
  const UNREADABLE: ConditionalRead = { kind: 'unreadable' }
@@ -56,7 +57,9 @@ async function read_conditional(
56
57
  try {
57
58
  return to_read(await git_gh_exec.exec_gh_command(to_args(path, etag), timeout_ms))
58
59
  } catch (error) {
59
- return failure_status(error) === NOT_MODIFIED_STATUS ? UNCHANGED : UNREADABLE
60
+ return failure_status(error) === NOT_MODIFIED_STATUS
61
+ ? UNCHANGED
62
+ : { kind: 'unreadable', cause: error }
60
63
  }
61
64
  }
62
65
 
@@ -281,7 +281,11 @@ async function issue_view_json(
281
281
  // `repo` reads a child in another repository. Cross-repository children are read this way rather
282
282
  // than from a local checkout: their state is a GitHub fact, and requiring a clone to learn it is
283
283
  // what kept the auto-close from ever running on such an epic.
284
- const STATE_AND_RELATIONS_FIELDS = 'number,state,labels,blockedBy'
284
+ //
285
+ // `body` rides along because `epic:next` holds a child until its declared start time
286
+ // (joshuafolkken/kit#4007); the REST issue endpoint answers it in the same response, so it costs no
287
+ // request.
288
+ const STATE_AND_RELATIONS_FIELDS = 'number,state,labels,blockedBy,body'
285
289
 
286
290
  async function issue_get_state_and_relations(
287
291
  issue_number: string,
@@ -71,6 +71,7 @@ const REST_FIELD_NAMES = new Map<string, string>([
71
71
  ['url', 'html_url'],
72
72
  ['createdAt', 'created_at'],
73
73
  ['closedAt', 'closed_at'],
74
+ ['stateReason', 'state_reason'],
74
75
  ['updatedAt', 'updated_at'],
75
76
  ])
76
77
 
@@ -56,21 +56,39 @@ async function did_write_succeed(write: () => Promise<unknown>): Promise<boolean
56
56
  }
57
57
  }
58
58
 
59
- async function issue_edit_body(issue_number: string, body: string): Promise<string> {
59
+ async function issue_patch(
60
+ issue_number: string,
61
+ fields: Readonly<Record<string, string>>,
62
+ repo?: string,
63
+ ): Promise<string> {
60
64
  return await git_gh_exec.exec_gh_api({
61
- path: git_gh_api_path.issue_api_path(issue_number),
65
+ path: git_gh_api_path.issue_api_path(issue_number, repo),
62
66
  method: PATCH_METHOD,
63
- body: JSON.stringify({ body }),
67
+ body: JSON.stringify(fields),
64
68
  jq_filter: HTML_URL_FILTER,
65
69
  })
66
70
  }
67
71
 
72
+ // The optional `repo` (`owner/name`) on these writes addresses an issue in another repository; left
73
+ // out, the path keeps gh's `{owner}/{repo}` placeholder — the checkout's own repository.
74
+ async function issue_edit_body(issue_number: string, body: string, repo?: string): Promise<string> {
75
+ return await issue_patch(issue_number, { body }, repo)
76
+ }
77
+
78
+ async function issue_edit_title(
79
+ issue_number: string,
80
+ title: string,
81
+ repo?: string,
82
+ ): Promise<string> {
83
+ return await issue_patch(issue_number, { title }, repo)
84
+ }
85
+
68
86
  // **Every comment josh posts carries `RUN_MARKER`**, an HTML comment GitHub does not render. A run
69
87
  // posts under the person's own `gh` login, so the marker is the only thing that tells the issue watch
70
88
  // (`issue-watch-diff.ts`) a run's comment from a person's update.
71
- async function issue_comment(issue_number: string, body: string): Promise<string> {
89
+ async function issue_comment(issue_number: string, body: string, repo?: string): Promise<string> {
72
90
  return await git_gh_exec.exec_gh_api({
73
- path: `${git_gh_api_path.issue_api_path(issue_number)}${COMMENTS_SEGMENT}`,
91
+ path: `${git_gh_api_path.issue_api_path(issue_number, repo)}${COMMENTS_SEGMENT}`,
74
92
  body: JSON.stringify({ body: `${body}\n\n${issue_watch_diff.RUN_MARKER}` }),
75
93
  jq_filter: HTML_URL_FILTER,
76
94
  })
@@ -99,17 +117,25 @@ async function issue_try_comment(issue_number: string, body: string): Promise<bo
99
117
  // It is a required parameter that may be `undefined` rather than an optional one: skipping the
100
118
  // announcement is a decision the caller makes from what it read, never something a call site can
101
119
  // fall into by leaving an argument off.
102
- async function issue_close(issue_number: string, comment: string | undefined): Promise<boolean> {
120
+ async function close_with(
121
+ issue_number: string,
122
+ comment: string | undefined,
123
+ state: Readonly<Record<string, string>>,
124
+ ): Promise<boolean> {
103
125
  return await did_write_succeed(async () => {
104
126
  if (comment !== undefined) await issue_comment(issue_number, comment)
105
127
  await git_gh_exec.exec_gh_api({
106
128
  path: git_gh_api_path.issue_api_path(issue_number),
107
129
  method: PATCH_METHOD,
108
- body: JSON.stringify({ state: CLOSED_STATE }),
130
+ body: JSON.stringify(state),
109
131
  })
110
132
  })
111
133
  }
112
134
 
135
+ async function issue_close(issue_number: string, comment: string | undefined): Promise<boolean> {
136
+ return await close_with(issue_number, comment, { state: CLOSED_STATE })
137
+ }
138
+
113
139
  // REST answers 422 `{"resource":"Label","code":"invalid","field":"color"}` for a color carrying a
114
140
  // leading `#`. The one caller passes the hash form (`EPIC_LABEL_COLOR`), so dropping it here is what
115
141
  // keeps that call site unchanged.
@@ -204,12 +230,16 @@ async function issue_create_with_label(input: {
204
230
  // say why it refused.
205
231
  type LabelWrite = { is_applied: true } | { is_applied: false; reason: string }
206
232
 
207
- // The issue's label names, read back after a failed write. A read that itself fails answers
208
- // `undefined`, which the caller treats as "not applied" — the write's own error is the reason then.
209
- async function read_label_names(issue_number: string): Promise<Array<string> | undefined> {
233
+ // The issue's label names, every page of them — read back after a failed write, and by a pull
234
+ // request's classification read. A read that itself fails answers `undefined`, which the write
235
+ // treats as "not applied" — its own error is the reason then.
236
+ async function read_label_names(
237
+ issue_number: string,
238
+ repo?: string,
239
+ ): Promise<Array<string> | undefined> {
210
240
  try {
211
241
  const raw = await git_gh_exec.exec_gh_api({
212
- path: `${git_gh_api_path.issue_api_path(issue_number)}${LABELS_SEGMENT}`,
242
+ path: git_gh_api_path.issue_labels_api_path(issue_number, repo),
213
243
  should_paginate: true,
214
244
  jq_filter: LABEL_NAMES_FILTER,
215
245
  })
@@ -226,15 +256,19 @@ async function read_label_names(issue_number: string): Promise<Array<string> | u
226
256
  // after the write or a secondary rate limit can each throw after the label landed — which refused a
227
257
  // lane dispatch whose label was in fact applied. So a throw is confirmed by
228
258
  // reading the labels back, and only a label that is really absent answers `is_applied: false`.
229
- async function issue_apply_label(issue_number: string, label: string): Promise<LabelWrite> {
230
- const labels_path = `${git_gh_api_path.issue_api_path(issue_number)}${LABELS_SEGMENT}`
259
+ async function issue_apply_label(
260
+ issue_number: string,
261
+ label: string,
262
+ repo?: string,
263
+ ): Promise<LabelWrite> {
264
+ const labels_path = git_gh_api_path.issue_labels_api_path(issue_number, repo)
231
265
 
232
266
  try {
233
267
  await git_gh_exec.exec_gh_api({ path: labels_path, body: JSON.stringify({ labels: [label] }) })
234
268
 
235
269
  return { is_applied: true }
236
270
  } catch (error) {
237
- const names = await read_label_names(issue_number)
271
+ const names = await read_label_names(issue_number, repo)
238
272
 
239
273
  if (names?.includes(label) === true) return { is_applied: true }
240
274
  error_text.trace_swallowed('git_gh_issue_write.issue_apply_label', error)
@@ -250,8 +284,12 @@ async function issue_apply_label(issue_number: string, label: string): Promise<L
250
284
  // Applied after the body edit so a failure leaves an issue with the epic sections and no label,
251
285
  // which `epic:check` reports — rather than a labelled issue with nothing to track. The caller checks
252
286
  // the return: the label is what the auto-close filters on.
253
- async function issue_add_label(issue_number: string, label: string): Promise<boolean> {
254
- const write = await issue_apply_label(issue_number, label)
287
+ async function issue_add_label(
288
+ issue_number: string,
289
+ label: string,
290
+ repo?: string,
291
+ ): Promise<boolean> {
292
+ const write = await issue_apply_label(issue_number, label, repo)
255
293
 
256
294
  return write.is_applied
257
295
  }
@@ -266,7 +304,7 @@ async function issue_add_label(issue_number: string, label: string): Promise<boo
266
304
  // a `false` swallowed here would reach that guard as a success and the step would be reported as
267
305
  // done.
268
306
  async function issue_remove_label(issue_number: string, label: string): Promise<void> {
269
- const labels_path = `${git_gh_api_path.issue_api_path(issue_number)}${LABELS_SEGMENT}`
307
+ const labels_path = git_gh_api_path.issue_labels_api_path(issue_number)
270
308
 
271
309
  await git_gh_exec.exec_gh_api({
272
310
  path: `${labels_path}/${encodeURIComponent(label)}`,
@@ -274,6 +312,25 @@ async function issue_remove_label(issue_number: string, label: string): Promise<
274
312
  })
275
313
  }
276
314
 
315
+ // **The removal for a caller that wants the label gone, not removed by this call** — a release that
316
+ // may find the label already off. A failed DELETE is confirmed against the labels the issue carries,
317
+ // the read `issue_apply_label` confirms an addition with, so an absent label answers `true` and a
318
+ // failure that left the label on answers `false`.
319
+ async function issue_clear_label(issue_number: string, label: string): Promise<boolean> {
320
+ try {
321
+ await issue_remove_label(issue_number, label)
322
+
323
+ return true
324
+ } catch (error) {
325
+ const names = await read_label_names(issue_number)
326
+
327
+ if (names?.includes(label) === false) return true
328
+ error_text.trace_swallowed('git_gh_issue_write.issue_clear_label', error)
329
+
330
+ return false
331
+ }
332
+ }
333
+
277
334
  // The blocker's **database id**, which is the only thing the dependencies endpoint accepts — and the
278
335
  // reason this resolution exists rather than the issue number being sent straight through.
279
336
  //
@@ -333,15 +390,18 @@ async function issue_remove_blocked_by(issue_number: string, blocker: string): P
333
390
 
334
391
  const git_gh_issue_write = {
335
392
  issue_edit_body,
393
+ issue_edit_title,
336
394
  issue_comment,
337
395
  issue_try_comment,
338
396
  issue_close,
339
397
  label_ensure,
340
398
  issue_create_request,
341
399
  issue_create_with_label,
400
+ read_label_names,
342
401
  issue_apply_label,
343
402
  issue_add_label,
344
403
  issue_remove_label,
404
+ issue_clear_label,
345
405
  issue_add_blocked_by,
346
406
  issue_remove_blocked_by,
347
407
  }
@@ -4,6 +4,9 @@ import { BLOCKED_BY_COUNT_FIELD } from './git-gh-issue-rest'
4
4
  import { git_gh_issue_write } from './git-gh-issue-write'
5
5
 
6
6
  const NUMBER_AND_BODY_FIELDS = 'number,body'
7
+ // The label listing's fields. `stateReason` rides along on the same response: the epic auto-close
8
+ // reads `reopened` off it, so its sweep leaves an epic a person reopened to them (#4564).
9
+ const LABELLED_FIELDS = 'number,body,stateReason'
7
10
  // The backlog scan's fields. The title rides along because the pre-filing scan compares titles
8
11
  // and it costs nothing: the same listing request already carries it, so the
9
12
  // two consumers share one read rather than each making their own.
@@ -111,7 +114,7 @@ async function issue_search_body(term: string, limit: number): Promise<IssueList
111
114
  }
112
115
 
113
116
  async function issue_list_by_label(label: string, limit: number): Promise<IssueListOutcome> {
114
- return await issue_list({ json_fields: NUMBER_AND_BODY_FIELDS, limit, label })
117
+ return await issue_list({ json_fields: LABELLED_FIELDS, limit, label })
115
118
  }
116
119
 
117
120
  // The same filter with the fields the `auto-ok` pickup needs: it orders by
@@ -151,8 +154,9 @@ async function issue_list_by_label_in_repo(
151
154
  }
152
155
 
153
156
  // Every open issue with what `josh auto-ok:judge` judges it by — its labels and body — and `updatedAt`,
154
- // so the backlog driver's resident check reads an issue's comments again only once it has moved.
155
- const JUDGEMENT_FIELDS = 'number,title,body,labels,updatedAt'
157
+ // so the backlog driver's resident check reads an issue's comments again only once it has moved; and
158
+ // `author_association` and `user`, so an issue a third party filed is never judged.
159
+ const JUDGEMENT_FIELDS = 'number,title,body,labels,updatedAt,author_association,user'
156
160
 
157
161
  async function issue_list_open_for_judgement(limit: number): Promise<IssueListOutcome> {
158
162
  return await issue_list({ json_fields: JUDGEMENT_FIELDS, limit })
@@ -0,0 +1,89 @@
1
+ import { error_text } from '#scripts/lib/error-message'
2
+ import { json_value } from '#scripts/lib/json-value'
3
+ import { z } from 'zod'
4
+ import { FULL_PAGE_QUERY } from './git-gh-api-path'
5
+ import { git_gh_conditional, type ConditionalRead } from './git-gh-conditional'
6
+ import { git_gh_exec } from './git-gh-exec'
7
+
8
+ // The merge gate's per-poll reads, each sent with the ETag of this process's previous answer
9
+ // (joshuafolkken/kit#4550).
10
+ //
11
+ // **Never a pull request's detail**: GitHub computes its `mergeable_state` lazily, under an unchanged
12
+ // ETag, so a 304 would keep a stale state (joshuafolkken/kit#4589).
13
+ //
14
+ // **`pnpm josh followup` reads the same pull request every 10 seconds** while its checks run, and
15
+ // every lane waiting on its merge does so at once. A `304 Not Modified` does not count against the
16
+ // rate limit, so a poll that finds nothing changed costs only its pull detail read.
17
+ //
18
+ // **A listing is read one page at a time only while it fits in one.** A listing longer than a page is
19
+ // read through `--paginate --slurp` as before; the conditional read cannot page, and a partial
20
+ // listing would drop checks from the verdict.
21
+
22
+ const UNREADABLE_POLL_MESSAGE = 'gh api could not read a merge-gate poll'
23
+ const PAGE_SIZE = 100
24
+
25
+ interface KeptAnswer {
26
+ etag: string
27
+ body: string
28
+ }
29
+
30
+ const kept_by_path = new Map<string, KeptAnswer>()
31
+
32
+ const page_schema = z.object({ total_count: z.number() })
33
+
34
+ // gh's own failure rides along as the cause and in the message: the poll loop's warning prints the
35
+ // message alone, and a rate limit must read differently there from expired auth.
36
+ function unreadable(path: string, answer: ConditionalRead): Error {
37
+ const cause = answer.kind === 'unreadable' ? answer.cause : undefined
38
+ const reason = cause === undefined ? '' : `: ${error_text.message_of(cause)}`
39
+
40
+ return new Error(`${UNREADABLE_POLL_MESSAGE}: ${path}${reason}`, { cause })
41
+ }
42
+
43
+ function to_body(path: string, answer: ConditionalRead): string {
44
+ const previous = kept_by_path.get(path)
45
+
46
+ if (previous !== undefined && answer.kind === 'unchanged') return previous.body
47
+ if (answer.kind !== 'changed') throw unreadable(path, answer)
48
+ if (answer.etag !== undefined) kept_by_path.set(path, { etag: answer.etag, body: answer.body })
49
+
50
+ return answer.body
51
+ }
52
+
53
+ // The answer for `path`, or the previous one where GitHub says it has not changed. A failure throws,
54
+ // the contract the unconditional read had.
55
+ async function read(path: string): Promise<string> {
56
+ const answer = await git_gh_conditional.read_conditional(path, kept_by_path.get(path)?.etag)
57
+
58
+ return to_body(path, answer)
59
+ }
60
+
61
+ // A page that does not parse as a listing is not taken as the whole one: the full read answers it, and
62
+ // its own parser reports what it was.
63
+ function is_whole_listing(page: string): boolean {
64
+ const total = json_value.parse_with(page, page_schema)?.total_count
65
+
66
+ return total !== undefined && total <= PAGE_SIZE
67
+ }
68
+
69
+ // A commit listing in the `--slurp` shape — an array of pages — however it was read.
70
+ async function read_object_pages(path: string): Promise<string> {
71
+ const full_path = `${path}${FULL_PAGE_QUERY}`
72
+ const page = await read(full_path)
73
+
74
+ if (is_whole_listing(page)) return `[${page}]`
75
+
76
+ return await git_gh_exec.exec_gh_api({
77
+ path: full_path,
78
+ should_paginate: true,
79
+ should_slurp: true,
80
+ })
81
+ }
82
+
83
+ function forget_poll_reads(): void {
84
+ kept_by_path.clear()
85
+ }
86
+
87
+ const git_gh_poll_read = { UNREADABLE_POLL_MESSAGE, forget_poll_reads, read, read_object_pages }
88
+
89
+ export { git_gh_poll_read }
@@ -17,8 +17,10 @@ import { git_gh_pr_rest, type RestPull } from './git-gh-pr-rest'
17
17
  const GRAPHQL_PATH = 'graphql'
18
18
  const OPEN_PULLS_QUERY = `${git_gh_api_path.FULL_PAGE_QUERY}&state=open`
19
19
  const MISSING_NODE_ID_MESSAGE = 'gh api answered a pull request without a node_id'
20
+ // **`expectedHeadOid` binds the auto-merge to the commit the caller pushed** (#4036): GitHub then
21
+ // refuses it if the head has moved, rather than landing a commit nobody here pushed or checked.
20
22
  const ENABLE_AUTO_MERGE_MUTATION =
21
- 'mutation($id: ID!) { enablePullRequestAutoMerge(input: { pullRequestId: $id, mergeMethod: MERGE }) { clientMutationId } }'
23
+ 'mutation($id: ID!, $head: GitObjectID!) { enablePullRequestAutoMerge(input: { pullRequestId: $id, mergeMethod: MERGE, expectedHeadOid: $head }) { clientMutationId } }'
22
24
 
23
25
  interface OpenPull {
24
26
  number: number
@@ -26,13 +28,16 @@ interface OpenPull {
26
28
  has_auto_merge: boolean
27
29
  }
28
30
 
29
- async function pr_enable_auto_merge(branch_name: string): Promise<void> {
31
+ async function pr_enable_auto_merge(branch_name: string, head_sha: string): Promise<void> {
30
32
  const pull = await read_pull(await require_pr_number(branch_name))
31
33
  if (pull.node_id === undefined) throw new Error(MISSING_NODE_ID_MESSAGE)
32
34
 
33
35
  await git_gh_exec.exec_gh_api({
34
36
  path: GRAPHQL_PATH,
35
- body: JSON.stringify({ query: ENABLE_AUTO_MERGE_MUTATION, variables: { id: pull.node_id } }),
37
+ body: JSON.stringify({
38
+ query: ENABLE_AUTO_MERGE_MUTATION,
39
+ variables: { id: pull.node_id, head: head_sha },
40
+ }),
36
41
  })
37
42
  }
38
43
 
@@ -27,7 +27,7 @@ import { MERGED_STATE, to_gh_state } from './git-gh-rest-state'
27
27
  // branch name that says nothing about which repository holds it. Named once
28
28
  // because both sides of a pull request carry the same shape.
29
29
  const rest_repo_schema = z.looseObject({ full_name: z.string().optional() }).nullish()
30
- const rest_pull_side_schema = z.looseObject({ repo: rest_repo_schema })
30
+ const rest_pull_side_schema = z.looseObject({ ref: z.string().optional(), repo: rest_repo_schema })
31
31
 
32
32
  type RestPullSide = z.infer<typeof rest_pull_side_schema>
33
33
 
@@ -1,7 +1,9 @@
1
1
  import { FULL_PAGE_QUERY, git_gh_api_path } from './git-gh-api-path'
2
+ import { git_gh_branch_rules } from './git-gh-branch-rules'
2
3
  import { git_gh_exec } from './git-gh-exec'
3
- import { read_pull, require_pr_number } from './git-gh-pr-read'
4
- import type { RestPull } from './git-gh-pr-rest'
4
+ import { git_gh_poll_read } from './git-gh-poll-read'
5
+ import { require_pr_number } from './git-gh-pr-read'
6
+ import { git_gh_pr_rest, type RestPull } from './git-gh-pr-rest'
5
7
  import { git_gh_pr_review } from './git-gh-pr-review'
6
8
  import { git_gh_pr_rollup } from './git-gh-pr-rollup'
7
9
  import { to_gh_state } from './git-gh-rest-state'
@@ -19,17 +21,6 @@ import { to_gh_state } from './git-gh-rest-state'
19
21
 
20
22
  const NO_HEAD_SHA_MESSAGE = 'gh api answered a pull request with no head commit'
21
23
 
22
- // Both commit endpoints answer an *object* wrapping the listing, so `--paginate` alone would emit
23
- // one document per page and `JSON.parse` would reject the pair; `--slurp` wraps the pages in one
24
- // outer array instead (`git-gh-exec.ts` → `GhApiRequest`).
25
- async function read_object_pages(path: string): Promise<string> {
26
- return await git_gh_exec.exec_gh_api({
27
- path: `${path}${FULL_PAGE_QUERY}`,
28
- should_paginate: true,
29
- should_slurp: true,
30
- })
31
- }
32
-
33
24
  // The reviews endpoint answers a bare array, whose pages `gh` merges into one array on its own —
34
25
  // slurping it would produce `[[…],[…]]`, which the listing schema then rejects.
35
26
  async function read_array_pages(path: string): Promise<string> {
@@ -47,11 +38,12 @@ function read_head_sha(pull: RestPull): string {
47
38
  }
48
39
 
49
40
  // One pull request's rollup: the check runs and the status contexts, read from the head commit and
50
- // merged back into the single array `gh` answered with.
41
+ // merged back into the single array `gh` answered with. Both endpoints answer an *object* wrapping the
42
+ // listing, so their pages arrive slurped into one outer array (`git-gh-poll-read.ts`).
51
43
  async function read_status_check_rollup(commit_sha: string): Promise<Array<object>> {
52
44
  const [check_runs_json, status_json] = await Promise.all([
53
- read_object_pages(git_gh_api_path.commit_check_runs_api_path(commit_sha)),
54
- read_object_pages(git_gh_api_path.commit_status_api_path(commit_sha)),
45
+ git_gh_poll_read.read_object_pages(git_gh_api_path.commit_check_runs_api_path(commit_sha)),
46
+ git_gh_poll_read.read_object_pages(git_gh_api_path.commit_status_api_path(commit_sha)),
55
47
  ])
56
48
 
57
49
  return git_gh_pr_rollup.to_status_check_rollup({ check_runs_json, status_json })
@@ -69,10 +61,24 @@ async function pr_get_review_decision(pr_number: number): Promise<string> {
69
61
  // `git-pr-checks-eval.ts` compares strictly against: `MERGE_STATE_CLEAN` never matches a lower-case
70
62
  // `clean`, which would also take every pull request out of the CodeRabbit non-blocking exemption
71
63
  // keyed on `UNSTABLE`. The rule is shared with `to_pr_info` rather than written twice.
64
+ //
65
+ // **`headRefOid` is the commit the rollup was read from**, in `gh`'s spelling, so a merge can be bound
66
+ // to the head whose checks passed rather than to whatever the branch points at by then (#4036).
67
+ //
68
+ // **`requiredContexts` is the base branch's required checks** (`git-gh-branch-rules.ts`), which the
69
+ // merge gate reads to accept an `UNSTABLE` pull request held only by an optional check.
72
70
  async function build_checks_fields(pull: RestPull): Promise<Record<string, unknown>> {
71
+ const head_sha = read_head_sha(pull)
72
+ const [rollup, required_contexts] = await Promise.all([
73
+ read_status_check_rollup(head_sha),
74
+ git_gh_branch_rules.read_required_contexts(pull.base?.ref),
75
+ ])
76
+
73
77
  return {
74
- statusCheckRollup: await read_status_check_rollup(read_head_sha(pull)),
78
+ statusCheckRollup: rollup,
75
79
  mergeStateStatus: to_gh_state(pull.mergeable_state),
80
+ headRefOid: head_sha,
81
+ requiredContexts: required_contexts,
76
82
  }
77
83
  }
78
84
 
@@ -81,12 +87,19 @@ interface ResolvedPull {
81
87
  pull: RestPull
82
88
  }
83
89
 
84
- // The resolution and the detail read, which every path below needs and which the branch → number
85
- // memo in `git-gh-pr-read.ts` makes free after the first poll.
90
+ // The resolution and the detail read, which every path below needs. The branch → number memo in
91
+ // `git-gh-pr-read.ts` makes the first free after the first poll.
92
+ //
93
+ // **The detail is read without an ETag.** GitHub computes `mergeable_state` lazily and can change it
94
+ // under an unchanged ETag, so a 304 answered from the poll cache kept the gate reading a stale
95
+ // `blocked` on a pull request that had turned `clean` (joshuafolkken/kit#4589).
86
96
  async function resolve_pull(branch_name: string): Promise<ResolvedPull> {
87
97
  const pr_number = await require_pr_number(branch_name)
98
+ const json = await git_gh_exec.exec_gh_api({
99
+ path: git_gh_api_path.pull_api_path(String(pr_number)),
100
+ })
88
101
 
89
- return { pr_number, pull: await read_pull(pr_number) }
102
+ return { pr_number, pull: git_gh_pr_rest.parse_rest_pull(json) }
90
103
  }
91
104
 
92
105
  // Everything the snapshot carries except the review decision: three requests rather than four.