@joshuafolkken/kit 1.1178.0 → 1.1240.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 (442) hide show
  1. package/.claude/.claude-plugin/plugin.json +1 -1
  2. package/.claude/settings.json +2 -2
  3. package/.claude/skills/dependency-update/SKILL.md +4 -8
  4. package/.claude/skills/epic-commands/SKILL.md +2 -2
  5. package/.claude/skills/epic-commands/epic-bundle.md +1 -1
  6. package/.claude/skills/workflow-commands/SKILL.md +2 -4
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +7 -3
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +23 -2
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +9 -4
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +4 -3
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +21 -13
  13. package/.claude/skills/workflow-commands/chain-rule.md +1 -1
  14. package/.claude/skills/workflow-commands/delegation.md +2 -2
  15. package/.claude/skills/workflow-commands/followup.md +10 -0
  16. package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
  17. package/.claude/skills/workflow-commands/halfrun.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  19. package/.claude/skills/workflow-commands/kickoff.md +2 -1
  20. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  21. package/.claude/skills/workflow-commands/observation-ledger.md +3 -3
  22. package/.claude/skills/workflow-commands/pre-gate-cut.md +6 -1
  23. package/.claude/skills/workflow-commands/prerequisite.md +2 -2
  24. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  25. package/.claude/skills/workflow-commands/working-tree-hold.md +1 -1
  26. package/.codex/hooks.json +2 -2
  27. package/.cursorrules +6 -41
  28. package/.github/actions/setup-node/action.yml +1 -1
  29. package/.github/workflows/auto-tag.yml +3 -4
  30. package/.github/workflows/ci.yml +32 -31
  31. package/.github/workflows/dependabot-auto-merge.yml +13 -6
  32. package/.github/workflows/publish.yml +50 -4
  33. package/.github/workflows/sonar-qube.yml +3 -0
  34. package/.pnpmfile.mjs +4 -3
  35. package/.prettierignore +8 -2
  36. package/CLAUDE.md +18 -20
  37. package/README.md +44 -38
  38. package/SECURITY.md +15 -1
  39. package/dist/CLAUDE.md +18 -20
  40. package/dist/commands/document-section-cli.js +734 -0
  41. package/dist/hooks/audit-provision.js +346 -0
  42. package/dist/hooks/batch-guard.js +5 -4
  43. package/dist/hooks/{chunk-G6KRCKEC.js → chunk-4TZVB44A.js} +496 -378
  44. package/dist/hooks/chunk-5VNDSNG3.js +12 -0
  45. package/dist/hooks/chunk-CDY4NFQG.js +15 -0
  46. package/dist/hooks/chunk-ELCN5LCH.js +135 -0
  47. package/dist/hooks/{chunk-VQLLNFNT.js → chunk-F3ELQ2AF.js} +3 -3
  48. package/dist/hooks/{chunk-I4XSL4TT.js → chunk-GPTFMK5E.js} +1 -1
  49. package/dist/hooks/{chunk-3V37IID6.js → chunk-JBBMAPC4.js} +23 -14
  50. package/dist/hooks/{chunk-UAGLLIGZ.js → chunk-KHGB5S3Y.js} +7 -6
  51. package/dist/hooks/{chunk-GDS5N2KB.js → chunk-KHX4U3BG.js} +735 -683
  52. package/dist/hooks/{chunk-VESKRQOF.js → chunk-KRBERBBI.js} +3 -3
  53. package/dist/hooks/{chunk-DO6NWWHU.js → chunk-QVSWU24O.js} +4 -4
  54. package/dist/hooks/{chunk-S6X6WYKR.js → chunk-WK2XSHSI.js} +1643 -923
  55. package/dist/hooks/{chunk-ZAL3NRGL.js → chunk-XZYKEM6J.js} +25 -10
  56. package/dist/hooks/{chunk-32GQTL4F.js → chunk-ZQGD4GBY.js} +4 -2
  57. package/dist/hooks/codex-hook-adapter.js +14 -12
  58. package/dist/hooks/duplicate-read-guard.js +6 -5
  59. package/dist/hooks/format-edited.js +4 -3
  60. package/dist/hooks/inputs.json +203 -179
  61. package/dist/hooks/investigation-guard.js +6 -5
  62. package/dist/hooks/pretool-guard.js +12 -10
  63. package/dist/hooks/session-lang.js +2 -4
  64. package/dist/hooks/stop-guard.js +66 -72
  65. package/dist/josh.js +1088 -78
  66. package/dist/version/index.d.ts +7 -2
  67. package/dist/version/index.js +152 -75
  68. package/eslint/base.js +23 -1
  69. package/eslint/rules/code-quality.js +3 -0
  70. package/eslint/rules/early-return-one-liner.js +98 -0
  71. package/eslint/rules/unicorn.js +16 -1
  72. package/package.json +7 -6
  73. package/pnpm-workspace.yaml +9 -4
  74. package/prettier/basic.d.ts +3 -1
  75. package/prettier/index.d.ts +3 -1
  76. package/prettier/static.d.ts +3 -1
  77. package/prompts/coding-standards.md +1 -1
  78. package/prompts/collaboration-workflow/file-edits.md +4 -4
  79. package/prompts/collaboration-workflow/glossary.md +1 -1
  80. package/prompts/collaboration-workflow/issue-template.md +1 -0
  81. package/prompts/collaboration-workflow/operating-rules.md +17 -9
  82. package/prompts/collaboration-workflow/overview.md +2 -2
  83. package/prompts/collaboration-workflow/principles.md +14 -12
  84. package/prompts/collaboration-workflow/report-format.md +1 -1
  85. package/prompts/collaboration-workflow/residency.md +1 -1
  86. package/prompts/collaboration-workflow/rule-delivery.md +6 -6
  87. package/prompts/collaboration-workflow/shell-body.md +6 -6
  88. package/prompts/collaboration-workflow/turn-batching.md +1 -1
  89. package/prompts/collaboration-workflow/upstream-interrupt.md +12 -2
  90. package/prompts/collaboration-workflow/wip-cap.md +10 -10
  91. package/prompts/review-rubric.md +1 -2
  92. package/prompts/review.md +1 -1
  93. package/scripts/agent/agent-headless.ts +29 -0
  94. package/scripts/agent/agent-launch-environment.ts +6 -2
  95. package/scripts/agent/codex-agent-argv.ts +2 -1
  96. package/scripts/auto-ok/auto-ok-cli.ts +1 -1
  97. package/scripts/backlog/backlog-arrival.ts +3 -3
  98. package/scripts/backlog/backlog-budget.ts +1 -1
  99. package/scripts/backlog/backlog-drive-args.ts +135 -0
  100. package/scripts/backlog/backlog-drive-cli.ts +11 -137
  101. package/scripts/backlog/backlog-drive-launch.ts +39 -0
  102. package/scripts/backlog/backlog-drive-named-offer.ts +3 -5
  103. package/scripts/backlog/backlog-drive-named.ts +3 -3
  104. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  105. package/scripts/backlog/backlog-drive-owner.ts +1 -1
  106. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  107. package/scripts/backlog/backlog-drive-retrospective.ts +1 -1
  108. package/scripts/backlog/backlog-drive.ts +1 -1
  109. package/scripts/backlog/backlog-next.ts +16 -5
  110. package/scripts/backlog/backlog-offer-cli.ts +6 -6
  111. package/scripts/backlog/backlog-offer.ts +1 -1
  112. package/scripts/backlog/backlog-plan-cli.ts +1 -1
  113. package/scripts/backlog/backlog-pool.ts +57 -11
  114. package/scripts/backlog/backlog-ready.ts +1 -1
  115. package/scripts/backlog/backlog-scope.ts +1 -1
  116. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  117. package/scripts/backlog/backlog-stalled.ts +1 -1
  118. package/scripts/build/build-codex-hooks.ts +3 -1
  119. package/scripts/build/build-commands.ts +66 -0
  120. package/scripts/build/build-hooks.ts +2 -1
  121. package/scripts/build/build-library.ts +12 -3
  122. package/scripts/build/build.ts +70 -0
  123. package/scripts/build/local-bin.ts +3 -13
  124. package/scripts/delegation/investigation-reads.ts +3 -1
  125. package/scripts/discovery/repo-origin.ts +5 -5
  126. package/scripts/doctor/doctor-consumer.ts +2 -2
  127. package/scripts/doctor/doctor-io.ts +2 -3
  128. package/scripts/document/capped-print-part.ts +30 -0
  129. package/scripts/document/capped-print.ts +3 -4
  130. package/scripts/document/document-byte-budget.ts +11 -2
  131. package/scripts/document/document-scan.ts +117 -0
  132. package/scripts/document/document-section.ts +143 -16
  133. package/scripts/document/entry-read-budget.ts +5 -3
  134. package/scripts/document/entry-read-set.ts +10 -89
  135. package/scripts/document/read-set-cost.ts +98 -0
  136. package/scripts/epic/epic-add-body.ts +1 -0
  137. package/scripts/epic/epic-audit-checks.ts +1 -1
  138. package/scripts/epic/epic-audit-rationale.ts +4 -3
  139. package/scripts/epic/epic-bundle-cli.ts +14 -3
  140. package/scripts/epic/epic-bundle-poll.ts +41 -0
  141. package/scripts/epic/epic-busy.ts +1 -1
  142. package/scripts/epic/epic-candidate-confirm.ts +3 -2
  143. package/scripts/epic/epic-classify.ts +1 -1
  144. package/scripts/epic/epic-cli-argv.ts +78 -46
  145. package/scripts/epic/epic-cli-remove.ts +11 -19
  146. package/scripts/epic/epic-cli.ts +74 -73
  147. package/scripts/epic/epic-close-comment.ts +1 -1
  148. package/scripts/epic/epic-close.ts +1 -1
  149. package/scripts/epic/epic-cross-repo.ts +5 -5
  150. package/scripts/epic/epic-graph.ts +1 -1
  151. package/scripts/epic/epic-index.ts +1 -1
  152. package/scripts/epic/epic-issue.ts +2 -6
  153. package/scripts/epic/epic-lane-offer.ts +2 -2
  154. package/scripts/epic/epic-next.ts +29 -42
  155. package/scripts/epic/epic-solo-stale.ts +1 -1
  156. package/scripts/epic/epic-triage.ts +8 -4
  157. package/scripts/epic/epic-validate.ts +1 -1
  158. package/scripts/followup/git-followup-finish.ts +2 -2
  159. package/scripts/followup/git-followup-label.ts +2 -2
  160. package/scripts/followup/git-followup-merged.ts +2 -2
  161. package/scripts/followup/git-pr-followup-checks.ts +142 -0
  162. package/scripts/followup/git-pr-followup.ts +4 -129
  163. package/scripts/gate/core-admission.ts +162 -0
  164. package/scripts/gate/core-budget.ts +190 -68
  165. package/scripts/gate/gate-plan.ts +80 -7
  166. package/scripts/gate/gate-report.ts +28 -9
  167. package/scripts/gate/gate-skip.ts +38 -7
  168. package/scripts/gate/hook-gate-reuse.ts +12 -10
  169. package/scripts/gate/machine-capacity.ts +175 -0
  170. package/scripts/gate/pre-commit-type-check.ts +4 -1
  171. package/scripts/gate/project-checks.ts +6 -9
  172. package/scripts/gate/type-check-step.ts +2 -3
  173. package/scripts/gate/verification-gate.ts +34 -10
  174. package/scripts/gh/git-gh-api-path.ts +2 -2
  175. package/scripts/gh/git-gh-issue-rest.ts +3 -3
  176. package/scripts/gh/git-gh-issue-write.ts +53 -7
  177. package/scripts/gh/git-gh-pr-read.ts +64 -19
  178. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  179. package/scripts/gh/git-gh-pr.ts +5 -1
  180. package/scripts/gh/git-pr-ai-review.ts +1 -1
  181. package/scripts/gh/git-pr-checks-eval.ts +1 -3
  182. package/scripts/gh/git-pr-checks-parse.ts +1 -1
  183. package/scripts/gh/git-pr-checks-watch.ts +6 -5
  184. package/scripts/gh/git-pr-checks.ts +7 -5
  185. package/scripts/gh/git-pr-coderabbit.ts +1 -1
  186. package/scripts/gh/git-pr-error.ts +1 -3
  187. package/scripts/gh/git-pr.ts +9 -13
  188. package/scripts/gh/github-issue-url.ts +2 -2
  189. package/scripts/git/constants.ts +2 -6
  190. package/scripts/git/git-command.ts +20 -218
  191. package/scripts/git/git-diff-reads.ts +225 -0
  192. package/scripts/git/git-error.ts +4 -12
  193. package/scripts/git/git-pre-push-hook.ts +139 -0
  194. package/scripts/git/git-prompt.ts +2 -6
  195. package/scripts/git/git-spawn-sync.ts +3 -1
  196. package/scripts/git/git-spawn.ts +1 -1
  197. package/scripts/git/git-staging.ts +4 -6
  198. package/scripts/git/git-status.ts +3 -9
  199. package/scripts/hooks/codex-hook-adapter.ts +1 -1
  200. package/scripts/hooks/edited-cspell.ts +2 -4
  201. package/scripts/hooks/format-edited-file.ts +3 -12
  202. package/scripts/hooks/pre-push-unit.ts +31 -9
  203. package/scripts/hooks/reserved-run.ts +2 -2
  204. package/scripts/hooks/run-hook.sh +5 -4
  205. package/scripts/hooks/stop-guard.ts +5 -3
  206. package/scripts/init/init-actions.ts +0 -5
  207. package/scripts/init/init-ai-copy.ts +13 -2
  208. package/scripts/init/init-logic-json-merge.ts +19 -0
  209. package/scripts/init/init-logic-secretlint.ts +7 -7
  210. package/scripts/init/init-logic-workspace.ts +41 -2
  211. package/scripts/init/init-logic.ts +16 -26
  212. package/scripts/init/init.ts +10 -16
  213. package/scripts/init/initial-commit.ts +4 -4
  214. package/scripts/init/kit-development-versions.ts +40 -0
  215. package/scripts/init/kit-setup-state.ts +2 -2
  216. package/scripts/init/package-manager-pin.ts +35 -0
  217. package/scripts/init/start-exec.ts +68 -19
  218. package/scripts/init/start-setup-pr.ts +9 -9
  219. package/scripts/init/start-steps.ts +6 -10
  220. package/scripts/issue/defect-rate-cli.ts +1 -1
  221. package/scripts/issue/git-next-issues.ts +1 -1
  222. package/scripts/issue/issue-auto-ok.ts +32 -7
  223. package/scripts/issue/issue-backlinks-cli.ts +2 -2
  224. package/scripts/issue/issue-backlinks.ts +9 -9
  225. package/scripts/issue/issue-comment-cli.ts +19 -13
  226. package/scripts/issue/issue-file-cli.ts +72 -22
  227. package/scripts/issue/issue-file.ts +29 -1
  228. package/scripts/issue/issue-labels.ts +13 -0
  229. package/scripts/issue/issue-release-cli.ts +155 -0
  230. package/scripts/issue/issue-release.ts +58 -0
  231. package/scripts/issue/issue-scout-closed.ts +1 -1
  232. package/scripts/issue/issue-state-cli.ts +30 -74
  233. package/scripts/josh/josh-command-map.ts +2 -0
  234. package/scripts/josh/josh-command-types.ts +14 -0
  235. package/scripts/josh/josh-commands-ai.ts +4 -4
  236. package/scripts/josh/josh-commands-backlog.ts +4 -1
  237. package/scripts/josh/josh-commands-development.ts +18 -0
  238. package/scripts/josh/josh-commands-document.ts +1 -0
  239. package/scripts/josh/josh-commands-issue.ts +8 -1
  240. package/scripts/josh/josh-commands-lane.ts +24 -1
  241. package/scripts/josh/josh-commands-maintenance.ts +6 -6
  242. package/scripts/josh/josh-commands-run.ts +12 -7
  243. package/scripts/josh/josh-in-process.ts +28 -9
  244. package/scripts/josh/josh-logic.ts +34 -15
  245. package/scripts/josh/process-identity.ts +1 -3
  246. package/scripts/josh/session-language-cli.ts +3 -4
  247. package/scripts/lane/lane-await.ts +5 -1
  248. package/scripts/lane/lane-child-invocation.ts +2 -2
  249. package/scripts/lane/lane-cli.ts +12 -4
  250. package/scripts/lane/lane-dispatch.ts +14 -10
  251. package/scripts/lane/lane-environment.ts +5 -1
  252. package/scripts/lane/lane-handoff.ts +1 -1
  253. package/scripts/lane/lane-install.ts +2 -13
  254. package/scripts/lane/lane-launch-cli.ts +15 -1
  255. package/scripts/lane/lane-ledger.ts +145 -0
  256. package/scripts/lane/lane-leftover.ts +44 -30
  257. package/scripts/lane/lane-load.ts +108 -0
  258. package/scripts/lane/lane-measure-cli.ts +149 -0
  259. package/scripts/lane/lane-occupancy.ts +3 -0
  260. package/scripts/lane/lane-open.ts +5 -5
  261. package/scripts/lane/lane-paths.ts +13 -0
  262. package/scripts/lane/lane-reap.ts +1 -3
  263. package/scripts/lane/lane-registry.ts +11 -0
  264. package/scripts/lane/lane-relaunch.ts +1 -1
  265. package/scripts/lane/lane-stats.ts +224 -0
  266. package/scripts/lane/lane-stray.ts +140 -0
  267. package/scripts/lane/lane-vacant.ts +36 -0
  268. package/scripts/lane/openai-lane-ship.ts +2 -2
  269. package/scripts/lane/openai-lane-supervisor-owner.ts +180 -0
  270. package/scripts/lane/openai-lane-supervisor.ts +7 -165
  271. package/scripts/lane/openai-review-broker.ts +2 -4
  272. package/scripts/lib/ancestor-directories.ts +35 -0
  273. package/scripts/lib/animation-helpers.ts +2 -2
  274. package/scripts/lib/buffered-process.ts +3 -7
  275. package/scripts/lib/cli-flags.ts +71 -1
  276. package/scripts/lib/spawn-exit.ts +2 -2
  277. package/scripts/lib/timeouts.ts +35 -2
  278. package/scripts/lines/line-budget.ts +4 -6
  279. package/scripts/notify/telegram-test.ts +6 -0
  280. package/scripts/observations/observation-ledger-line.ts +6 -6
  281. package/scripts/observations/observation-ledger-migrate.ts +55 -4
  282. package/scripts/observations/observation-ledger.ts +26 -7
  283. package/scripts/overrides/lockfile-overrides.ts +1 -1
  284. package/scripts/overrides/overrides-logic.ts +1 -1
  285. package/scripts/propagate/propagate-git.ts +1 -1
  286. package/scripts/propagate/propagate-publish.ts +2 -2
  287. package/scripts/propagate/propagate-steps.ts +20 -15
  288. package/scripts/propagate/propagate.ts +36 -27
  289. package/scripts/refactor/import-graph.ts +18 -1
  290. package/scripts/refactor/refactor-lint.ts +4 -4
  291. package/scripts/release/github-release-environment.ts +1 -0
  292. package/scripts/release/github-release-runs.ts +115 -0
  293. package/scripts/release/github-release.ts +13 -67
  294. package/scripts/repo/repository-labels.ts +2 -2
  295. package/scripts/repo/required-checks-logic.ts +1 -3
  296. package/scripts/review/live-evidence.ts +2 -4
  297. package/scripts/review/review-brief-cli.ts +1 -1
  298. package/scripts/review/review-finding-ledger.ts +1 -1
  299. package/scripts/review/review-findings-cli.ts +1 -3
  300. package/scripts/rules/decision-oracle-batch.ts +128 -0
  301. package/scripts/rules/decision-oracle-tokens.ts +21 -0
  302. package/scripts/rules/decision-oracle.ts +8 -120
  303. package/scripts/rules/delivered-rules.ts +26 -182
  304. package/scripts/rules/direct-filing.ts +1 -1
  305. package/scripts/rules/early-heartbeat.ts +3 -3
  306. package/scripts/rules/git-argv.ts +1 -1
  307. package/scripts/rules/git-force.ts +1 -1
  308. package/scripts/rules/implementation-cut.ts +2 -2
  309. package/scripts/rules/index-guard.ts +1 -1
  310. package/scripts/rules/issue-comments.ts +118 -0
  311. package/scripts/rules/{issue-fold.ts → issue-fold-rule.ts} +2 -2
  312. package/scripts/rules/lane-background.ts +2 -2
  313. package/scripts/rules/lane-park.ts +18 -0
  314. package/scripts/rules/lane-split-park.ts +128 -0
  315. package/scripts/rules/oracle-firing.ts +1 -1
  316. package/scripts/rules/poll-loop.ts +1 -1
  317. package/scripts/rules/pre-gate-cut.ts +1 -1
  318. package/scripts/rules/protected-files.ts +59 -4
  319. package/scripts/rules/{run-tail.ts → run-tail-rule.ts} +2 -2
  320. package/scripts/rules/shell-body-trigger.ts +1 -1
  321. package/scripts/rules/stop-rules.ts +18 -7
  322. package/scripts/rules/test-declared-commit.ts +4 -4
  323. package/scripts/rules/wip-cap.ts +63 -0
  324. package/scripts/run/{run-carry-args.ts → carry/run-carry-args.ts} +37 -13
  325. package/scripts/run/{run-carry-change.ts → carry/run-carry-change.ts} +29 -7
  326. package/scripts/run/{run-carry-cli.ts → carry/run-carry-cli.ts} +4 -6
  327. package/scripts/run/{run-carry.ts → carry/run-carry.ts} +1 -1
  328. package/scripts/run/{run-cut-args.ts → cut/run-cut-args.ts} +1 -1
  329. package/scripts/run/{run-cut-cli.ts → cut/run-cut-cli.ts} +18 -5
  330. package/scripts/run/{run-cut.ts → cut/run-cut.ts} +1 -1
  331. package/scripts/run/{run-entry-cli.ts → entry/run-entry-cli.ts} +11 -11
  332. package/scripts/run/{run-entry.ts → entry/run-entry.ts} +2 -2
  333. package/scripts/run/{run-event-render.ts → event/run-event-render.ts} +1 -0
  334. package/scripts/run/{run-event-scope.ts → event/run-event-scope.ts} +1 -1
  335. package/scripts/run/{run-event-stream-emit.ts → event/run-event-stream-emit.ts} +1 -1
  336. package/scripts/run/{run-event-stream.ts → event/run-event-stream.ts} +20 -2
  337. package/scripts/run/{run-hold-cli.ts → hold/run-hold-cli.ts} +5 -5
  338. package/scripts/run/{run-merge-cli.ts → merge/run-merge-cli.ts} +10 -5
  339. package/scripts/run/{run-merge-steps.ts → merge/run-merge-steps.ts} +53 -5
  340. package/scripts/run/{run-merge.ts → merge/run-merge.ts} +1 -1
  341. package/scripts/run/{run-progress-cli.ts → progress/run-progress-cli.ts} +1 -1
  342. package/scripts/run/{run-progress-config.ts → progress/run-progress-config.ts} +2 -17
  343. package/scripts/run/{run-progress-read.ts → progress/run-progress-read.ts} +5 -5
  344. package/scripts/run/{run-progress.ts → progress/run-progress.ts} +1 -1
  345. package/scripts/run/{run-review-steps.ts → review/run-review-steps.ts} +2 -3
  346. package/scripts/run/run-ending.ts +2 -2
  347. package/scripts/run/run-halfrun-resume.ts +6 -1
  348. package/scripts/run/run-headless.ts +1 -1
  349. package/scripts/run/run-invocation.ts +85 -84
  350. package/scripts/run/run-liveness.ts +1 -1
  351. package/scripts/run/run-parent-cut-hook.ts +1 -1
  352. package/scripts/run/run-preflight.ts +6 -6
  353. package/scripts/run/run-prep-cli.ts +1 -1
  354. package/scripts/run/run-prrun-resume.ts +1 -1
  355. package/scripts/run/run-report-cli.ts +4 -4
  356. package/scripts/run/run-report.ts +2 -2
  357. package/scripts/run/run-status-cli.ts +1 -1
  358. package/scripts/run/run-step-cli.ts +3 -3
  359. package/scripts/run/run-step.ts +7 -4
  360. package/scripts/run/run-stop-notify.ts +1 -1
  361. package/scripts/run/run-stranded-detect.ts +4 -4
  362. package/scripts/run/run-stranded.ts +2 -2
  363. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  364. package/scripts/run/run-watcher-guard.ts +5 -3
  365. package/scripts/run/run-watcher-hook.ts +1 -1
  366. package/scripts/run/{run-ship-cli.ts → ship/run-ship-cli.ts} +2 -2
  367. package/scripts/run/{run-ship-detach.ts → ship/run-ship-detach.ts} +3 -3
  368. package/scripts/run/ship/run-ship-lock.ts +50 -0
  369. package/scripts/run/{run-ship-preflight.ts → ship/run-ship-preflight.ts} +6 -2
  370. package/scripts/run/{run-ship-probe.ts → ship/run-ship-probe.ts} +2 -2
  371. package/scripts/run/{run-ship-return.ts → ship/run-ship-return.ts} +4 -3
  372. package/scripts/run/{run-ship-review-steps.ts → ship/run-ship-review-steps.ts} +3 -3
  373. package/scripts/run/{run-ship-scoped.ts → ship/run-ship-scoped.ts} +10 -1
  374. package/scripts/run/{run-ship-steps.ts → ship/run-ship-steps.ts} +11 -12
  375. package/scripts/run/ship/run-ship-stop-text.ts +13 -0
  376. package/scripts/run/{run-ship-sync.ts → ship/run-ship-sync.ts} +25 -11
  377. package/scripts/run/{run-tidy-lanes.ts → tidy/run-tidy-lanes.ts} +1 -1
  378. package/scripts/run/{run-wake-cli.ts → wake/run-wake-cli.ts} +25 -11
  379. package/scripts/run/{run-wake-describe.ts → wake/run-wake-describe.ts} +58 -7
  380. package/scripts/run/{run-wake-driver.ts → wake/run-wake-driver.ts} +59 -8
  381. package/scripts/run/{run-wake-handoff.ts → wake/run-wake-handoff.ts} +1 -1
  382. package/scripts/run/{run-wake-loop.ts → wake/run-wake-loop.ts} +13 -15
  383. package/scripts/run/wake/run-wake-restart.ts +58 -0
  384. package/scripts/run/{run-wake-session.ts → wake/run-wake-session.ts} +3 -3
  385. package/scripts/run/{run-wake.ts → wake/run-wake.ts} +16 -65
  386. package/scripts/safe-chain/preinstall-command.ts +20 -21
  387. package/scripts/safe-chain/project-config.ts +19 -15
  388. package/scripts/sync/sync-ai-files.ts +1 -1
  389. package/scripts/sync/sync-configs.ts +2 -1
  390. package/scripts/sync/sync.ts +15 -2
  391. package/scripts/test/unit-worker-share.ts +1 -0
  392. package/scripts/time-runtime/time-background.ts +5 -1
  393. package/scripts/time-runtime/time-instant.ts +3 -1
  394. package/scripts/time-runtime/time-spans.ts +6 -139
  395. package/scripts/time-runtime/time-tool-call.ts +160 -0
  396. package/scripts/version/effective-upstream.ts +2 -20
  397. package/scripts/version/latest-corepack.ts +124 -93
  398. package/scripts/version/latest-regression.ts +1 -1
  399. package/scripts/version/latest-update.ts +4 -4
  400. package/scripts/version/npm-registry.ts +20 -5
  401. package/scripts/version/publishable-range-check.ts +2 -2
  402. package/scripts/version/publishable-range.ts +1 -1
  403. package/scripts/version/release-age.ts +48 -38
  404. package/scripts/version/release-hold.ts +1 -1
  405. package/scripts/version/safe-chain-version-update.ts +40 -0
  406. package/scripts/version/upgrade-shell-command.ts +48 -8
  407. package/scripts/version/version-check-logic.ts +23 -14
  408. package/scripts/version/version-commands.ts +23 -11
  409. package/scripts/version/version-remote.ts +28 -13
  410. package/templates/pnpm-workspace.basic.yaml +4 -0
  411. package/templates/workflows/dependabot-auto-merge.yml +5 -5
  412. package/templates/workflows/github-release.yml +6 -0
  413. package/scripts/build/build-config-merge.ts +0 -27
  414. package/scripts/build/build-managed-marker.ts +0 -27
  415. package/scripts/build/build-self-sync-guard.ts +0 -27
  416. package/scripts/build/build-version.ts +0 -26
  417. package/scripts/version/preinstall-version-update.ts +0 -86
  418. /package/scripts/git/{schemas.ts → git-schemas.ts} +0 -0
  419. /package/scripts/overrides/{schemas.ts → overrides-schemas.ts} +0 -0
  420. /package/scripts/run/{run-carry-conversation.ts → carry/run-carry-conversation.ts} +0 -0
  421. /package/scripts/run/{run-carry-reclaim.ts → carry/run-carry-reclaim.ts} +0 -0
  422. /package/scripts/run/{run-carry-stash.ts → carry/run-carry-stash.ts} +0 -0
  423. /package/scripts/run/{run-carry-streak.ts → carry/run-carry-streak.ts} +0 -0
  424. /package/scripts/run/{run-cut-handoff.ts → cut/run-cut-handoff.ts} +0 -0
  425. /package/scripts/run/{run-cut-report.ts → cut/run-cut-report.ts} +0 -0
  426. /package/scripts/run/{run-entry-stop.ts → entry/run-entry-stop.ts} +0 -0
  427. /package/scripts/run/{run-event-cli.ts → event/run-event-cli.ts} +0 -0
  428. /package/scripts/run/{run-event-follow.ts → event/run-event-follow.ts} +0 -0
  429. /package/scripts/run/{run-event-watch.ts → event/run-event-watch.ts} +0 -0
  430. /package/scripts/run/{run-hold.ts → hold/run-hold.ts} +0 -0
  431. /package/scripts/run/{run-progress-args.ts → progress/run-progress-args.ts} +0 -0
  432. /package/scripts/run/{run-progress-clock.ts → progress/run-progress-clock.ts} +0 -0
  433. /package/scripts/run/{run-review-cli.ts → review/run-review-cli.ts} +0 -0
  434. /package/scripts/run/{run-review.ts → review/run-review.ts} +0 -0
  435. /package/scripts/run/{run-ship-next.ts → ship/run-ship-next.ts} +0 -0
  436. /package/scripts/run/{run-ship-pre-detach.ts → ship/run-ship-pre-detach.ts} +0 -0
  437. /package/scripts/run/{run-ship-review.ts → ship/run-ship-review.ts} +0 -0
  438. /package/scripts/run/{run-ship-stage.ts → ship/run-ship-stage.ts} +0 -0
  439. /package/scripts/run/{run-ship.ts → ship/run-ship.ts} +0 -0
  440. /package/scripts/run/{run-tidy-cli.ts → tidy/run-tidy-cli.ts} +0 -0
  441. /package/scripts/run/{run-tidy-stashes.ts → tidy/run-tidy-stashes.ts} +0 -0
  442. /package/scripts/run/{run-tidy.ts → tidy/run-tidy.ts} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { setTimeout } from 'node:timers/promises'
