@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
@@ -1,43 +1,36 @@
1
- #!/usr/bin/env tsx
2
- import { fileURLToPath } from 'node:url'
3
1
  import { git_gh_command } from '#scripts/gh/git-gh-command'
4
2
  import { issue_label_schema } from '#scripts/git/git-schemas'
5
3
  import { cutoff_of, type ScanCutoff } from '#scripts/git/listing-cutoff'
6
4
  import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
7
- import { issue_cite } from '#scripts/issue/issue-cite'
8
5
  import { session_cite } from '#scripts/issue/session-cite'
9
6
  import { bounded_pool } from '#scripts/lib/bounded-pool'
10
7
  import type { PollOptions } from '#scripts/lib/poll'
11
8
  import { issue_citation } from '#scripts/rules/issue-citation'
12
9
  import { z } from 'zod'
13
- import {
14
- epic_bundle,
15
- type BacklogIssue,
16
- type BundleAction,
17
- type BundleDecision,
18
- type MembershipContext,
19
- } from './epic-bundle'
20
- import { epic_bundle_evidence } from './epic-bundle-evidence'
10
+ import { epic_bundle, type BacklogIssue, type MembershipContext } from './epic-bundle'
11
+ import { epic_bundle_apply } from './epic-bundle-apply'
12
+ import { epic_bundle_format } from './epic-bundle-format'
21
13
  import { epic_bundle_gaps } from './epic-bundle-gaps'
22
14
  import { epic_bundle_poll } from './epic-bundle-poll'
23
15
  import { epic_bundle_referenced, type ReferencedContext } from './epic-bundle-referenced'
24
16
  import { epic_index, epic_schema, type FetchedEpics } from './epic-index'
25
17
  import { epic_issue } from './epic-issue'
26
- import { format_dependency_links, type IssueReference } from './epic-reference'
18
+ import type { IssueReference } from './epic-reference'
27
19
 
28
20
  // `josh epic:bundle <N>` — after an issue is filed, look at the open backlog and say whether it
29
21
  // belongs with something already there.
30
22
  //
31
23
  // The machine finds the candidates; the decision to bundle is the caller's. This command prints what
32
- // it found and what it recommends, and writes nothing.
24
+ // it found and what it recommends, and writes nothing — unless `--apply` asks it to write the answers
25
+ // whose placement is settled (`epic-bundle-apply.ts`).
33
26
 
34
27
  const SUCCESS_EXIT_CODE = 0
35
28
  const FAILURE_EXIT_CODE = 1
36
- const ARGV_OFFSET = 2
37
29
  // The open backlog was 13 issues when this was written. Scanning all of them is instant, so there is
38
30
  // no index and no cache; add one when the number makes it necessary, not before.
39
31
  const BACKLOG_LIMIT = 200
40
- const USAGE = 'Usage: josh epic:bundle <issue-number>'
32
+ const APPLY_FLAG = '--apply'
33
+ const USAGE = 'Usage: josh epic:bundle <issue-number> [--apply]'
41
34
  const UNKNOWN_REPO_MESSAGE =
42
35
  'Could not read this repository from `git remote`, so the backlog cannot be keyed by repository — check `gh auth status` and that this is a checkout with an `origin` remote.'
43
36
 
@@ -202,23 +195,7 @@ async function fetch_backlog(
202
195
  }
203
196
  }
204
197
 
205
- const ACTION_LINES: Readonly<Record<string, string>> = {
206
- add_to_epic: 'Add it to the epic that already tracks a related issue (Tier A — do it).',
207
- create_epic: 'Create an epic for these (Tier A — do it).',
208
- ask: 'Related issues sit in more than one epic: choose the one you recommend, add it, and record why (Tier A — do it).',
209
- none: 'Nothing to bundle.',
210
- }
211
-
212
- // `Nothing to bundle.` is right when nothing was found, and wrong when an epic already tracks the
213
- // issue — there the answer is actionable: a caller looking for somewhere to put a prerequisite adds
214
- // it to *that* epic rather than creating a second one.
215
- const ALREADY_TRACKED_LINE = 'Already in an epic — add to that one, do not create a second.'
216
-
217
- function headline(decision: BundleDecision): string {
218
- if (decision.action === 'none' && decision.epics.length > 0) return ALREADY_TRACKED_LINE
219
-
220
- return ACTION_LINES[decision.action] ?? ''
221
- }
198
+ const { format_decision } = epic_bundle_format
222
199
 
