@joshuafolkken/kit 1.1455.0 → 1.1514.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 (374) hide show
  1. package/.claude/settings.json +6 -6
  2. package/.claude/skills/dependency-update/SKILL.md +26 -55
  3. package/.claude/skills/epic-commands/SKILL.md +83 -156
  4. package/.claude/skills/epic-commands/epic-bundle.md +51 -79
  5. package/.claude/skills/epic-commands/execution-waves.md +43 -81
  6. package/.claude/skills/verify-ui/SKILL.md +24 -50
  7. package/.claude/skills/workflow-commands/SKILL.md +7 -9
  8. package/.claude/skills/workflow-commands/background-commands.md +31 -46
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +65 -85
  10. package/.claude/skills/workflow-commands/backlogrun-lanes.md +86 -125
  11. package/.claude/skills/workflow-commands/backlogrun-park.md +68 -118
  12. package/.claude/skills/workflow-commands/backlogrun-progress.md +17 -28
  13. package/.claude/skills/workflow-commands/backlogrun-recovery.md +17 -26
  14. package/.claude/skills/workflow-commands/backlogrun-steps.md +35 -52
  15. package/.claude/skills/workflow-commands/backlogrun.md +31 -50
  16. package/.claude/skills/workflow-commands/chain-rule.md +31 -40
  17. package/.claude/skills/workflow-commands/delegation.md +12 -8
  18. package/.claude/skills/workflow-commands/entry-sequence.md +1 -3
  19. package/.claude/skills/workflow-commands/followup.md +55 -77
  20. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -5
  21. package/.claude/skills/workflow-commands/fullrun.md +4 -6
  22. package/.claude/skills/workflow-commands/halfrun.md +3 -7
  23. package/.claude/skills/workflow-commands/into-target.md +1 -2
  24. package/.claude/skills/workflow-commands/issue-comments.md +43 -60
  25. package/.claude/skills/workflow-commands/issue-scout.md +3 -2
  26. package/.claude/skills/workflow-commands/kickoff.md +65 -74
  27. package/.claude/skills/workflow-commands/latest-gate.md +2 -6
  28. package/.claude/skills/workflow-commands/needs-human-review.md +2 -5
  29. package/.claude/skills/workflow-commands/observation-filing.md +59 -118
  30. package/.claude/skills/workflow-commands/observation-ledger.md +52 -112
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +88 -142
  32. package/.claude/skills/workflow-commands/prerequisite.md +11 -17
  33. package/.claude/skills/workflow-commands/progress-watcher.md +23 -33
  34. package/.claude/skills/workflow-commands/prrun.md +3 -5
  35. package/.claude/skills/workflow-commands/retrospective.md +35 -54
  36. package/.claude/skills/workflow-commands/split-assessment.md +32 -58
  37. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +54 -73
  39. package/.codex/hooks.json +6 -6
  40. package/.github/actions/setup-node/action.yml +1 -1
  41. package/.github/workflows/ci.yml +1 -1
  42. package/.github/workflows/publish.yml +2 -2
  43. package/CLAUDE.md +7 -6
  44. package/cspell/index.yaml +7 -0
  45. package/dist/CLAUDE.md +7 -6
  46. package/dist/commands/document-section-cli.js +67 -34
  47. package/dist/hooks/batch-guard.js +6 -6
  48. package/dist/hooks/chunk-4KKD2UTK.js +66 -0
  49. package/dist/hooks/{chunk-GPLGZ6IC.js → chunk-6TS2JD6D.js} +14 -3
  50. package/dist/hooks/chunk-7DSBJVFH.js +50 -0
  51. package/dist/hooks/{chunk-5H4SSDSD.js → chunk-A65Y4YOR.js} +3 -3
  52. package/dist/hooks/{chunk-3C4XRYG6.js → chunk-APUO6U4J.js} +102 -19
  53. package/dist/hooks/{chunk-IX6TTTI6.js → chunk-EFXE6C37.js} +8 -22
  54. package/dist/hooks/chunk-GP4IEC4O.js +20 -0
  55. package/dist/hooks/chunk-JP45SOCJ.js +56 -0
  56. package/dist/hooks/{chunk-OLMO72ON.js → chunk-LAOV7NLM.js} +1 -1
  57. package/dist/hooks/chunk-M4HGZV7U.js +83 -0
  58. package/dist/hooks/{chunk-TBJFTSUY.js → chunk-O6GDRNJB.js} +9 -7
  59. package/dist/hooks/{chunk-HFGWYGUV.js → chunk-PF2NZL2A.js} +5 -5
  60. package/dist/hooks/{chunk-WNLVGT7E.js → chunk-PTICX4OL.js} +4 -5
  61. package/dist/hooks/{chunk-HHI6FO3R.js → chunk-RT27QRJW.js} +763 -1515
  62. package/dist/hooks/{chunk-7WQBPLUN.js → chunk-SYOTDYCI.js} +1149 -1095
  63. package/dist/hooks/{chunk-LIAFCXL7.js → chunk-TNUMY6NL.js} +1519 -1332
  64. package/dist/hooks/chunk-UPUZF3AN.js +279 -0
  65. package/dist/hooks/{chunk-Z4XI7CZS.js → chunk-WK6SMBIC.js} +1932 -784
  66. package/dist/hooks/codex-hook-adapter.js +17 -14
  67. package/dist/hooks/duplicate-read-guard.js +7 -7
  68. package/dist/hooks/format-edited.js +5 -4
  69. package/dist/hooks/inputs.json +302 -247
  70. package/dist/hooks/investigation-guard.js +8 -11
  71. package/dist/hooks/pretool-guard.js +16 -13
  72. package/dist/hooks/session-lang.js +372 -26
  73. package/dist/hooks/stop-guard.js +2593 -189
  74. package/dist/josh.js +2128 -282
  75. package/dist/managed-marker/index.js +1 -2
  76. package/dist/version/index.js +15 -12
  77. package/eslint/base.js +2 -1
  78. package/eslint/rules/unicorn.js +16 -0
  79. package/lefthook/base.yml +5 -3
  80. package/package.json +14 -12
  81. package/prompts/coding-standards.md +12 -22
  82. package/prompts/collaboration-workflow/file-edits.md +25 -45
  83. package/prompts/collaboration-workflow/gh-rest.md +19 -36
  84. package/prompts/collaboration-workflow/glossary.md +5 -7
  85. package/prompts/collaboration-workflow/issue-citation.md +6 -14
  86. package/prompts/collaboration-workflow/issue-template.md +40 -32
  87. package/prompts/collaboration-workflow/lane-instructions.md +35 -0
  88. package/prompts/collaboration-workflow/operating-rules.md +33 -46
  89. package/prompts/collaboration-workflow/output-bounds.md +15 -15
  90. package/prompts/collaboration-workflow/overview.md +14 -19
  91. package/prompts/collaboration-workflow/plan-comment.md +13 -13
  92. package/prompts/collaboration-workflow/principles.md +57 -54
  93. package/prompts/collaboration-workflow/proposal-request.md +1 -9
  94. package/prompts/collaboration-workflow/report-format.md +41 -49
  95. package/prompts/collaboration-workflow/residency.md +15 -11
  96. package/prompts/collaboration-workflow/rule-delivery.md +7 -15
  97. package/prompts/collaboration-workflow/shell-body.md +10 -20
  98. package/prompts/collaboration-workflow/turn-batching.md +8 -14
  99. package/prompts/collaboration-workflow/upstream-interrupt.md +26 -34
  100. package/prompts/collaboration-workflow/wip-cap.md +26 -32
  101. package/prompts/collaboration-workflow.md +25 -25
  102. package/prompts/refactoring.md +33 -43
  103. package/prompts/review-rubric.md +84 -129
  104. package/prompts/review.md +110 -141
  105. package/prompts/sonar-hotspot-handling.md +22 -50
  106. package/prompts/testing-guide.md +48 -99
  107. package/scripts/adopt/adopt-toolkits.ts +2 -4
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-exit-record.ts +23 -1
  110. package/scripts/agent/agent-role-profile.ts +101 -45
  111. package/scripts/agent/agent-safe-text.ts +60 -0
  112. package/scripts/agent/claude-agent-argv.ts +14 -0
  113. package/scripts/agent/codex-agent-argv.ts +9 -2
  114. package/scripts/agent/lane-instructions.ts +144 -0
  115. package/scripts/backlog/backlog-budget-cli.ts +1 -2
  116. package/scripts/backlog/backlog-budget.ts +4 -4
  117. package/scripts/backlog/backlog-drive-carried.ts +26 -0
  118. package/scripts/backlog/backlog-drive-cli.ts +10 -5
  119. package/scripts/backlog/backlog-drive-named.ts +3 -5
  120. package/scripts/backlog/backlog-drive-restore.ts +28 -2
  121. package/scripts/backlog/backlog-drive-seats.ts +27 -0
  122. package/scripts/backlog/backlog-drive.ts +11 -6
  123. package/scripts/backlog/backlog-occupied.ts +56 -0
  124. package/scripts/backlog/backlog-ready.ts +59 -15
  125. package/scripts/behavior/behavior-rules.ts +3 -2
  126. package/scripts/cost-runtime/codex-usage.ts +4 -2
  127. package/scripts/cost-runtime/cost-cli.ts +1 -2
  128. package/scripts/delegation/duplicate-read-guard.ts +2 -2
  129. package/scripts/delegation/investigation-guard.ts +15 -65
  130. package/scripts/delegation/investigation-reads.ts +1 -2
  131. package/scripts/discovery/repo-discovery.ts +4 -2
  132. package/scripts/discovery/repo-origin.ts +2 -4
  133. package/scripts/doctor/doctor-logic.ts +6 -3
  134. package/scripts/document/document-byte-budget.ts +28 -27
  135. package/scripts/document/document-byte-check.ts +1 -2
  136. package/scripts/document/document-section-cli.ts +17 -5
  137. package/scripts/document/entry-read-budget.ts +3 -3
  138. package/scripts/document/read-set-cli.ts +4 -1
  139. package/scripts/epic/epic-audit-orphans.ts +5 -8
  140. package/scripts/epic/epic-audit-rationale.ts +8 -2
  141. package/scripts/epic/epic-audit.ts +52 -1
  142. package/scripts/epic/epic-bundle-cli.ts +1 -2
  143. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  144. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  145. package/scripts/epic/epic-bundle.ts +17 -9
  146. package/scripts/epic/epic-chains.ts +6 -2
  147. package/scripts/epic/epic-close-comment.ts +1 -2
  148. package/scripts/followup/git-followup-workflow.ts +19 -1
  149. package/scripts/gate/check-inputs.ts +129 -0
  150. package/scripts/gate/check-reuse.ts +162 -0
  151. package/scripts/gate/core-budget.ts +93 -44
  152. package/scripts/gate/core-wait.ts +130 -0
  153. package/scripts/gate/free-cores.ts +49 -0
  154. package/scripts/gate/gate-ledger.ts +17 -3
  155. package/scripts/gate/gate-plan.ts +23 -1
  156. package/scripts/gate/gate-report.ts +15 -2
  157. package/scripts/gate/gate-run-steps.ts +150 -0
  158. package/scripts/gate/held-mark.ts +55 -0
  159. package/scripts/gate/machine-capacity.ts +70 -11
  160. package/scripts/gate/pre-commit-type-check.ts +14 -1
  161. package/scripts/gate/verification-gate.ts +65 -127
  162. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  163. package/scripts/gh/git-gh-issue-write.ts +24 -2
  164. package/scripts/gh/git-pr.ts +19 -3
  165. package/scripts/git/git-common-directory.ts +3 -3
  166. package/scripts/git/git-diff-reads.ts +16 -9
  167. package/scripts/git/git-execa-error.ts +1 -2
  168. package/scripts/git/main-merge-regenerate.ts +78 -0
  169. package/scripts/git/main-merge.ts +14 -5
  170. package/scripts/hooks/batch-guard.ts +5 -8
  171. package/scripts/hooks/format-edited-file.ts +10 -4
  172. package/scripts/hooks/pre-commit-lint.ts +91 -0
  173. package/scripts/hooks/pre-push-unit.ts +15 -4
  174. package/scripts/hooks/pretool-guard.ts +48 -79
  175. package/scripts/hooks/reserved-run.ts +1 -0
  176. package/scripts/hooks/run-hook.sh +10 -12
  177. package/scripts/hooks/step-zero-notice.ts +3 -2
  178. package/scripts/hooks/stop-actions.ts +204 -0
  179. package/scripts/hooks/stop-guard.ts +62 -21
  180. package/scripts/init/hook-command-rewrite.ts +6 -2
  181. package/scripts/init/hook-launch.ts +12 -7
  182. package/scripts/init/init-logic-deploy-vps.ts +4 -2
  183. package/scripts/issue/behavior-change-lint.ts +12 -6
  184. package/scripts/issue/expected-effect-lint.ts +59 -0
  185. package/scripts/issue/issue-cite-cli.ts +35 -15
  186. package/scripts/issue/issue-classification.ts +1 -1
  187. package/scripts/issue/issue-lint-cli.ts +5 -3
  188. package/scripts/issue/issue-scout-cli.ts +22 -16
  189. package/scripts/issue/markdown-section.ts +19 -5
  190. package/scripts/josh/command-usage.ts +110 -0
  191. package/scripts/josh/file-map-stamp.ts +1 -3
  192. package/scripts/josh/hook-decision.ts +17 -2
  193. package/scripts/josh/josh-command-map.ts +2 -0
  194. package/scripts/josh/josh-command-types.ts +55 -9
  195. package/scripts/josh/josh-commands-ai.ts +13 -0
  196. package/scripts/josh/josh-commands-development.ts +1 -1
  197. package/scripts/josh/josh-commands-hooks.ts +6 -0
  198. package/scripts/josh/josh-commands-lane.ts +10 -1
  199. package/scripts/josh/josh-commands-workflow.ts +5 -0
  200. package/scripts/josh/josh-logic.ts +6 -15
  201. package/scripts/josh/josh-usage-automation.ts +121 -0
  202. package/scripts/josh/josh-usage-backlog.ts +180 -0
  203. package/scripts/josh/josh-usage-developer.ts +230 -0
  204. package/scripts/josh/josh-usage-hooks.ts +38 -0
  205. package/scripts/josh/josh-usage-issue.ts +205 -0
  206. package/scripts/josh/josh-usage-review.ts +101 -0
  207. package/scripts/josh/josh-usage-run.ts +252 -0
  208. package/scripts/josh/josh-usage-session.ts +238 -0
  209. package/scripts/josh/josh-usage-workflow.ts +212 -0
  210. package/scripts/josh/josh.ts +14 -5
  211. package/scripts/josh/package-directory.ts +20 -0
  212. package/scripts/lane/lane-await.ts +3 -2
  213. package/scripts/lane/lane-capacity.ts +8 -2
  214. package/scripts/lane/lane-check-stats.ts +56 -0
  215. package/scripts/lane/lane-child-invocation.ts +49 -5
  216. package/scripts/lane/lane-dispatch.ts +3 -3
  217. package/scripts/lane/lane-guard-policy.ts +5 -5
  218. package/scripts/lane/lane-handoff.ts +8 -1
  219. package/scripts/lane/lane-install.ts +12 -4
  220. package/scripts/lane/lane-ledger.ts +52 -1
  221. package/scripts/lane/lane-limit-cli.ts +8 -9
  222. package/scripts/lane/lane-load.ts +9 -2
  223. package/scripts/lane/lane-measure-cli.ts +4 -0
  224. package/scripts/lane/lane-parked.ts +18 -0
  225. package/scripts/lane/lane-preserve.ts +29 -1
  226. package/scripts/lane/lane-process-load.ts +125 -0
  227. package/scripts/lane/lane-process-stats.ts +93 -0
  228. package/scripts/lane/lane-registry.ts +17 -10
  229. package/scripts/lane/lane-restart.ts +5 -26
  230. package/scripts/lane/lane-session-action.ts +146 -0
  231. package/scripts/lane/lane-session-broker.ts +68 -125
  232. package/scripts/lane/lane-spent.ts +14 -3
  233. package/scripts/lane/lane-stats.ts +1 -0
  234. package/scripts/lane/lane-withdraw-cli.ts +71 -0
  235. package/scripts/lane/lane-withdraw.ts +182 -0
  236. package/scripts/lint/format.ts +4 -4
  237. package/scripts/lint/lint-parallel.ts +10 -3
  238. package/scripts/lint/lint-related-scope.ts +4 -1
  239. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  240. package/scripts/notify/telegram-test.ts +10 -5
  241. package/scripts/overrides/lockfile-overrides.ts +1 -3
  242. package/scripts/propagate/propagate.ts +1 -2
  243. package/scripts/release/release-progress.ts +3 -2
  244. package/scripts/report/report-format-reference.ts +2 -0
  245. package/scripts/report/report-lint.ts +7 -4
  246. package/scripts/review/acceptance-map-check.ts +61 -0
  247. package/scripts/review/acceptance-map.ts +205 -0
  248. package/scripts/review/review-brief-cli.ts +1 -1
  249. package/scripts/review/review-record-cli.ts +6 -2
  250. package/scripts/rules/agent-model.ts +59 -0
  251. package/scripts/rules/delivered-rules.ts +11 -2
  252. package/scripts/rules/destructive-command.ts +6 -9
  253. package/scripts/rules/direct-filing.ts +3 -7
  254. package/scripts/rules/early-heartbeat.ts +7 -18
  255. package/scripts/rules/file-body.ts +6 -13
  256. package/scripts/rules/filing-cap.ts +4 -6
  257. package/scripts/rules/firing-point.ts +6 -5
  258. package/scripts/rules/git-force.ts +5 -9
  259. package/scripts/rules/guard-remedy.ts +117 -0
  260. package/scripts/rules/implementation-cut.ts +37 -35
  261. package/scripts/rules/index-guard.ts +4 -7
  262. package/scripts/rules/issue-comments.ts +67 -16
  263. package/scripts/rules/josh-git-bare.ts +3 -6
  264. package/scripts/rules/lane-background.ts +10 -21
  265. package/scripts/rules/lane-carry-conflict.ts +7 -17
  266. package/scripts/rules/lane-interactive-ask.ts +6 -11
  267. package/scripts/rules/lane-park.ts +5 -13
  268. package/scripts/rules/lane-split-park.ts +2 -7
  269. package/scripts/rules/lane-switch-main.ts +9 -12
  270. package/scripts/rules/last-prompt.ts +50 -5
  271. package/scripts/rules/oracle-consulted.ts +4 -5
  272. package/scripts/rules/oracle-list-cli.ts +7 -0
  273. package/scripts/rules/piped-verification.ts +84 -32
  274. package/scripts/rules/poll-loop.ts +7 -17
  275. package/scripts/rules/pre-gate-cut.ts +7 -21
  276. package/scripts/rules/prior-comment-read.ts +7 -5
  277. package/scripts/rules/protected-files.ts +5 -9
  278. package/scripts/rules/raw-field-body.ts +3 -7
  279. package/scripts/rules/rule-body-guard.ts +4 -11
  280. package/scripts/rules/rule-list.ts +4 -1
  281. package/scripts/rules/rule-registry-rows.ts +10 -0
  282. package/scripts/rules/rule-registry.ts +7 -4
  283. package/scripts/rules/rule-rewrite.ts +114 -0
  284. package/scripts/rules/rule-value.ts +7 -1
  285. package/scripts/rules/run-tail-rule.ts +6 -22
  286. package/scripts/rules/shell-body-trigger.ts +4 -6
  287. package/scripts/rules/shell-segments.ts +22 -0
  288. package/scripts/rules/stop-decision.ts +77 -0
  289. package/scripts/rules/stop-rules.ts +164 -77
  290. package/scripts/rules/tail-commands.ts +15 -1
  291. package/scripts/rules/test-declared-commit.ts +4 -10
  292. package/scripts/rules/third-party-write.ts +5 -10
  293. package/scripts/rules/worktree-guard.ts +5 -12
  294. package/scripts/run/board/run-board-cli.ts +2 -0
  295. package/scripts/run/board/run-board-closed.ts +8 -2
  296. package/scripts/run/board/run-board-github.ts +19 -3
  297. package/scripts/run/board/run-board-header.ts +4 -1
  298. package/scripts/run/board/run-board-idle.ts +31 -0
  299. package/scripts/run/board/run-board-labels.ts +2 -0
  300. package/scripts/run/board/run-board-layout.ts +1 -1
  301. package/scripts/run/board/run-board-read.ts +25 -12
  302. package/scripts/run/board/run-board-reason.ts +17 -4
  303. package/scripts/run/board/run-board-render-legend.ts +1 -0
  304. package/scripts/run/board/run-board-render-slot.ts +1 -1
  305. package/scripts/run/board/run-board-render-waits.ts +41 -0
  306. package/scripts/run/board/run-board-render.ts +6 -1
  307. package/scripts/run/board/run-board-row-yield.ts +1 -0
  308. package/scripts/run/board/run-board-state.ts +9 -0
  309. package/scripts/run/board/run-board-status.ts +89 -23
  310. package/scripts/run/board/run-board-thanks.ts +7 -2
  311. package/scripts/run/board/run-board-tick.ts +37 -8
  312. package/scripts/run/carry/run-carry-args.ts +1 -3
  313. package/scripts/run/carry/run-carry-conversation.ts +7 -2
  314. package/scripts/run/cut/run-cut-cli.ts +18 -22
  315. package/scripts/run/cut/run-cut-decline.ts +72 -0
  316. package/scripts/run/cut/run-cut-ready.ts +74 -0
  317. package/scripts/run/cut/run-cut-report.ts +29 -0
  318. package/scripts/run/cut/run-cut.ts +10 -1
  319. package/scripts/run/detached-launch.ts +23 -4
  320. package/scripts/run/entry/run-entry-cli.ts +8 -1
  321. package/scripts/run/event/run-event-render.ts +1 -0
  322. package/scripts/run/event/run-event-scope.ts +19 -1
  323. package/scripts/run/event/run-event-stream-emit.ts +13 -6
  324. package/scripts/run/event/run-event-stream.ts +4 -0
  325. package/scripts/run/hold/run-hold-cli.ts +14 -3
  326. package/scripts/run/hold/run-hold-session.ts +46 -0
  327. package/scripts/run/hold/run-hold.ts +13 -4
  328. package/scripts/run/launch-priority.ts +32 -0
  329. package/scripts/run/merge/run-merge-cli.ts +16 -42
  330. package/scripts/run/merge/run-merge-ship.ts +59 -1
  331. package/scripts/run/merge/run-merge-signals.ts +99 -0
  332. package/scripts/run/merge/run-merge-steps.ts +11 -1
  333. package/scripts/run/merge/run-merge.ts +22 -9
  334. package/scripts/run/run-ending.ts +31 -3
  335. package/scripts/run/run-liveness.ts +1 -1
  336. package/scripts/run/run-parent-cut-hook.ts +5 -10
  337. package/scripts/run/run-poll-hook.ts +157 -0
  338. package/scripts/run/run-preflight.ts +1 -2
  339. package/scripts/run/run-step-cli.ts +22 -15
  340. package/scripts/run/run-step-section.ts +85 -0
  341. package/scripts/run/run-stop-notify.ts +1 -2
  342. package/scripts/run/run-watcher-guard.ts +6 -3
  343. package/scripts/run/ship/run-ship-cli.ts +5 -12
  344. package/scripts/run/ship/run-ship-detach.ts +9 -0
  345. package/scripts/run/ship/run-ship-next.ts +10 -2
  346. package/scripts/run/ship/run-ship-overlap.ts +195 -0
  347. package/scripts/run/ship/run-ship-pre-detach.ts +33 -15
  348. package/scripts/run/ship/run-ship-preflight.ts +28 -2
  349. package/scripts/run/ship/run-ship-return.ts +31 -7
  350. package/scripts/run/ship/run-ship-review-steps.ts +25 -14
  351. package/scripts/run/ship/run-ship-review.ts +15 -2
  352. package/scripts/run/ship/run-ship-steps.ts +1 -1
  353. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  354. package/scripts/run/ship/run-ship-sync.ts +14 -6
  355. package/scripts/run/tidy/run-tidy-cli.ts +3 -3
  356. package/scripts/run/tidy/run-tidy-lanes.ts +3 -2
  357. package/scripts/safe-chain/project-config.ts +7 -2
  358. package/scripts/sync/sync-hook-safety.ts +8 -2
  359. package/scripts/test/test-e2e-guard.ts +30 -5
  360. package/scripts/test/test-unit-guard.ts +16 -1
  361. package/scripts/test/unit-worker-share.ts +26 -3
  362. package/scripts/time-runtime/time-batch-guard.ts +3 -3
  363. package/scripts/time-runtime/time-hook-transcript.ts +3 -2
  364. package/scripts/time-runtime/time-shell.ts +39 -4
  365. package/scripts/time-runtime/time-spans.ts +1 -0
  366. package/scripts/time-runtime/time-tool-call.ts +7 -0
  367. package/scripts/version/effective-upstream.ts +3 -4
  368. package/scripts/version/kit-version-config.ts +8 -2
  369. package/scripts/version/latest-corepack.ts +1 -2
  370. package/scripts/version/release-hold.ts +11 -4
  371. package/scripts/version/version-commands.ts +12 -4
  372. package/templates/gitignore +6 -2
  373. package/dist/hooks/chunk-D5QBTOCZ.js +0 -68
  374. package/dist/hooks/chunk-UT7YC3N2.js +0 -56