2
2
  import semver from 'semver'
3
3
  import { z } from 'zod'
4
+ import { github_release_runs, type PollState, type RunSource } from './github-release-runs'
4
5
 
5
6
  const API_ROOT = 'https://api.github.com/repos'
6
7
  const LATEST_PATH = '/releases/latest'
@@ -8,42 +9,26 @@ const REPOSITORY_PATTERN = /^[\w.-]+\/[\w.-]+$/u
8
9
  const TAG_PATTERN = /^v\d+\.\d+\.\d+(?:[.-][0-9A-Za-z.-]+)?$/u
9
10
  const REQUEST_TIMEOUT_MS = 30_000
10
11
  const NOT_FOUND_STATUS = 404
11
- // A job skipped by its `if:` (or neutral) belongs to a run that succeeded; counting it would skip a
12
- // lower tag whose release is still on its way.
13
- const FAILED_CONCLUSIONS = new Set(['failure', 'cancelled', 'timed_out', 'startup_failure'])
14
12
  const POLL_INTERVAL_MS = 30_000
15
13
  const MAX_WAIT_ATTEMPTS = 120
16
14
  const RELEASE_SCHEMA = z.object({ tag_name: z.string().min(1) })
17
15
  const NOTES_SCHEMA = z.object({ name: z.string().min(1), body: z.string().min(1) })