223
200
  // The epics currently open, at this command's own listing limit. A failed read stays `undefined` and
224
201
  // is reported: without the list, an issue an epic already tracks is told to create a second one —
@@ -227,72 +204,6 @@ async function fetch_epics(): Promise<FetchedEpics | undefined> {
227
204
  return await epic_index.fetch_epics(BACKLOG_LIMIT)
228
205
  }
229
206
 
230
- function format_numbers(numbers: ReadonlyArray<number>): string {
231
- return numbers.map((issue_number) => issue_cite.plain(issue_number)).join(', ')
232
- }
233
-
234
- // The order to record alongside the bundle. Bundling without it records the batch and loses the
235
- // reason it is a batch, so the recommendation carries it rather than leaving it to be remembered.
236
- function format_links(links: ReadonlyArray<{ blocker: number; blocked: number }>): string {
237
- if (links.length === 0) return ' Order: none declared — do not invent one'
238
-
239
- return ` Order: ${format_dependency_links(links)}`
240
- }
241
-
242
- function format_order(
243
- decision: BundleDecision,
244
- subject: BacklogIssue,
245
- backlog: ReadonlyArray<BacklogIssue>,
246
- ): Array<string> {
247
- if (decision.action !== 'add_to_epic' && decision.action !== 'create_epic') return []
248
- const members = backlog.filter((issue) => decision.candidates.includes(issue.number))
249
- const children = epic_bundle.bundle_children(subject, members)
250
-
251
- // The evidence goes under the order rather than beside the verdict: what it explains is the
252
- // order, and a reader checking one reads straight on into the other.
253
- return [
254
- ` Children: ${format_numbers(children)}`,
255
- format_links(epic_bundle.bundle_dependency_links(subject, members)),
256
- ...epic_bundle_evidence.format_evidence(subject, members),
257
- ]
258
- }
259
-
260
- // The verdicts that put the subject into an epic. Each one asserts that no epic already tracks it —
261
- // `create_epic` asserts as much about the candidates too — and that negative is exactly what a cut
262
- // epic listing cannot establish. `none` is absent on purpose: it either
263
- // names the epic it *found* tracking the subject, which a cut cannot unseat, or reports no candidate
264
- // at all, which says nothing about epics.
265
- const PLACING_ACTIONS: ReadonlySet<BundleAction> = new Set<BundleAction>([
266
- 'add_to_epic',
267
- 'create_epic',
268
- 'ask',
269
- ])
270
-
271
- // `is_membership_established` is what separates "no epic tracks these" from "their epics were never
272
- // read".
273
- function format_decision(
274
- decision: BundleDecision,
275
- subject: BacklogIssue,
276
- backlog: ReadonlyArray<BacklogIssue>,
277
- is_membership_established: boolean,
278
- ): string {
279
- if (!is_membership_established && PLACING_ACTIONS.has(decision.action)) {
280
- return epic_bundle_gaps.unconfirmed_membership(format_numbers(decision.candidates)).join('\n')
281
- }
282
-
283
- const lines = [headline(decision), ` ${decision.reason}`]
284
-
285
- if (decision.candidates.length > 0) {
286
- lines.push(` Related: ${format_numbers(decision.candidates)}`)
287
- }
288
-
289
- if (decision.epics.length > 1) {
290
- lines.push(` Epics involved: ${format_numbers(decision.epics)}`)
291
- }
292
-
293
- return [...lines, ...format_order(decision, subject, backlog)].join('\n')
294
- }
295
-
296
207
  // The open backlog and the epics tracking it, read once.