@@ -54,7 +54,7 @@
54
54
  "hooks": [
55
55
  {
56
56
  "type": "command",
57
- "command": "project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null || git rev-parse --show-toplevel)\" && cd \"$project_root\" && sh scripts/hooks/run-hook.sh audit-provision",
57
+ "command": "if project_root=\"$(unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\"; fi && cd \"$project_root\" && sh scripts/hooks/run-hook.sh audit-provision",
58
58
  "timeout": 180
59
59
  }
60
60
  ]
@@ -66,7 +66,7 @@
66
66
  "hooks": [
67
67
  {
68
68
  "type": "command",
69
- "command": "project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null || git rev-parse --show-toplevel)\" && cd \"$project_root\" && sh scripts/hooks/run-hook.sh session-lang",
69
+ "command": "if project_root=\"$(unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\"; fi && cd \"$project_root\" && sh scripts/hooks/run-hook.sh session-lang",
70
70
  "timeout": 10
71
71
  }
72
72
  ]
@@ -74,11 +74,11 @@
74
74
  ],
75
75
  "PreToolUse": [
76
76
  {
77
- "matcher": "Bash|Edit|Read|Write|AskUserQuestion",
77
+ "matcher": "Bash|Edit|Read|Write|AskUserQuestion|Agent|Task",
78
78
  "hooks": [
79
79
  {
80
80
  "type": "command",
81
- "command": "project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null || git rev-parse --show-toplevel)\" && cd \"$project_root\" && sh scripts/hooks/run-hook.sh pretool-guard",
81
+ "command": "if project_root=\"$(unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\"; fi && cd \"$project_root\" && sh scripts/hooks/run-hook.sh pretool-guard",
82
82
  "timeout": 20
83
83
  }
84
84
  ]
@@ -90,7 +90,7 @@
90
90
  "hooks": [
91
91
  {
92
92
  "type": "command",
93
- "command": "project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null || git rev-parse --show-toplevel)\" && cd \"$project_root\" && sh scripts/hooks/run-hook.sh format-edited",
93
+ "command": "if project_root=\"$(unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\"; fi && cd \"$project_root\" && sh scripts/hooks/run-hook.sh format-edited",
94
94
  "timeout": 90
95
95
  }
96
96
  ]
@@ -102,7 +102,7 @@
102
102
  "hooks": [
103
103
  {
104
104
  "type": "command",
105
- "command": "project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null || git rev-parse --show-toplevel)\" && cd \"$project_root\" && sh scripts/hooks/run-hook.sh stop-guard",
105
+ "command": "if project_root=\"$(unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\"; fi && cd \"$project_root\" && sh scripts/hooks/run-hook.sh stop-guard",
106
106
  "timeout": 20
107
107
  }
108
108
  ]
@@ -5,76 +5,47 @@ description: Checks after `pnpm update`, `josh latest`, `josh adopt`, `pnpm josh
5
5
 
6
6
  # After a dependency-update command
7
7
 
8
- `CLAUDE.md` → "Decision autonomy" keeps both prohibitions resident as Tier C — never touch `overrides`
9
- in either file, never touch `devEngines`, without explicit user approval. This skill is the other
10
- half: what you actually run to find out whether a command already touched them, and how to read the
11
- one change that is expected. It applies after `pnpm update`, `josh latest`, `josh adopt` (which runs
12
- `josh latest` as one of its steps), `pnpm josh overrides`, a Dependabot merge, or any other command
13
- that can rewrite dependency versions.
14
-
15
- This skill is the single source of the overrides protection's procedure;
16
- `prompts/collaboration-workflow/operating-rules.md` only points here. Overrides were added on
17
- purpose — for security, compatibility or a working guarantee (for example
18
- `"esbuild@<=0.24.2": ">=0.25.0"` for Workers build compatibility).
8
+ `CLAUDE.md` → "Decision autonomy" keeps both prohibitions resident as Tier C: never touch `overrides`,
9
+ never touch `devEngines`, without explicit user approval. This skill is the single source of how to check
10
+ whether a command touched them, after `pnpm update`, `josh latest`, `josh adopt` (which runs
11
+ `josh latest`), `pnpm josh overrides`, a Dependabot merge, or any command that rewrites dependency
12
+ versions. Overrides exist on purpose (e.g. `"esbuild@<=0.24.2": ">=0.25.0"` for Workers builds).
19
13
 
20
14
  ## 1. Effective overrides live in the workspace — inspect both files
21
15
 
22
- **pnpm 11 and 12 read effective overrides only from `pnpm-workspace.yaml`.** The old
23
- `pnpm.overrides` field in **`package.json` is ignored**, as verified with pnpm 12.6.0. Inspect both
24
- files to preserve any existing declarations, but do not count the package field as an effective
25
- override. An absent or empty package field says nothing about workspace overrides: app-kit's
26
- `package.json` has no `pnpm` field, while its workspace has a real override.
16
+ **pnpm 11 and 12 read effective overrides only from `pnpm-workspace.yaml`.** `pnpm.overrides` in
17
+ **`package.json` is ignored** (verified with pnpm 12.6.0). Inspect both to preserve existing
18
+ declarations, but an absent package field says nothing about workspace overrides.
27
19
 
28
20
  ## 2. The check is a command you run, not a conclusion you reach
29
21
 
30
- **The check is a command you run, not a conclusion you reach.** After `pnpm update`, `josh latest`,
31
- or any dependency-update command, verify the overrides in both `pnpm-workspace.yaml` and
32
- `package.json` by running
33
-
34
22
  ```bash
35
23
  git diff -- pnpm-workspace.yaml package.json
36
24
  ```
37
25
 
38
- (after `josh adopt`, which has already committed and returned to the default branch, compare the
39
- pull-request branch instead: `git diff <default>...<branch> -- pnpm-workspace.yaml package.json`)
40
- and confirm the effective `overrides:` block in `pnpm-workspace.yaml` and any historical
41
- `pnpm.overrides` declarations in `package.json` are untouched, **and** that `devDependencies`
42
- versions still respect the effective overrides. If any entry was removed, modified, or bumped past
43
- an override, restore it immediately, investigate why it changed, and report that to the user — never
44
- keep the change without explicit approval.
26
+ (after `josh adopt`, which has already committed and returned to the default branch:
27
+ `git diff <default>...<branch> -- pnpm-workspace.yaml package.json`). Confirm both overrides blocks
28
+ are untouched **and** `devDependencies` still respect the effective overrides. A removed, modified or
29
+ over-bumped entry: restore it immediately, investigate, and report — never keep it without approval.
45
30
 
46
- `josh latest` prints its own verdict as its last overrides line (`✔ overrides unchanged (<n> from
47
- <file>)`, or a `⚠ overrides changed` warning), and `pnpm josh overrides` compares effective workspace
48
- entries against a saved snapshot and reports ignored package entries — **quote what one printed.**
31
+ `josh latest` prints its verdict as its last overrides line (`✔ overrides unchanged (<n> from
32
+ <file>)` or `⚠ overrides changed`); `pnpm josh overrides` compares against a saved snapshot —
33
+ **quote what one printed.**
49
34
 
50
35
  ## 3. `devEngines` — the one expected change
51
36
 
52
- Verify `devEngines` was not changed **outside the legitimate `josh latest` pnpm bump**. If it changed
53
- in any other way, restore it immediately and ask the user before making any change.
54
-
55
- **Exception — the `josh latest` lockstep pnpm bump is expected, NOT a violation.** `josh latest`
56
- deliberately bumps `devEngines.packageManager.version` in lockstep with the top-level
57
- `packageManager` pin (see `scripts/version/latest-corepack.ts` → `sync_development_engines`); the two
58
- MUST stay exactly equal — **byte-identical, `+sha512…` Corepack integrity suffix included**. pnpm
59
- compares them as raw strings, so a bare `11.18.0` paired with `pnpm@11.18.0+sha512…` is a mismatch
60
- and the dual-declaration warning fires; only a character-for-character match suppresses it.
61
-
62
- So after `josh latest`, **KEEP** a `devEngines.packageManager.version` change **if and only if** it
63
- now equals everything after `pnpm@` in the new `packageManager` pin (same version string **and** same
64
- integrity suffix; only the `version` field moved). Reverting it would both undo a valid toolchain
65
- update **and** re-introduce a `packageManager`/`devEngines` mismatch — the opposite of the rule's
66
- intent.
37
+ **Exception — the `josh latest` lockstep pnpm bump is expected, NOT a violation.** **KEEP** a
38
+ `devEngines.packageManager.version` change **if and only if** it equals everything after `pnpm@` in
39
+ the new `packageManager` pin — **byte-identical, `+sha512…` Corepack integrity suffix included**
40
+ (`scripts/version/latest-corepack.ts` → `sync_development_engines`). Reverting it would re-introduce
41
+ the mismatch.
67
42
 
68
- **Restore + ask only** when `devEngines` changed in some OTHER way: its version no longer matches
69
- `packageManager` (a dropped, stale, or truncated integrity suffix counts as a mismatch), its
70
- structure changed (`name` / `onFail` / fields added or removed), or it was touched by something other
71
- than `josh latest`. The one structural change that is expected is `josh sync` moving
72
- `devEngines.packageManager.onFail` from `"error"` to `"download"` — a user-approved migration that
73
- leaves `name` and `version` untouched; keep it.
43
+ **Restore + ask** when `devEngines` changed any other way: the version no longer matches
44
+ `packageManager` (a dropped or truncated suffix counts), its structure changed (`name` / `onFail` /
45
+ fields), or something other than `josh latest` touched it. One structural change is expected and
46
+ kept: `josh sync` moving `devEngines.packageManager.onFail` from `"error"` to `"download"`.
74
47
 
75
48
  ## 4. When the bump breaks something — fix forward
76
49
 
77
- The procedure — latest-first, fix forward at the correct layer, pin back only as a last resort with a
78
- tracking issue — has its single source in
79
- `prompts/collaboration-workflow/principles.md` → "latest-first". Fix-forward never authorizes a silent edit to a protected pin: the
80
- approval gates in sections 1–3 still apply.
50
+ Single source: `prompts/collaboration-workflow/principles.md` → "latest-first". Fix-forward never
51
+ authorizes a silent edit to a protected pin; sections 1–3 still apply.
@@ -5,10 +5,6 @@ description: Procedures for `josh epic:audit`, `epic:next` and `epic:bundle`. Re
5
5
 
6
6
  # The `josh epic:*` commands
7
7
 
8
- These three commands are what turn an epic from a list of issue numbers into something a run can
9
- execute unattended. **This skill is their single source**; where each rule came from is
10
- `docs/maintainers/epic-commands-rationale.md` → "Where each rule came from".
11
-
12
8
  The workflow keywords themselves — `kickoff`, `fullrun`, `halfrun`, `prrun`, `backlogrun` — live in the
13
9
  `workflow-commands` skill.
14
10
 
@@ -19,27 +15,23 @@ epic:audit → find contradictions across the children, and fix what it finds (T
19
15
  backlogrun → which calls epic:next each round
20
16
  ```
21
17
 
22
- Front-loading every `needs-decision` in one pass is `backlogrun`'s job, not a command of this skill:
23
- `backlogrun-steps.md` → "Resolve what the plan can resolve, before starting". A `backlogrun #E --only`'s
24
- pre-check is `epic:audit`.
18
+ Front-loading every `needs-decision` is `backlogrun`'s job: `backlogrun-steps.md` → "Resolve what
19
+ the plan can resolve, before starting". A `backlogrun #E --only`'s pre-check is `epic:audit`.
25
20
 
26
- **Two references are read only when their case arises**: `execution-waves.md` when an epic's children
27
- need an order between groups (a wave boundary, or one child that must run alone), and
28
- `epic-bundle.md` when a filing's `epic:bundle` answer places the issue.
21
+ Read `execution-waves.md` only when children need an order between groups (a wave boundary, or a child
22
+ that must run alone), and `epic-bundle.md` only when a filing's `epic:bundle` answer places the issue.
29
23
 
30
24
  ## Recording a decision
31
25
 
32
- **A decision is recorded in two places, and one without the other loses half of it.** The epic's
33
- `## Decisions` log carries the decision; a comment on each child it applies to carries the reasoning
34
- for that child's reader. **Recording a decision removes that child's `needs-decision` label** (Tier A);
35
- the label-clearing rule itself is `backlogrun-park.md` → "park and continue".
26
+ Record it in both places: the epic's `## Decisions` log, and a comment on each child it applies to.
27
+ Recording a decision removes that child's `needs-decision` label (Tier A; `backlogrun-park.md` →
28
+ "park and continue").
36
29
 
37
- - **A decision taken *as* a child joins the epic** goes through `pnpm josh epic --add … --decision-file`
38
- — `epic-bundle.md` is that flag's single source, and it writes both halves at once.
39
- - **A decision about a child the epic already tracks** cannot use that flag: an insertion with nothing
40
- to add is refused outright. Until an entry point for already-tracked children exists, write the
41
- child comments with `pnpm josh issue:comment <N> --body-file <path>` on each child the answer
42
- applies to, and **say in the report that the epic's `## Decisions` entry is still pending**.
30
+ - **Decided as a child joins the epic**: `pnpm josh epic --add … --decision-file` writes both
31
+ (`epic-bundle.md`).
32
+ - **About a child the epic already tracks**: that flag refuses an insertion with nothing to add.
33
+ Comment on each child with `pnpm josh issue:comment <N> --body-file <path>`, and **say in the report
34
+ that the epic's `## Decisions` entry is still pending**.
43
35
 
44
36
  ```md
45
37
  ## Decisions
@@ -55,8 +47,8 @@ the label-clearing rule itself is `backlogrun-park.md` → "park and continue".
55
47
 
56
48
  ## Creating an epic
57
49
 
58
- A split into two or more issues always gets an epic (`prompts/collaboration-workflow/issue-template.md`).
59
- Create it with the command, never by hand-writing the body:
50
+ A split into two or more issues always gets an epic (`prompts/collaboration-workflow/issue-template.md`),
51
+ created with the command, never by hand:
60
52
 
61
53
  ```bash
62
54
  pnpm josh epic "<epic-title>" <N1> <N2> ... # order-free batch
@@ -64,105 +56,68 @@ pnpm josh epic "<epic-title>" <N1> <N2> ... --ordered # argument order is the d
64
56
  # --rationale-file <path|-> fills Split rationale; --origin <owner/repo#N> adds the backlink
65
57
  ```
66
58
 
67
- The body format is the command's output, and `pnpm josh epic:check <E>` answers whether a body still
68
- meets it (the parser auto-close reads; exit 1 on a miss) — run it after any hand edit. `pnpm josh
69
- followup` closes the epic once every task-list child is closed; one tracking a cross-repository child
70
- is closed by hand. The by-hand fallback where `josh` is unavailable: `issue-template.md`; the format's
71
- reasons and the history: `docs/maintainers/epic-commands-rationale.md` → "Creating an epic by hand".
59
+ After any hand edit run `pnpm josh epic:check <E>` (exit 1 when the body no longer parses).
60
+ `pnpm josh followup` closes the epic once every task-list child is closed; one tracking a
61
+ cross-repository child is closed by hand. Without `josh`: `issue-template.md`.
72
62
 
73
63
  ## `josh epic:audit <E>` — contradictions across the children
74
64
 
75
- `epic:check` verifies one epic's *format*; this verifies that the children agree.
76
-
77
- Run it **without being asked**: when a `backlogrun` starts a named epic's children, and right
78
- after a child is added or a dependency changed.
79
-
80
- The cycle and declaration-mismatch checks are `epic:next`'s, reused rather than re-derived. What this
81
- adds is reading *inside* the children:
65
+ `epic:check` verifies the format; this verifies the children agree. Run it **without being asked**
66
+ when a `backlogrun` starts a named epic's children, and right after a child is added or a dependency
67
+ changed. Cycle and declaration checks are reused from `epic:next`; it adds:
82
68
 
83
69
  | Check | Level |
84
70
  | --- | --- |
85
71
  | A child's body names another child, nothing orders the two | warning |
86
- | A child's **acceptance criteria** name another child, nothing orders the two | **error**; a warning once both children are closed, and a warning when the pair is in two repositories. A warning there does **not** mean the pair is safe: the child is still offered as runnable, and recording the relation is what clears it |
72
+ | A child's **acceptance criteria** name another child, nothing orders the two | **error**; a warning once both are closed or when the pair spans two repositories — the child is still offered as runnable until the relation is recorded |
87
73
  | A body cites a missing or already-closed issue | warning |
88
- | A task-list row points at another **epic** | warning — `epic:next` withholds the row, so the batch is already safe; what is left is a thing a person has to look at |
74
+ | A task-list row points at another **epic** | warning — `epic:next` already withholds the row; a person should look |
89
75
  | An issue names this epic as parent that the task list does not track | warning |
90
76
  | The search for those issues could not read the open backlog | **error** |
91
77
  | That search stopped before the end of the backlog | warning |
92
78
 
93
- **Only errors fail it** (exit 1); a warning leaves the exit code alone and is for the reader to judge
94
- — the first check fires on a legitimate forward reference as readily as on a missing dependency. A
95
- forward reference the other child *already depends on* is not reported at all.
96
-
97
- **A pair with either child closed is a warning, not an error**, and **the demotion needs the closed
98
- state confirmed**: `epic_issue.normalize_state` maps every state but `CLOSED` (`MERGED` included) to
99
- `OPEN`, so a state that could not be confirmed stays an error.
79
+ **Only errors fail it** (exit 1). A forward reference the other child already depends on is not
80
+ reported. A pair is demoted to a warning only when the closed state is **confirmed** (any state but
81
+ `CLOSED` normalizes to `OPEN`).
100
82
 
101
- **Fixing what it finds is Tier A** — re-pointing a dependency or correcting prose is reversible and
102
- will otherwise stall the work, so fix it without asking and record why on the issue. Park with
103
- `needs-decision` only when the contradiction is a design choice nobody has made.
83
+ **Fixing what it finds is Tier A** — fix it and record why on the issue. Park with `needs-decision`
84
+ only for a design choice nobody has made.
104
85
 
105
- **The two `orphan search` findings are the exception, because neither is a contradiction.** They are
106
- about the search itself rather than about anything the children say:
86
+ The two `orphan search` findings are about the search, not the children:
107
87
 
108
- - `✖ orphan search: Could not list the open issues…` — the search never ran, so "no orphans" would
109
- be a claim about a listing that never arrived. It fails the audit, which stops the epic's run at its
110
- step 0. **Re-run the audit**; that is the whole response. There is nothing to fix and nothing to
111
- decide, so neither Tier A nor a `needs-decision` park applies. If it keeps failing, check
112
- `gh auth status` and whether the rate limit has reset.
113
- - `⚠ orphan search: The open-issue scan hit its …` — the search covered only the newest part of the
114
- backlog (500 issues, or 50 bodies mentioning the epic). It ran, so the audit passes; read the line,
115
- and look further down the backlog by hand if an orphan is expected there.
88
+ - `✖ orphan search: Could not list the open issues…` — **re-run the audit**; nothing to fix or decide.
89
+ If it keeps failing, check `gh auth status` and the rate limit.
90
+ - `⚠ orphan search: The open-issue scan hit its …` — only the newest 500 issues (or 50 bodies) were
91
+ covered; the audit passes. Look further by hand if an orphan is expected.
116
92
 
117
- **One thing it cannot check** belongs to planning: when a child introduces a new label, command,
118
- state or artifact, list the existing code referencing that concept and confirm some child owns
119
- updating it. Label names are single-sourced in `scripts/issue/issue-labels.ts`.
120
-
121
- History: `docs/maintainers/epic-commands-rationale.md` → "`epic:audit` — why the children are read across".
93
+ **It cannot check** that when a child introduces a new label, command, state or artifact, some child
94
+ owns updating the existing code referencing that concept — do that at planning. Label names live in
95
+ `scripts/issue/issue-labels.ts`.
122
96
 
123
97
  ## `josh epic:next <E…>` — what is runnable
124
98
 
125
- Returns **every** runnable child, bundled per repository with the local checkout to run it in.
126
- `--repo <owner/repo>` narrows to one and prints a single token: the issue number, or the verdict.
127
- `--lanes` beside it prints one issue number per line instead, **up to the number of free lanes in
128
- that repository** — so a caller that reads one token keeps reading one token.
129
-
130
- **It takes more than one epic, and they answer as one.** Every leading argument is an epic
131
- reference — the split is on the first flag, so `epic:next 858 909 --repo X --lanes` reads two — and
132
- their runnable children merge into one candidate pool per repository, so six free lanes fill from
133
- every named epic rather than from whichever was typed first. **The priority order is the order the
134
- epics were named.** **Inside one epic the order is that epic's own task list**: its declared chain
135
- still decides which children are *runnable*, and among those, the order the task list names them is
136
- the order they are offered — so an epic says "do this one first" by moving the row, not by declaring
137
- a chain, which would stop every child behind a stuck one.
138
- **`pnpm josh epic --add <E> <N> --order-before <M>` is what moves that row**: the row goes where the
139
- flag names, and the declaration and the `blocked-by` relations are left exactly as they stood — so
140
- "moving the row" is a command rather than the hand edit `epic --add` exists to prevent.
141
- `--order-after <M>` is its other direction, and both work on a child the epic already tracks, which
142
- is a pure reorder. **A child a chain still holds is not freed by moving its row**: `epic:next`
143
- filters by `blocked-by` before it applies task-list order, so the command prints a ⚠️ line naming
144
- that child rather than reporting a reordering nothing can observe. **A child two epics both track
145
- enters once**, keyed by `owner/repo#number` and kept by the epic named earlier; withheld there, it
146
- stays withheld, because a `blocked-by` relation belongs to the issue rather than to the epic listing
147
- it. **One unusable graph refuses the whole answer**, and **one reference that does not parse fails
148
- the read** rather than being dropped. `docs/josh-commands-backlog.md` → "`josh epic:next`" carries the
149
- worked form.
150
-
151
- **An `in-progress` issue occupies a lane rather than the whole repository.** The occupancy is counted
152
- from that repository's own `in-progress` listing — never from anything the session remembers — and
153
- what is left of `JOSH_LANE_LIMIT` (**default 4**) is what gets offered. At zero the answer is `wait`
154
- and the holders are named on standard error. A parked child releases its lane; one stopped by
155
- `needs-human-review` goes on holding one, because its uncommitted work is still in that checkout.
156
-
157
- **A child that is itself an epic is never offered** — an epic is not a unit of work. It waits on a
158
- *person*, because no amount of waiting turns an epic into work. **The test is the child's `epic`
159
- label, never how its task-list row is written**: a row naming `owner/repo#N` is a different property
160
- and a legitimate one — it disables the epic auto-close by design, which is why a cross-repository
161
- backlink is prose rather than a row — so a cross-repository child that is not an epic stays
162
- runnable, and one that is an epic is withheld exactly like a local one. **A parent epic over another
163
- epic never auto-closes**: the auto-close evaluates only the epics whose own task list holds the issue
164
- a merge just closed, and a grandchild merging never reaches the grandparent. `epic:audit` reports the
165
- same row, with that consequence in the finding.
99
+ Returns **every** runnable child, bundled per repository with its local checkout. `--repo <owner/repo>`
100
+ narrows to one and prints a single token (an issue number or the verdict); `--lanes` beside it prints
101
+ one number per line, **up to the number of free lanes in that repository**.
102
+
103
+ - **Several epics answer as one**: every argument before the first flag is an epic; their runnable
104
+ children merge into one pool per repository. **Priority is the order the epics were named**, then
105
+ each epic's own task-list order (its declared chain still decides what is runnable).
106
+ - **Reorder with `pnpm josh epic --add <E> <N> --order-before <M>`** (or `--order-after <M>`), never a
107
+ hand edit; declarations and `blocked-by` relations stay as they were. Moving a row does not free a
108
+ child a chain still holds — the command prints a ⚠️ line instead.
109
+ - **A child two epics track enters once**, kept by the epic named earlier.
110
+ - **One unusable graph refuses the whole answer**; **one reference that does not parse fails the
111
+ read**. Worked form: `docs/josh-commands-backlog.md` → "`josh epic:next`".
112
+
113
+ **An `in-progress` issue occupies a lane, not the repository.** Free lanes are `JOSH_LANE_LIMIT`
114
+ (**default 4**) minus that repository's `in-progress` listing. At zero the answer is `wait`, with the
115
+ holders on standard error. A parked child releases its lane; a `needs-human-review` stop keeps it.
116
+
117
+ **A child that is itself an epic is never offered** and waits on a *person*. The test is the child's
118
+ `epic` label, never how its row is written: a cross-repository `owner/repo#N` row that is not an epic
119
+ stays runnable. **A parent epic over another epic never auto-closes** (a grandchild's merge never
120
+ reaches it); `epic:audit` reports the row.
166
121
 
167
122
  Children that are not runnable are sorted by **whether waiting helps**, never by label:
168
123
 
@@ -172,62 +127,40 @@ Children that are not runnable are sorted by **whether waiting helps**, never by
172
127
  | Waiting on time | Wait and ask again |
173
128
  | Waiting on a person | Stop and report |
174
129
 
175
- **A blocker outside every named epic is weighed, not ignored.** Closed, it resolves (a
176
- cross-repository one still waits for its release); open and tracked by any epic named in the same
177
- call, the child waits on time unless that blocker itself waits on a person, which the child
178
- inherits; open and tracked by none, the child waits on a person and the blocker is named on standard
179
- error; a state the relation did not carry reads as waiting. **So an order between two epics is
180
- recorded with a native `blocked-by` relation and honoured by naming both epics** — `epic:next <E1>
181
- <E2>`, or `backlog:next`, whose set is the whole opted-in backlog. The table is
182
- `docs/josh-commands-backlog.md` → "`josh epic:next`".
183
-
184
- Two things stop the command rather than being worked around: a **circular dependency**, and a
185
- **disagreement between the epic body and the `blocked-by` relations** (an epic written before `josh`
186
- recorded them, a recording that failed, or a relation hand-added since). Only a line that is
187
- *nothing but* a chain counts as a declaration — a prose line recommending an execution order is a suggestion, not a dependency.
130
+ **A blocker outside every named epic is weighed**: closed, it resolves (cross-repository: after its
131
+ release); open and tracked by an epic named in the same call, the child waits on time (or on a person,
132
+ if the blocker does); open and untracked, the child waits on a person and the blocker is named on
133
+ standard error; an unknown state reads as waiting. **Order two epics with a native `blocked-by`
134
+ relation and name both** — `epic:next <E1> <E2>`, or `backlog:next`.
188
135
 
189
- Why it orders and counts as it does: `docs/maintainers/epic-commands-rationale.md` → "`epic:next` — why it answers as it does".
136
+ Two things stop the command: a **circular dependency**, and a **disagreement between the epic body
137
+ and the `blocked-by` relations**. Only a line that is *nothing but* a chain is a declaration — a prose
138
+ line recommending an execution order is a suggestion, not a dependency.
190
139
 
191
140
  ## Epics that span repositories
192
141
 
193
- Write cross-repository children in the task list as `owner/repo#N` or a full issue URL. Their state
194
- is read against that repository through `gh api`, so **no local clone is needed to learn it** — only
195
- to implement.
142
+ Write cross-repository children as `owner/repo#N` or a full issue URL. Their state is read through
143
+ `gh api`, so **no local clone is needed to learn it** — only to implement.
196
144
 
197
- - **The owner restriction is inherited unchanged**: a repository with a different owner is never a
198
- target, by any route.
199
- - **The epic auto-closes only when every cross-repository child's state could actually be read.** One
200
- unreadable child leaves it open, exactly as before.
201
- - **An epic in another repository must be referenced as `owner/repo#N`** — `backlogrun
145
+ - **The owner restriction is inherited unchanged**: a different owner is never a target.
146
+ - **The epic auto-closes only when every cross-repository child's state could be read.**
147
+ - **An epic in another repository is referenced as `owner/repo#N`** — `backlogrun
202
148
  joshuafolkken/kit#<E> --only`, `epic:next joshuafolkken/kit#<E> --repo joshuafolkken/app-kit`. A
203
- bare `#N` resolves to *this* repository's issue of that number. A cross-repository epic exists in
204
- one repository only.
205
- - **`epic:next` prints each candidate's repository and local checkout** from the repository discovery
206
- map; a repository with no checkout prints `(no local checkout)` and is **never cloned on its own**.
207
-
208
- **A dependency that crosses a repository is not satisfied by the blocking issue closing** — merging
209
- does not publish. It resolves only when the blocker is closed **and** the version its default branch
210
- declares has appeared in the registry.
211
-
212
- **Unless that repository publishes nothing.** A repository with no `package.json` on its default
213
- branch, or one declaring `private`, ships no release for the check to wait on, so a closed blocker
214
- there resolves. The answer is read from the blocker repository's own manifest and never from the
215
- registry (a registry 404 also means "this token may not see it"). A manifest read that fails (rather
216
- than answering 404) is told apart by HTTP status and still waits.
217
-
218
- **The evaluation is an AND in that order.** While the blocker is open the registry is never
219
- consulted, so a run never stalls on a publish from the moment it starts. The target is that exact
220
- version, never "something newer". **A child no longer bumps the version**: the version moves only
221
- when `pnpm josh release` runs, so the target is the release that includes the blocker, not the
222
- default branch's version just after its merge (the previous release). The publish check shares
223
- `josh propagate`'s implementation; it is not defined twice. History:
224
- `docs/maintainers/epic-commands-rationale.md` → "Cross-repository epics".
149
+ bare `#N` is this repository's issue.
150
+ - **`epic:next` prints each candidate's local checkout**; none prints `(no local checkout)` and is
151
+ **never cloned on its own**.
152
+
153
+ **A cross-repository dependency resolves only when the blocker is closed and the version its default
154
+ branch declares is in the registry** (checked in that order; that exact version). A child no longer
155
+ bumps the version, so the target is the release that includes the blocker. **Unless that repository
156
+ publishes nothing**: no `package.json` on its default branch, or `private`, resolves on close — read
157
+ from its manifest, never the registry; a failed manifest read (not a 404) still waits. The publish
158
+ check is `josh propagate`'s.
225
159
 
226
160
  ## `josh epic:bundle <N>` — does this new issue belong with one already filed?
227
161
 
228
- It runs right after an issue is filed: by `kickoff` / `fullrun` / `halfrun`, or by any Tier A filing
229
- mid-implementation, including inside a `backlogrun`. **`pnpm josh issue:file` runs it as its last step**;
230
- run it by hand only when that step printed `⚠`. **It recommends; it writes nothing.**
162
+ Runs right after any filing; **`pnpm josh issue:file` runs it as its last step** — run it by hand only
163
+ when that step printed `⚠`. **It recommends; it writes nothing.**
231
164
 
232
165
  | Candidates | Do | Tier |
233
166
  | --- | --- | --- |
@@ -239,10 +172,4 @@ run it by hand only when that step printed `⚠`. **It recommends; it writes not
239
172
  | No strong signal | Nothing | — |
240
173
  | **The epic listing was cut short** | **Nothing** — every placing row above is withheld | — |
241
174
 
242
- **A placing answer is acted on with `epic-bundle.md`** — what counts as a signal, the cut listing,
243
- choosing between epics, and the `--decision-file` record that pays for the choice. `Nothing to
244
- bundle.` needs no further read.
245
-
246
- History: `docs/maintainers/epic-commands-rationale.md` → "`epic:bundle` — why issues filed apart are bundled afterwards";
247
- the reasons behind `epic-bundle.md`: `docs/maintainers/epic-commands-rationale.md` → "`epic:bundle` — why each answer reads as it does";
248
- behind `execution-waves.md`: `docs/maintainers/epic-commands-rationale.md` → "Execution waves — why a wave is not a mechanism".
175
+ **A placing answer is acted on with `epic-bundle.md`**. `Nothing to bundle.` needs no further read.