18
- const RUN_SCHEMA = z.object({
19
- id: z.number(),
20
- display_title: z.string(),
21
- status: z.string().optional(),
22
- conclusion: z.string().nullable().optional(),
23
- })
24
- const JOB_SCHEMA = z.object({
25
- name: z.string(),
26
- status: z.string(),
27
- conclusion: z.string().nullable(),
28
- })
29
- const RUNS_SCHEMA = z.object({ workflow_runs: z.array(RUN_SCHEMA) })
30
- const JOBS_SCHEMA = z.object({ jobs: z.array(JOB_SCHEMA) })
31
-
32
16
  type ReleaseRequest = (url: string, init: RequestInit) => Promise<Response>
33
17
  type Wait = () => Promise<void>
34
- type PollState = 'ready' | 'failed' | 'pending'
35
18
 
36
19
  // What differs between repositories. `start_tag` is the last tag that predates automatic releases;
37
20
  // without it the latest existing release is the floor. `workflow` names the publish workflow whose
38
21
  // failed run lets a lower tag be skipped, and `jobs` the jobs in it that count (empty: every job).
39
22
  // `await_publish` holds the tag's own release until its run in that workflow has succeeded, for a
40
- // release started beside the publication rather than from inside it.
23
+ // release started beside the publication rather than from inside it. `release_run_workflow` names
24
+ // the workflow whose run creates a tag's release, so a lower tag left without one can be told lost.
41
25
  interface ReleaseSettings {
42
26
  repository: string
43
27
  start_tag?: string | undefined
44
28
  workflow?: string | undefined
45
29
  jobs?: ReadonlyArray<string> | undefined
46
30
  await_publish?: boolean | undefined
31
+ release_run_workflow?: string | undefined
47
32
  }