297
208
  async function read_backlog(repo: string, options?: BacklogOptions): Promise<FetchedBacklog> {
298
209
  const open_epics = await fetch_epics()
@@ -366,7 +277,13 @@ function warn_about_gaps(backlog: FetchedBacklog): void {
366
277
  warn_cutoff(epic_bundle_gaps.epic_gap(backlog.epic_cutoff ?? NO_CUTOFF, BACKLOG_LIMIT))
367
278
  }
368
279
 
369
- function report_decision(subject: BacklogIssue, backlog: FetchedBacklog, repo: string): number {
280
+ // The report always prints; `--apply` then writes what it settled (`epic-bundle-apply.ts`).
281
+ async function report_decision(
282
+ subject: BacklogIssue,
283
+ backlog: FetchedBacklog,
284
+ repo: string,
285
+ is_apply: boolean,
286
+ ): Promise<number> {
370
287
  const others = backlog.issues.filter((issue) => issue.number !== subject.number)
371
288
  const is_established = epic_bundle_gaps.is_membership_established(backlog.epic_cutoff)
372
289
  const decision = epic_bundle.decide_bundle(subject, others)
@@ -376,8 +293,14 @@ function report_decision(subject: BacklogIssue, backlog: FetchedBacklog, repo: s
376
293
  const report = format_decision(decision, subject, others, is_established)
377
294
 
378
295
  console.info(issue_citation.linkify(report, repo))
379
-
380
- return SUCCESS_EXIT_CODE
296
+ if (!is_apply) return SUCCESS_EXIT_CODE
297
+
298
+ return await epic_bundle_apply.apply_decision({
299
+ decision,
300
+ subject,
301
+ members: epic_bundle_format.members_of(decision, others),
302
+ is_membership_established: is_established,
303
+ })
381
304
  }
382
305
 
383
306
  // Widen, report what the read could not cover, then decide. Split out of `report_for`, which is
@@ -386,12 +309,13 @@ async function report_widened(
386
309
  subject: BacklogIssue,
387
310
  backlog: FetchedBacklog,
388
311
  repo: string,
312
+ is_apply: boolean,
389
313
  ): Promise<number> {
390
314
  const widened = await widen_with_referenced(subject, backlog)
391
315
 
392
316
  warn_about_gaps(widened)
393
317
 
394
- return report_decision(subject, widened, repo)
318
+ return await report_decision(subject, widened, repo, is_apply)
395
319
  }
396
320
 
397
321
  // The recommendation for one issue, from the open backlog around it. `options` is the poll a caller
@@ -400,6 +324,7 @@ async function report_for(
400
324
  issue_number: number,
401
325
  repo: string,
402
326
  options?: PollOptions,
327
+ is_apply = false,
403
328
  ): Promise<number> {
404
329
  const backlog = await epic_bundle_poll.read_until_listed(
405
330
  async () => await read_backlog(repo),
@@ -423,11 +348,12 @@ async function report_for(
423
348
  return FAILURE_EXIT_CODE
424
349
  }
425
350
 
426
- return await report_widened(subject, backlog, repo)
351
+ return await report_widened(subject, backlog, repo, is_apply)
427
352
  }
428
353
 
429
354
  async function run(argv: ReadonlyArray<string>): Promise<number> {
430
- const issue_number = epic_issue.parse_epic_number(argv[0])
355
+ const raw_issue = argv.find((argument) => argument !== APPLY_FLAG)
356
+ const issue_number = epic_issue.parse_epic_number(raw_issue)
431
357
 
432
358
  if (issue_number === undefined) {
433
359
  console.error(USAGE)
@@ -448,25 +374,14 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
448
374
  return FAILURE_EXIT_CODE
449
375
  }
450
376
 
451
- return await report_for(issue_number, repo)
452
- }
453
-
454
- // `process.exitCode` rather than `process.exit()`: the answer goes to standard output and a write to
455
- // a pipe is asynchronous on macOS, so exiting can tear the process down before it drains. This
456
- // command's answer is what a workflow reads and acts on, which is exactly that pipe. The same shape
457
- // is in `scripts/cost-runtime/cost-cli.ts`, which met the truncation first.
458
- async function main(argv: ReadonlyArray<string>): Promise<void> {
459
- process.exitCode = await run(argv)
377
+ return await report_for(issue_number, repo, undefined, argv.includes(APPLY_FLAG))
460
378
  }
461
379
 
462
380
  const epic_bundle_cli = {
463
381
  USAGE,
464
382
  BACKLOG_LIMIT,
465
- ACTION_LINES,
466
- ALREADY_TRACKED_LINE,
383
+ ...epic_bundle_format,
467
384
  build_epic_index,
468
- format_numbers,
469
- format_order,
470
385
  unreadable_backlog_message,
471
386
  read_backlog,
472
387
  report_for,
@@ -474,11 +389,7 @@ const epic_bundle_cli = {
474
389
  fetch_backlog,
475
390
  widen_with_referenced,
476
391
  warn_about_gaps,
477
- format_decision,
478
392
  run,
479
- main,
480
393
  }
481
394
 
482
- if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
483
-
484
395
  export { epic_bundle_cli }
@@ -1,4 +1,5 @@
1
1
  import { issue_cite } from '#scripts/issue/issue-cite'
2
+ import type { SignalSection } from './epic-audit'
2
3
  import { epic_bundle, type BacklogIssue } from './epic-bundle'
3
4
 
4
5
  // The facts the bundle decision was already made from, printed beside the order it prints.
@@ -20,10 +21,26 @@ import { epic_bundle, type BacklogIssue } from './epic-bundle'
20
21
  type EvidenceKind = 'dependency' | 'reference'
21
22
 
22
23
  // One fact, and the order it points to. `first` is the issue the fact puts ahead of `second`.
24
+ // `section` is where a reference was read, so the reader sees it was the acceptance criteria or the
25
+ // parent line that counted, not a mention elsewhere in the body.
23
26
  interface OrderingEvidence {
24
27
  kind: EvidenceKind
25
28
  first: number
26
29
  second: number
30
+ section?: SignalSection
31
+ }
32
+
33
+ // What one directed test found: nothing, or the fact with whatever detail it carries.
34
+ type EvidenceFound = Pick<OrderingEvidence, 'section'> | undefined
35
+
36
+ function blocker_found(from: BacklogIssue, to: BacklogIssue): EvidenceFound {
37
+ return epic_bundle.names_as_blocker(from, to) ? {} : undefined
38
+ }
39
+
40
+ function reference_found(from: BacklogIssue, to: BacklogIssue): EvidenceFound {
41
+ const section = epic_bundle.reference_section(from, to)
42
+
43
+ return section === undefined ? undefined : { section }
27
44
  }
28
45
 
29
46
  // The two readings, each written as a directed test of one issue against another. Both are
@@ -34,14 +51,28 @@ interface OrderingEvidence {
34
51
  // `blocked-by` says so outright: the blocker has to land before the issue that declares it. A
35
52
  // reference says it by having been written — the issue that names another was drafted with that
36
53
  // other one already in existence, so the named one is the earlier of the two.
37
- const EVIDENCE_TESTS: ReadonlyArray<{
54
+ interface EvidenceTest {
38
55
  kind: EvidenceKind
39
- holds: (from: BacklogIssue, to: BacklogIssue) => boolean
40
- }> = [
41
- { kind: 'dependency', holds: (from, to) => epic_bundle.names_as_blocker(from, to) },
42
- { kind: 'reference', holds: (from, to) => epic_bundle.names_in_body(from, to) },
56
+ find: (from: BacklogIssue, to: BacklogIssue) => EvidenceFound
57
+ }
58
+
59
+ const EVIDENCE_TESTS: ReadonlyArray<EvidenceTest> = [
60
+ { kind: 'dependency', find: blocker_found },
61
+ { kind: 'reference', find: reference_found },
43
62
  ]
44
63
 
64
+ // One test in one direction: the fact it found, or none.
65
+ function directed_evidence(
66
+ test: EvidenceTest,
67
+ from: BacklogIssue,
68
+ to: BacklogIssue,
69
+ ): Array<OrderingEvidence> {
70
+ const found = test.find(from, to)
71
+ if (found === undefined) return []
72
+
73
+ return [{ kind: test.kind, first: to.number, second: from.number, ...found }]
74
+ }
75
+
45
76
  // Both directions of one pair, because both are facts. Two issues that name each other produce two
46
77
  // lines pointing opposite ways, which is the honest report: the reader is the one deciding.
47
78
  function pair_evidence(subject: BacklogIssue, other: BacklogIssue): Array<OrderingEvidence> {
@@ -50,10 +81,8 @@ function pair_evidence(subject: BacklogIssue, other: BacklogIssue): Array<Orderi
50
81
  { from: other, to: subject },
51
82
  ]
52
83
 
53
- return EVIDENCE_TESTS.flatMap(({ kind, holds }) =>
54
- directions
55
- .filter((pair) => holds(pair.from, pair.to))
56
- .map((pair) => ({ kind, first: pair.to.number, second: pair.from.number })),
84
+ return EVIDENCE_TESTS.flatMap((test) =>
85
+ directions.flatMap((pair) => directed_evidence(test, pair.from, pair.to)),
57
86
  )
58
87
  }
59
88
 
@@ -85,8 +114,8 @@ function ordering_evidence(
85
114
  return member_pairs(members).flatMap((pair) => pair_evidence(pair.left, pair.right))
86
115
  }
87
116
 
88
- // How each kind reads. `where` says the fact came from prose rather than from a recorded relation,
89
- // and the two `order_*` halves say how strongly the fact settles the order.
117
+ // How each kind reads. The two `order_*` halves say how strongly the fact settles the order; where a
118
+ // reference was read comes from the fact itself (`section_phrase`).
90
119
  //
91
120
  // **A recorded dependency states the order; a reference only points at it.** A `blocked-by` says
92
121
  // outright that the blocker lands first. A reference says it by having been written — which holds
@@ -95,20 +124,14 @@ function ordering_evidence(
95
124
  // the reference line reports the direction it points to and asserts nothing further; deciding is
96
125
  // still the reader's.
97
126
  const EVIDENCE_WORDING: Readonly<
98
- Record<EvidenceKind, { verb: string; where: string; order_prefix: string; order_suffix: string }>
127
+ Record<EvidenceKind, { verb: string; order_prefix: string; order_suffix: string }>
99
128
  > = {
100
- dependency: {
101
- verb: 'is recorded as blocked by',
102
- where: '',
103
- order_prefix: '',
104
- order_suffix: ' comes first',
105
- },
106
- reference: {
107
- verb: 'names',
108
- where: ' in its body',
109
- order_prefix: 'that points to ',
110
- order_suffix: ' first',
111
- },
129
+ dependency: { verb: 'is recorded as blocked by', order_prefix: '', order_suffix: ' comes first' },
130
+ reference: { verb: 'names', order_prefix: 'that points to ', order_suffix: ' first' },
131
+ }
132
+
133
+ function section_phrase(item: OrderingEvidence): string {
134
+ return item.section === undefined ? '' : ` in its ${item.section}`
112
135
  }
113
136
 
114
137
  const EVIDENCE_HEADING = ' Evidence:'
@@ -117,12 +140,12 @@ const EVIDENCE_INDENT_WIDTH = 4
117
140
  const EVIDENCE_INDENT = ' '.repeat(EVIDENCE_INDENT_WIDTH)
118
141
 
119
142
  function format_one(item: OrderingEvidence): string {
120
- const { verb, where, order_prefix, order_suffix } = EVIDENCE_WORDING[item.kind]
143
+ const { verb, order_prefix, order_suffix } = EVIDENCE_WORDING[item.kind]
121
144
  const first = issue_cite.plain(item.first)
122
145
  const second = issue_cite.plain(item.second)
123
146
  const order = `${order_prefix}${first}${order_suffix}`
124
147
 
125
- return `${EVIDENCE_INDENT}${second} ${verb} ${first}${where} — ${order}`
148
+ return `${EVIDENCE_INDENT}${second} ${verb} ${first}${section_phrase(item)} — ${order}`
126
149
  }
127
150
 
128
151
  // The block that goes under `Order:`. Empty when neither reading found anything, which leaves the
@@ -0,0 +1,116 @@
1
+ import { issue_cite } from '#scripts/issue/issue-cite'
2
+ import {
3
+ epic_bundle,
4
+ type BacklogIssue,
5
+ type BundleAction,
6
+ type BundleDecision,
7
+ } from './epic-bundle'
8
+ import { epic_bundle_evidence } from './epic-bundle-evidence'
9
+ import { epic_bundle_gaps } from './epic-bundle-gaps'
10
+ import { format_dependency_links } from './epic-reference'
11
+
12
+ // How `josh epic:bundle` words its verdict. Split out of `epic-bundle-cli.ts`, which reads the backlog,
13
+ // when `--apply` pushed that file past its line ceiling; the wording has no reads of its own.
14
+
15
+ const ACTION_LINES: Readonly<Record<string, string>> = {
16
+ add_to_epic: 'Add it to the epic that already tracks a related issue (Tier A — do it).',
17
+ create_epic: 'Create an epic for these (Tier A — do it).',
18
+ ask: 'Related issues sit in more than one epic: choose the one you recommend, add it, and record why (Tier A — do it).',
19
+ none: 'Nothing to bundle.',
20
+ }
21
+
22
+ // `Nothing to bundle.` is right when nothing was found, and wrong when an epic already tracks the
23
+ // issue — there the answer is actionable: a caller looking for somewhere to put a prerequisite adds
24
+ // it to *that* epic rather than creating a second one.
25
+ const ALREADY_TRACKED_LINE = 'Already in an epic — add to that one, do not create a second.'
26
+
27
+ function headline(decision: BundleDecision): string {
28
+ if (decision.action === 'none' && decision.epics.length > 0) return ALREADY_TRACKED_LINE
29
+
30
+ return ACTION_LINES[decision.action] ?? ''
31
+ }
32
+
33
+ function format_numbers(numbers: ReadonlyArray<number>): string {
34
+ return numbers.map((issue_number) => issue_cite.plain(issue_number)).join(', ')
35
+ }
36
+
37
+ // The backlog rows of the verdict's candidates — what the printed order and `--apply` both read.
38
+ function members_of(
39
+ decision: BundleDecision,
40
+ backlog: ReadonlyArray<BacklogIssue>,
41
+ ): Array<BacklogIssue> {
42
+ return backlog.filter((issue) => decision.candidates.includes(issue.number))
43
+ }
44
+
45
+ // The order to record alongside the bundle. Bundling without it records the batch and loses the
46
+ // reason it is a batch, so the recommendation carries it rather than leaving it to be remembered.
47
+ function format_links(links: ReadonlyArray<{ blocker: number; blocked: number }>): string {
48
+ if (links.length === 0) return ' Order: none declared — do not invent one'
49
+
50
+ return ` Order: ${format_dependency_links(links)}`
51
+ }
52
+
53
+ function format_order(
54
+ decision: BundleDecision,
55
+ subject: BacklogIssue,
56
+ backlog: ReadonlyArray<BacklogIssue>,
57
+ ): Array<string> {
58
+ if (decision.action !== 'add_to_epic' && decision.action !== 'create_epic') return []
59
+ const members = members_of(decision, backlog)
60
+ const children = epic_bundle.bundle_children(subject, members)
61
+
62
+ // The evidence goes under the order rather than beside the verdict: what it explains is the
63
+ // order, and a reader checking one reads straight on into the other.
64
+ return [
65
+ ` Children: ${format_numbers(children)}`,
66
+ format_links(epic_bundle.bundle_dependency_links(subject, members)),
67
+ ...epic_bundle_evidence.format_evidence(subject, members),
68
+ ]
69
+ }
70
+
71
+ // The verdicts that put the subject into an epic. Each one asserts that no epic already tracks it —
72
+ // `create_epic` asserts as much about the candidates too — and that negative is exactly what a cut
73
+ // epic listing cannot establish. `none` is absent on purpose: it either
74
+ // names the epic it *found* tracking the subject, which a cut cannot unseat, or reports no candidate
75
+ // at all, which says nothing about epics.
76
+ const PLACING_ACTIONS: ReadonlySet<BundleAction> = new Set<BundleAction>([
77
+ 'add_to_epic',
78
+ 'create_epic',
79
+ 'ask',
80
+ ])
81
+
82
+ // `is_membership_established` is what separates "no epic tracks these" from "their epics were never
83
+ // read".
84
+ function format_decision(
85
+ decision: BundleDecision,
86
+ subject: BacklogIssue,
87
+ backlog: ReadonlyArray<BacklogIssue>,
88
+ is_membership_established: boolean,
89
+ ): string {
90
+ if (!is_membership_established && PLACING_ACTIONS.has(decision.action)) {
91
+ return epic_bundle_gaps.unconfirmed_membership(format_numbers(decision.candidates)).join('\n')
92
+ }
93
+
94
+ const lines = [headline(decision), ` ${decision.reason}`]
95
+
96
+ if (decision.candidates.length > 0) {
97
+ lines.push(` Related: ${format_numbers(decision.candidates)}`)
98
+ }
99
+
100
+ if (decision.epics.length > 1) {
101
+ lines.push(` Epics involved: ${format_numbers(decision.epics)}`)
102
+ }
103
+
104
+ return [...lines, ...format_order(decision, subject, backlog)].join('\n')
105
+ }
106
+
107
+ const epic_bundle_format = {
108
+ ACTION_LINES,
109
+ ALREADY_TRACKED_LINE,
110
+ format_numbers,
111
+ format_order,
112
+ format_decision,
113
+ members_of,
114
+ }
115
+
116
+ export { epic_bundle_format }
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { epic_bundle_cli } from './epic-bundle-cli'
4
+
5
+ // The `josh epic:bundle` entry, kept apart from `epic-bundle-cli.ts` because other modules import that
6
+ // one: a bundle is one file, so a main guard there would fire for every command that carries it
7
+ // (joshuafolkken/kit#4186).
8
+ //
9
+ // `process.exitCode` rather than `process.exit()`: the answer goes to standard output and a write to
10
+ // a pipe is asynchronous on macOS, so exiting can tear the process down before it drains. This
11
+ // command's answer is what a workflow reads and acts on, which is exactly that pipe. The same shape
12
+ // is in `scripts/cost-runtime/cost-main.ts`, which met the truncation first.
13
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
14
+ const ARGV_OFFSET = 2
15
+
16
+ process.exitCode = await epic_bundle_cli.run(process.argv.slice(ARGV_OFFSET))
17
+ }
@@ -44,10 +44,21 @@ interface ReferencedLookups {
44
44
  dropped: Array<number>
45
45
  }
46
46
 
47
+ // Every number the body names, the ones a bundle signal counts first: the cap below must not leave a
48
+ // signal unread because twenty background mentions came ahead of it in the body.
49
+ function signal_first(subject: BacklogIssue): Array<number> {
50
+ const signals = epic_audit_logic
51
+ .signal_references(subject.body, subject.repo)
52
+ .map((reference) => reference.number)
53
+ const all = epic_audit_logic.parse_references(subject.body, subject.repo)
54
+
55
+ return [...new Set([...signals, ...all])]
56
+ }
57
+
47
58
  function referenced_lookups(subject: BacklogIssue, known: ReadonlySet<number>): ReferencedLookups {
48
- const candidates = epic_audit_logic
49
- .parse_references(subject.body, subject.repo)
50
- .filter((number) => number !== subject.number && !known.has(number))
59
+ const candidates = signal_first(subject).filter(
60
+ (number) => number !== subject.number && !known.has(number),
61
+ )
51
62
 
52
63
  return {
53
64
  numbers: candidates.slice(0, REFERENCED_LOOKUP_LIMIT),
@@ -1,6 +1,6 @@
1
1
  import { issue_cite } from '#scripts/issue/issue-cite'
2
2
  import { has_label_name, RELEASE_LABEL } from '#scripts/issue/issue-labels'
3
- import { epic_audit_logic } from './epic-audit'
3
+ import { epic_audit_logic, type SignalSection } from './epic-audit'
4
4
  import { epic_graph } from './epic-graph'
5
5
  import type { DependencyLink } from './epic-parse'
6
6
  import type { IssueReference } from './epic-reference'
@@ -11,9 +11,9 @@ import type { IssueReference } from './epic-reference'
11
11
  // not reach the other way in: two issues filed days apart that turn out to be the front and back of
12
12
  // one job are executed separately, in whatever order, with the reasoning recorded nowhere.
13
13
  //
14
- // The candidate search reads issue references out of prose — the same reading `epic:audit` does
15
- // inside one epic. That analysis is imported rather than written a second time; the only
16
- // difference is what it is pointed at.
14
+ // The candidate search reads issue references out of the acceptance criteria and the `parent: #N`
15
+ // line — the same reading `epic:audit` does inside one epic. That analysis is imported rather than
16
+ // written a second time; the only difference is what it is pointed at.
17
17
 
18
18
  // An open issue as the search sees it.
19
19
  interface BacklogIssue {
@@ -59,11 +59,19 @@ interface BundleDecision {
59
59
  reason: string
60
60
  }
61
61
 
62
- // Whether `from`'s body names `to`. One direction of the citation test, because which direction it
63
- // was is what `epic-bundle-evidence.ts` reports — and the read is single-sourced here rather than
64
- // written a second time there, so the candidate search and the evidence beside it cannot drift apart.
62
+ // Where `from`'s body names `to` in a place that counts as a relation — its acceptance criteria or
63
+ // its `parent: #N` line — or nothing. One direction of the citation test, because which direction
64
+ // and which section it was is what `epic-bundle-evidence.ts` reports — and the read is single-sourced
65
+ // here rather than written a second time there, so the candidate search and the evidence beside it
66
+ // cannot drift apart. A number written only as the background of a filing is not a relation.
67
+ function reference_section(from: BacklogIssue, to: BacklogIssue): SignalSection | undefined {
68
+ return epic_audit_logic
69
+ .signal_references(from.body, from.repo)
70
+ .find((reference) => reference.number === to.number)?.section
71
+ }
72
+
65
73
  function names_in_body(from: BacklogIssue, to: BacklogIssue): boolean {
66
- return epic_audit_logic.parse_references(from.body, from.repo).includes(to.number)
74
+ return reference_section(from, to) !== undefined
67
75
  }
68
76
 
69
77
  // Whether two issues cite each other, in either direction. A one-way citation is enough: the point
@@ -324,7 +332,7 @@ function bundle_children(
324
332
 
325
333
  const epic_bundle = {
326
334
  names_as_blocker,
327
- names_in_body,
335
+ reference_section,
328
336
  NO_SIGNAL_REASON,
329
337
  already_tracked_reason,
330
338
  has_recorded_dependency,
@@ -1,12 +1,7 @@
1
1
  import { git_gh_command } from '#scripts/gh/git-gh-command'
2
2
  import { open_issue_schema, type OpenIssueData } from '#scripts/git/git-schemas'
3
3
  import { read_json_listing } from '#scripts/git/parse-json-array'
4
- import {
5
- ALREADY_DONE_LABEL,
6
- has_any_label,
7
- IN_PROGRESS_LABEL,
8
- NEEDS_DECISION_LABEL,
9
- } from '#scripts/issue/issue-labels'
4
+ import { has_any_label, IN_PROGRESS_LABEL, PARKED_LABELS } from '#scripts/issue/issue-labels'
10
5
  import { session_cite } from '#scripts/issue/session-cite'
11
6
 
12
7
  // How much of a repository's parallelism is already spoken for — asked of the *repository*, never of
@@ -34,12 +29,10 @@ const LISTING_LIMIT = 100
34
29
  // Read through `has_any_label` rather than compared directly, for the casing reason
35
30
  // `issue-labels.ts` records: GitHub keeps the spelling a label was created with.
36
31
  //
37
- // `already-done` joins `needs-decision` here for the same reason it joins it in
38
- // `epic_classify.local_category`: the run that applied it committed
39
- // nothing, so the checkout it ran in is clean and there is no uncommitted work for the next child to
40
- // start on top of. That is exactly what separates both from `needs-human-review`, which is
41
- // deliberately not parked because its work is still sitting in the tree.
42
- const PARKED_LABELS: ReadonlySet<string> = new Set([NEEDS_DECISION_LABEL, ALREADY_DONE_LABEL])
32
+ // The park labels (`PARKED_LABELS`): `already-done` and `run:stalled` join `needs-decision` here for
33
+ // the same reason they join it in `epic_classify.local_category`: the run that applied one leaves no
34
+ // uncommitted work for the next child to start on top of. That is exactly what separates them from
35
+ // `needs-human-review`, which is deliberately not parked because its work is still sitting in the tree.
43
36
 
44
37
  // What one repository answered. `unreadable` is kept apart from `idle` because reading a failed
45
38
  // read as an empty listing is a confident absence