48
33
 
49
34
  interface PublishOptions extends ReleaseSettings {
@@ -51,12 +36,10 @@ interface PublishOptions extends ReleaseSettings {
51
36
  wait?: Wait
52
37
  }
53
38
 
54
- interface Client {
39
+ interface Client extends Omit<RunSource, 'read'> {
55
40
  request: ReleaseRequest
56
41
  token: string
57
42
  url: string
58
- workflow: string | undefined
59
- jobs: ReadonlyArray<string>
60
43
  }
61
44
 
62
45
  // `fallback` answers when no tag sits between the floor and the target; without one the floor itself
@@ -139,59 +122,21 @@ function predecessor(
139
122
  .toSorted((left, right) => semver.compare(right, left))[0]
140
123
  }
141
124
 
142
- function is_failed_job(job: z.infer<typeof JOB_SCHEMA>, names: ReadonlyArray<string>): boolean {
143
- if (job.status !== 'completed' || !FAILED_CONCLUSIONS.has(job.conclusion ?? '')) return false
144
- if (names.length === 0) return true
145
-
146
- return names.some((name) => job.name === name || job.name.startsWith(`${name} /`))
147
- }
148
-
149
- async function publish_run(
150
- client: Client,
151
- workflow_name: string,
152
- tag: string,
153
- ): Promise<z.infer<typeof RUN_SCHEMA> | undefined> {
154
- const workflow = encodeURIComponent(workflow_name)
155
- const runs_response = await api_get(client, `/actions/workflows/${workflow}/runs?per_page=100`)
156
- const runs = RUNS_SCHEMA.parse(await read_response(runs_response)).workflow_runs
157
-
158
- return runs.find((item) => item.display_title === `Publish ${tag}`)
159
- }
160
-
161
- async function failed_publication(client: Client, tag: string): Promise<boolean> {
162
- if (client.workflow === undefined) return false
163
-
164
- const run = await publish_run(client, client.workflow, tag)
165
- if (!run) return false
166
-
167
- const jobs_response = await api_get(client, `/actions/runs/${String(run.id)}/jobs?per_page=100`)
168
- const { jobs } = JOBS_SCHEMA.parse(await read_response(jobs_response))
169
-
170
- return jobs.some((job) => is_failed_job(job, client.jobs))
125
+ function run_source(client: Client): RunSource {
126
+ return { ...client, read: async (path) => await read_response(await api_get(client, path)) }
171
127
  }
172
128
 
173
129
  async function default_wait(): Promise<void> {
174
130
  await setTimeout(POLL_INTERVAL_MS)
175
131
  }
176
132
 
133
+ // The lost state is read before the release: a run completes only after creating the release, so a
134
+ // run that completes between the two reads still shows its release to the second one.
177
135
  async function release_state(client: Client, tag: string): Promise<PollState> {
136
+ const is_lost = await github_release_runs.is_release_lost(run_source(client), tag)
178
137
  if (await existing_release(client, tag)) return 'ready'
179
- if (await failed_publication(client, tag)) return 'failed'
180
-
181
- return 'pending'
182
- }
183
-
184
- // A run not listed yet is pending too: the announcement that starts this release also starts the
185
- // publication, so the release can ask before GitHub has queued that run.
186
- async function publication_state(
187
- client: Client,
188
- workflow: string,
189
- tag: string,
190
- ): Promise<PollState> {
191
- const run = await publish_run(client, workflow, tag)
192
- if (run?.status !== 'completed') return 'pending'
193
138
 
194
- return run.conclusion === 'success' ? 'ready' : 'failed'
139
+ return is_lost ? 'failed' : 'pending'
195
140
  }
196
141
 
197
142
  async function poll(
@@ -225,7 +170,7 @@ async function wait_for_publication(client: Client, tag: string, budget: Budget)
225
170
  if (workflow === undefined) throw new Error('Waiting for the publication needs RELEASE_WORKFLOW')
226
171
 
227
172
  return await poll(
228
- async () => await publication_state(client, workflow, tag),
173
+ async () => await github_release_runs.publication_state(run_source(client), workflow, tag),
229
174
  budget,
230
175
  `Publish ${tag}`,
231
176
  )
@@ -325,6 +270,7 @@ function create_client(request: ReleaseRequest, token: string, settings: Release
325
270
  url: `${API_ROOT}/${settings.repository}`,
326
271
  workflow: settings.workflow,
327
272
  jobs: settings.jobs ?? [],
273
+ release_run_workflow: settings.release_run_workflow,
328
274
  }
329
275
  }
330
276
 
@@ -52,9 +52,9 @@ function label_names(labels: ReadonlyArray<LabelDefinition>): ReadonlyArray<stri
52
52
 
53
53
  // An unreadable listing is not an empty one: nothing is created, and every label is reported as
54
54
  // unconfirmed rather than as missing. An unresolved repository (no GitHub remote) is the same case.
55
- function unreadable(repo: string | undefined): ReadonlyArray<string> {
55
+ function unreadable(repo: string | undefined = 'this repository'): ReadonlyArray<string> {
56
56
  const names = label_names(REPOSITORY_LABELS)
57
- const target = repo ?? 'this repository'
57
+ const target = repo
58
58
 
59
59
  console.warn(
60
60
  ` ⚠ could not read the labels of ${target}; make sure these exist: ${names.join(', ')}`,
@@ -72,9 +72,7 @@ function workflow_job_names(content: string): Array<string> {
72
72
  const parsed = workflow_schema.safeParse(parse_yaml_safe(content))
73
73
  if (!parsed.success) return []
74
74
 
75
- return Object.values(parsed.data.jobs).flatMap((job) =>
76
- job.name === undefined ? [] : [job.name],
77
- )
75
+ return Object.values(parsed.data.jobs).flatMap((job) => job.name ?? [])
78
76
  }
79
77
 
80
78
  // The checks this repository should require: only those a workflow it has actually reports. A file
@@ -16,12 +16,10 @@ import { test_declared_logic, type Verdict } from '#scripts/test/test-declared-l
16
16
 
17
17
  const EVIDENCE_HEADING = '## 実機証跡'
18
18
 
19
- function verdict_for(paths: ReadonlyArray<string>, body: string | undefined): Verdict {
19
+ function verdict_for(paths: ReadonlyArray<string>, body: string | undefined = ''): Verdict {
20
20
  if (test_declared_logic.runtime_files(paths).length === 0) return 'exempt'
21
21
 
22
- return reproduction_measure.has_command_output(body ?? '', EVIDENCE_HEADING)
23
- ? 'satisfied'
24
- : 'required'
22
+ return reproduction_measure.has_command_output(body, EVIDENCE_HEADING) ? 'satisfied' : 'required'
25
23
  }
26
24
 
27
25
  // The diff is this checkout's, so it answers for the named branch only when that is the one checked
@@ -13,7 +13,7 @@ import { find_package_directory } from '#scripts/josh/josh-logic'
13
13
  import { path_decision } from '#scripts/josh/path-decision'
14
14
  import { stamp_file } from '#scripts/josh/stamp-file'
15
15
  import { openai_review_broker } from '#scripts/lane/openai-review-broker'
16
- import { run_ship_review } from '#scripts/run/run-ship-review'
16
+ import { run_ship_review } from '#scripts/run/ship/run-ship-review'
17
17
  import { review_attest } from './review-attest'
18
18
  import { review_brief } from './review-brief'
19
19
  import { review_checkout, type ReviewCheckout } from './review-checkout'
@@ -1,7 +1,7 @@
1
1
  // The review-finding line's grammar, its category vocabulary and the aggregation over it — the single
2
2
  // place all three are defined (joshuafolkken/kit#2325). A `/code-review` round's findings evaporated
3
3
  // the moment they were fixed, so no one could say which category recurred. They now land in the same
4
- // append-only ledger the observation lines use (`docs/maintainers/observations/`), under a distinct `- rf:`
4
+ // append-only ledger the observation lines use (`.josh/observations/`), under a distinct `- rf:`
5
5
  // prefix so `observation-ledger-line.ts`'s `- k:` grammar never treats them as its own — one ledger,
6
6
  // one commit path, a second line *type* rather than a second ledger.
7
7
 
@@ -19,9 +19,7 @@ function zero_line(zero_rounds: number): string {
19
19
  }
20
20
 
21
21
  function format_report(counts: ReadonlyArray<CategoryCount>, zero_rounds: number): string {
22
- if (counts.length === 0) {
23
- return zero_rounds === 0 ? NO_FINDINGS : zero_line(zero_rounds)
24
- }
22
+ if (counts.length === 0) return zero_rounds === 0 ? NO_FINDINGS : zero_line(zero_rounds)
25
23
 
26
24
  const body = counts.map((entry) => count_line(entry)).join('\n')
27
25
 
@@ -0,0 +1,128 @@
1
+ import type { DecisionOracle } from './decision-oracle'
2
+ import { oracle_tokens } from './decision-oracle-tokens'
3
+
4
+ // The batch oracles — the lane cut, the backlog budget and offer, the epic and post-merge steps, and
5
+ // `run:step` — kept beside the enumeration rather than inside it because `decision-oracle.ts` reached
6
+ // its file-size limit (joshuafolkken/kit#3264). They are one contiguous run of `DECISION_ORACLES`, so
7
+ // spreading them back in at the same position keeps the printed listing's order unchanged.
8
+
9
+ const {
10
+ BUSY,
11
+ EXCLUDE_ARG,
12
+ HUMAN_REVIEW,
13
+ ISSUE_N_ARG,
14
+ NONE,
15
+ NOT_A_LANE,
16
+ OVER,
17
+ RETRY,
18
+ STOP,
19
+ UNKNOWN,
20
+ WAIT,
21
+ } = oracle_tokens
22
+
23
+ const PRE_GATE_CUT_MD = '.claude/skills/workflow-commands/pre-gate-cut.md'
24
+ const BACKLOGRUN_MD = '.claude/skills/workflow-commands/backlogrun.md'
25
+
26
+ // The command reference in `docs/josh-commands.md` — one section per command, headed by the command
27
+ // itself. joshuafolkken/kit#2190 cut `backlogrun.md` back to a manifest of pointers, so a decision it
28
+ // used to carry inline (`run:merge`, `epic:next`, `backlog:budget`, `run:liveness`, `auto-ok:next`)
29
+ // now has its verdict contract only in this reference. That makes it the single source and the section
30
+ // a reader is routed to, in the same `file.md → \`josh <command>\`` form the `epic:reconcile` and
31
+ // `lane:list` entries already use. joshuafolkken/kit#2254.
32
+ const RUN_MERGE_REFERENCE = 'docs/josh-commands-run.md → `josh run:merge`'
33
+ const EPIC_NEXT_REFERENCE = 'docs/josh-commands-backlog.md → `josh epic:next`'
34
+ const BACKLOG_BUDGET_REFERENCE = 'docs/josh-commands-backlog.md → `josh backlog:budget`'
35
+ const RUN_LIVENESS_REFERENCE = 'docs/josh-commands-run.md → `josh run:liveness`'
36
+ const AUTO_OK_NEXT_REFERENCE = 'docs/josh-commands-backlog.md → `josh auto-ok:next`'
37
+
38
+ // Command used by two separate oracle entries (run:cut:resume and run:cut:gate).
39
+ const RUN_CUT_CMD = 'run:cut'
40
+
41
+ const BATCH_ORACLES: ReadonlyArray<DecisionOracle> = [
42
+ {
43
+ name: 'run:cut:resume',
44
+ command: RUN_CUT_CMD,
45
+ decision: 'Whether a lane child is resuming prior work or starting fresh',
46
+ args: `--resume ${ISSUE_N_ARG}`,
47
+ vocabulary: ['fresh', 'resume', NOT_A_LANE],
48
+ single_source: PRE_GATE_CUT_MD,
49
+ },
50
+ {
51
+ name: 'run:cut:gate',
52
+ command: RUN_CUT_CMD,
53
+ decision: 'Whether a lane child should take its pre-gate cut now',
54
+ args: ISSUE_N_ARG,
55
+ vocabulary: ['cut', NOT_A_LANE],
56
+ single_source: PRE_GATE_CUT_MD,
57
+ },
58
+ {
59
+ name: 'backlog:budget',
60
+ decision: 'Whether a backlogrun may start more work, keep watching, or finish',
61
+ args: '',
62
+ vocabulary: ['run', 'watch', STOP],
63
+ single_source: BACKLOG_BUDGET_REFERENCE,
64
+ },
65
+ {
66
+ name: 'run:liveness',
67
+ decision: 'Whether a delegated unit is still working or has stopped without reporting',
68
+ args: `${ISSUE_N_ARG} --output <path>`,
69
+ vocabulary: ['alive', 'stopped', 'settled', 'undetermined'],
70
+ single_source: RUN_LIVENESS_REFERENCE,
71
+ },
72
+ {
73
+ name: 'stash:pop',
74
+ decision: 'Whether a named stash entry exists and can be applied',
75
+ args: '<message>',
76
+ vocabulary: ['popped', 'conflicted', 'no-match', 'ambiguous'],
77
+ single_source: '.claude/skills/workflow-commands/prerequisite.md',
78
+ },
79
+ {
80
+ name: 'backlog:next',
81
+ decision: 'Which issue the backlog offers next, or whether to wait or stop',
82
+ args: EXCLUDE_ARG,
83
+ vocabulary: [WAIT, STOP, RETRY, 'error', NONE],
84
+ single_source: BACKLOGRUN_MD,
85
+ },
86
+ {
87
+ name: 'auto-ok:next',
88
+ decision: 'The next opted-in issue outside any epic, or none',
89
+ args: EXCLUDE_ARG,
90
+ vocabulary: [NONE],
91
+ single_source: AUTO_OK_NEXT_REFERENCE,
92
+ },
93
+ {
94
+ name: 'epic:next',
95
+ decision: "The next runnable child of an epic, or the epic's status",
96
+ args: '<epic>',
97
+ vocabulary: [WAIT, STOP, 'complete'],
98
+ single_source: EPIC_NEXT_REFERENCE,
99
+ },
100
+ {
101
+ name: 'run:merge',
102
+ decision: 'The post-merge batch step: confirm child, advance, or report a stop condition',
103
+ args: ISSUE_N_ARG,
104
+ vocabulary: [OVER, HUMAN_REVIEW, STOP, RETRY, BUSY],
105
+ single_source: RUN_MERGE_REFERENCE,
106
+ },
107
+ {
108
+ name: 'run:step',
109
+ decision: 'The run’s next single action, computed from the event stream, carry and issue state',
110
+ args: ISSUE_N_ARG,
111
+ // The non-command answers: `run:step` prints a runnable command for a phase with one to run, and
112
+ // one of these verdicts otherwise. A command line is not a vocabulary token, exactly as an issue
113
+ // number is not one for `backlog:next`.
114
+ vocabulary: [
115
+ 'implement',
116
+ HUMAN_REVIEW,
117
+ 'update-deps',
118
+ 'already-done',
119
+ 'keep-work',
120
+ WAIT,
121
+ STOP,
122
+ UNKNOWN,
123
+ ],
124
+ single_source: BACKLOGRUN_MD,
125
+ },
126
+ ]
127
+
128
+ export { BATCH_ORACLES }
@@ -0,0 +1,21 @@
1
+ // Vocabulary tokens and arguments that appear in more than one oracle entry, shared by
2
+ // `decision-oracle.ts` and `decision-oracle-batch.ts` so each string has one source
3
+ // (joshuafolkken/kit#3264).
4
+
5
+ const oracle_tokens = {
6
+ REQUIRED: 'required',
7
+ SKIP: 'skip',
8
+ STOP: 'stop',
9
+ WAIT: 'wait',
10
+ RETRY: 'retry',
11
+ OVER: 'over',
12
+ UNKNOWN: 'unknown',
13
+ NONE: 'none',
14
+ NOT_A_LANE: 'not-a-lane',
15
+ BUSY: 'busy',
16
+ HUMAN_REVIEW: 'human-review',
17
+ ISSUE_N_ARG: '<N>',
18
+ EXCLUDE_ARG: '[--exclude <n>...]',
19
+ } as const
20
+
21
+ export { oracle_tokens }
@@ -6,7 +6,11 @@
6
6
  // not by prose. Single source: `prompts/collaboration-workflow/residency.md` → question 0.
7
7
  //
8
8
  // Anything not on this list is answered by prose or by a hook-delivered rule, never by a command.
9
+ import { BATCH_ORACLES } from './decision-oracle-batch'
9
10
  import { RUN_ENTRY_ORACLE } from './decision-oracle-stage'
11
+ import { oracle_tokens } from './decision-oracle-tokens'
12
+
13
+ const { BUSY, ISSUE_N_ARG, NONE, OVER, REQUIRED, SKIP, UNKNOWN } = oracle_tokens
10
14
 
11
15
  // Paths that appear in more than one entry's `single_source` field.
12
16
  const CHAIN_RULE_MD = '.claude/skills/workflow-commands/chain-rule.md'
@@ -14,36 +18,7 @@ const BACKLOGRUN_PROGRESS_MD = '.claude/skills/workflow-commands/backlogrun-prog
14
18
  const SKILL_2E = '.claude/skills/workflow-commands/issue-scout.md'
15
19
  const SPLIT_ASSESSMENT_QUESTION =
16
20
  '.claude/skills/workflow-commands/split-assessment.md → The question'
17
- const PRE_GATE_CUT_MD = '.claude/skills/workflow-commands/pre-gate-cut.md'
18
- const BACKLOGRUN_MD = '.claude/skills/workflow-commands/backlogrun.md'
19
-
20
- // The command reference in `docs/josh-commands.md` — one section per command, headed by the command
21
- // itself. joshuafolkken/kit#2190 cut `backlogrun.md` back to a manifest of pointers, so a decision it
22
- // used to carry inline (`run:merge`, `epic:next`, `backlog:budget`, `run:liveness`, `auto-ok:next`)
23
- // now has its verdict contract only in this reference. That makes it the single source and the section
24
- // a reader is routed to, in the same `file.md → \`josh <command>\`` form the `epic:reconcile` and
25
- // `lane:list` entries already use. joshuafolkken/kit#2254.
26
- const RUN_MERGE_REFERENCE = 'docs/josh-commands-automation.md → `josh run:merge`'
27
- const EPIC_NEXT_REFERENCE = 'docs/josh-commands-automation.md → `josh epic:next`'
28
- const BACKLOG_BUDGET_REFERENCE = 'docs/josh-commands-automation.md → `josh backlog:budget`'
29
- const RUN_LIVENESS_REFERENCE = 'docs/josh-commands-automation.md → `josh run:liveness`'
30
- const AUTO_OK_NEXT_REFERENCE = 'docs/josh-commands-automation.md → `josh auto-ok:next`'
31
21
 
32
- // Command used by two separate oracle entries (run:cut:resume and run:cut:gate).
33
- const RUN_CUT_CMD = 'run:cut'
34
-
35
- // Vocabulary tokens that appear in more than one oracle's vocabulary array.
36
- const REQUIRED = 'required'
37
- const SKIP = 'skip'
38
- const STOP = 'stop'
39
- const WAIT = 'wait'
40
- const RETRY = 'retry'
41
- const OVER = 'over'
42
- const UNKNOWN = 'unknown'
43
- const NONE = 'none'
44
- const NOT_A_LANE = 'not-a-lane'
45
- const BUSY = 'busy'
46
- const HUMAN_REVIEW = 'human-review'
47
22
  // Lane liveness verdicts shared by the lane:list oracle and asserted against `lane_occupancy` in its
48
23
  // test. `LIVE` is the silent norm; `STOPPED` and `UNKNOWN` lead the difference lines.
49
24
  const LIVE = 'live'
@@ -53,10 +28,6 @@ const STOPPED = 'stopped'
53
28
  const RECONCILED = 'reconciled'
54
29
  const NOTHING_TO_RECONCILE = 'nothing to reconcile'
55
30
 
56
- // Arguments shared by more than one oracle entry.
57
- const ISSUE_N_ARG = '<N>'
58
- const EXCLUDE_ARG = '[--exclude <n>...]'
59
-
60
31
  interface DecisionOracle {
61
32
  // Short identifier used by the CLI and tests.
62
33
  name: string
@@ -193,90 +164,7 @@ const DECISION_ORACLES: ReadonlyArray<DecisionOracle> = [
193
164
  vocabulary: ['human_review: yes', 'human_review: no'],
194
165
  single_source: '.claude/skills/workflow-commands/needs-human-review.md',
195
166
  },
196
- {
197
- name: 'run:cut:resume',
198
- command: RUN_CUT_CMD,
199
- decision: 'Whether a lane child is resuming prior work or starting fresh',
200
- args: `--resume ${ISSUE_N_ARG}`,
201
- vocabulary: ['fresh', 'resume', NOT_A_LANE],
202
- single_source: PRE_GATE_CUT_MD,
203
- },
204
- {
205
- name: 'run:cut:gate',
206
- command: RUN_CUT_CMD,
207
- decision: 'Whether a lane child should take its pre-gate cut now',
208
- args: ISSUE_N_ARG,
209
- vocabulary: ['cut', NOT_A_LANE],
210
- single_source: PRE_GATE_CUT_MD,
211
- },
212
- {
213
- name: 'backlog:budget',
214
- decision: 'Whether a backlogrun may start more work, keep watching, or finish',
215
- args: '',
216
- vocabulary: ['run', 'watch', STOP],
217
- single_source: BACKLOG_BUDGET_REFERENCE,
218
- },
219
- {
220
- name: 'run:liveness',
221
- decision: 'Whether a delegated unit is still working or has stopped without reporting',
222
- args: `${ISSUE_N_ARG} --output <path>`,
223
- vocabulary: ['alive', 'stopped', 'settled', 'undetermined'],
224
- single_source: RUN_LIVENESS_REFERENCE,
225
- },
226
- {
227
- name: 'stash:pop',
228
- decision: 'Whether a named stash entry exists and can be applied',
229
- args: '<message>',
230
- vocabulary: ['popped', 'conflicted', 'no-match', 'ambiguous'],
231
- single_source: '.claude/skills/workflow-commands/prerequisite.md',
232
- },
233
- {
234
- name: 'backlog:next',
235
- decision: 'Which issue the backlog offers next, or whether to wait or stop',
236
- args: EXCLUDE_ARG,
237
- vocabulary: [WAIT, STOP, RETRY, 'error', NONE],
238
- single_source: BACKLOGRUN_MD,
239
- },
240
- {
241
- name: 'auto-ok:next',
242
- decision: 'The next opted-in issue outside any epic, or none',
243
- args: EXCLUDE_ARG,
244
- vocabulary: [NONE],
245
- single_source: AUTO_OK_NEXT_REFERENCE,
246
- },
247
- {
248
- name: 'epic:next',
249
- decision: "The next runnable child of an epic, or the epic's status",
250
- args: '<epic>',
251
- vocabulary: [WAIT, STOP, 'complete'],
252
- single_source: EPIC_NEXT_REFERENCE,
253
- },
254
- {
255
- name: 'run:merge',
256
- decision: 'The post-merge batch step: confirm child, advance, or report a stop condition',
257
- args: ISSUE_N_ARG,
258
- vocabulary: [OVER, HUMAN_REVIEW, STOP, RETRY, BUSY],
259
- single_source: RUN_MERGE_REFERENCE,
260
- },
261
- {
262
- name: 'run:step',
263
- decision: 'The run’s next single action, computed from the event stream, carry and issue state',
264
- args: ISSUE_N_ARG,
265
- // The non-command answers: `run:step` prints a runnable command for a phase with one to run, and
266
- // one of these verdicts otherwise. A command line is not a vocabulary token, exactly as an issue
267
- // number is not one for `backlog:next`.
268
- vocabulary: [
269
- 'implement',
270
- HUMAN_REVIEW,
271
- 'update-deps',
272
- 'already-done',
273
- 'keep-work',
274
- WAIT,
275
- STOP,
276
- UNKNOWN,
277
- ],
278
- single_source: BACKLOGRUN_MD,
279
- },
167
+ ...BATCH_ORACLES,
280
168
  {
281
169
  name: 'refactor:scan',
282
170
  decision: 'Whether the refactoring scope still holds high- or medium-priority candidates',
@@ -303,7 +191,7 @@ const DECISION_ORACLES: ReadonlyArray<DecisionOracle> = [
303
191
  decision: 'Whether cross-file or cross-repository code duplication exists',
304
192
  args: '',
305
193
  vocabulary: ['clean', 'clones:'],
306
- single_source: 'prompts/collaboration-workflow/principles.md → クローン禁止',
194
+ single_source: 'prompts/collaboration-workflow/principles.md → no-clones',
307
195
  },
308
196
  {
309
197
  name: 'epic:reconcile',
@@ -312,7 +200,7 @@ const DECISION_ORACLES: ReadonlyArray<DecisionOracle> = [
312
200
  "Whether an epic's declaration matches its recorded relations, and the repair when it does not",
313
201
  args: '--reconcile <E>',
314
202
  vocabulary: [RECONCILED, NOTHING_TO_RECONCILE],
315
- single_source: 'docs/josh-commands-automation.md → `josh epic --reconcile`',
203
+ single_source: 'docs/josh-commands-backlog.md → `josh epic --reconcile`',
316
204
  },
317
205
  {
318
206
  name: 'lane:list',
@@ -320,7 +208,7 @@ const DECISION_ORACLES: ReadonlyArray<DecisionOracle> = [
320
208
  'Whether each in-progress issue holds a live lane, and the two-directional difference',
321
209
  args: '',
322
210
  vocabulary: [LIVE, STOPPED, UNKNOWN],
323
- single_source: 'docs/josh-commands-automation.md → The `in-progress` / lane difference',
211
+ single_source: 'docs/josh-commands-run.md → The `in-progress` / lane difference',
324
212
  },
325
213
  RUN_ENTRY_ORACLE,
326
214
  ]