@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
@@ -1,113 +1,99 @@
1
1
  # `backlogrun` — running a child (shared mechanics, delegation, liveness, session setup)
2
2
 
3
- Point-of-use, read one section at a time from `backlogrun.md` → "The route table" (rationale: `docs/maintainers/backlogrun-child-rationale.md` → "Why the file is read by section").
3
+ Point-of-use, read one section at a time from `backlogrun.md` → "The manifest — the ordered flow".
4
4
 
5
5
  ## Running a child — the shared mechanics
6
6
 
7
- Everything below runs **one child** — of a named epic, or of the opted-in backlog. A single-issue named item, a named epic's child and a bare backlog child all run the same `fullrun` in the same way, and this part is the single source of how. A named epic runs these mechanics over its own children until every one is processed, then the run advances to the next named item.
7
+ This file is the single source of how **one child** runs — a named single-issue item, a named epic's
8
+ child and a bare backlog child all run the same `fullrun`. A named epic runs these mechanics over its
9
+ children until every one is processed, then the run advances to the next named item.
8
10
 
9
11
  ## When `#N` is not an epic
10
12
 
11
- `backlogrun` accepts an ordinary Issue as well as an epic. `backlogrun #<N>` on an Issue with no task list
12
- runs `#<N>` as a `fullrun` and then finishes. Inside `backlogrun #<N>`, a prerequisite or a split found
13
- mid-run does **not** stop the run (rationale: `docs/maintainers/backlogrun-child-rationale.md` → "Why a
14
- bare Issue promotes itself under `backlogrun` but not under `fullrun`"):
15
-
16
- 1. File the new Issue(s) with the matching route label — `route:split` for a split, `route:tier-a`
17
- for a prerequisite — no confirmation.
18
- 2. **Stash the work in progress and remove `in-progress` from `#<N>`**, exactly as steps 2 and 4 of
19
- "A prerequisite discovered mid-run" do — `git stash push -u -m "..."` with the `-u`, the
20
- `gh api repos/{owner}/{repo}/issues/<N>/comments` post that records the stash, and
21
- `pnpm josh run:release <N>`, which removes the label with the hold.
13
+ `backlogrun #<N>` on an Issue with no task list runs `#<N>` as a `fullrun` and finishes. A prerequisite
14
+ or a split found mid-run does **not** stop it:
15
+
16
+ 1. File the new Issue(s) — `route:split` for a split, `route:tier-a` for a prerequisite — no
17
+ confirmation.
18
+ 2. **Stash and remove `in-progress`**, as steps 2 and 4 of "A prerequisite discovered mid-run" do:
19
+ `git stash push -u -m "..."`, a `gh api repos/{owner}/{repo}/issues/<N>/comments` post recording the
20
+ stash, and `pnpm josh run:release <N>`.
22
21
  3. **Ask `pnpm josh epic:bundle <N>` whether an epic already tracks `#<N>` before creating one.**
23
22
 
24
23
  | Answer | What to do |
25
24
  | --- | --- |
26
- | An epic `#<E>` already tracks `#<N>` | `pnpm josh epic --add <E> <P> --before <N>` for a prerequisite, or `--add <E> <N1> ...` for a split. **Do not create a second epic.** Continue the loop against `#<E>` |
27
- | No epic tracks it | Create one — the command depends on what was found (table below) |
28
- | **The command could not answer** — a non-zero exit, `Could not confirm which epic already tracks these — do not place this issue in one.`, or a ⚠ warning about a truncated listing (beginning `⚠ The epic listing …`, in either form `hit its …-epic cap` / `stopped at the …-issue page ceiling`) above a `Nothing to bundle.` verdict; `⚠ Could not read #N.` is one failed relation read and voids nothing, and a definitive answer stands even beside a warning | Park `#<N>` with `needs-decision` and report. "Could not tell" is not "no epic tracks it" |
25
+ | An epic `#<E>` already tracks `#<N>` | `pnpm josh epic --add <E> <P> --before <N>` (prerequisite) or `--add <E> <N1> ...` (split). **Do not create a second epic**; continue against `#<E>` |
26
+ | No epic tracks it | Create one (table below) |
27
+ | **The command could not answer** | Park `#<N>` with `needs-decision` and report — "could not tell" is not "no epic" |
28
+
29
+ "Could not answer" is a non-zero exit, `Could not confirm which epic already tracks these — do not
30
+ place this issue in one.`, or a `⚠ The epic listing …` truncation warning (`hit its …-epic cap` /
31
+ `stopped at the …-issue page ceiling`) above `Nothing to bundle.`. `⚠ Could not read #N.` voids
32
+ nothing, and a definitive answer stands beside a warning.
29
33
 
30
- When creating one, `#<N>` is itself one of the deliverables — this path always takes the
31
- keep-as-a-child arm of `split-assessment.md`'s promote-or-create branch. Which command depends on
32
- what was found, because `--ordered` makes the argument order the dependency chain:
34
+ `#<N>` is itself one of the deliverables (the keep-as-a-child arm of `split-assessment.md`).
35
+ `--ordered` makes the argument order the dependency chain:
33
36
 
34
37
  | Found | Command |
35
38
  | --- | --- |
36
- | A prerequisite `<P>` | `pnpm josh epic "<title>" <P> <N> --ordered` — the prerequisite comes **first** |
39
+ | A prerequisite `<P>` | `pnpm josh epic "<title>" <P> <N> --ordered` — the prerequisite **first** |
37
40
  | A split into independent children | `pnpm josh epic "<title>" <N> <N1> ...` — **no `--ordered`** |
38
- | A split whose children do have an order | `pnpm josh epic "<title>" ... --ordered`, arguments in that order |
39
-
40
- 4. **Run `pnpm josh epic:audit <E>` now**, not earlier — there is no epic to audit until step 3.
41
- 5. **Do not stop.** Continue into the loop below against the new epic `#<E>`.
42
-
43
- **Nothing found means no epic.** If `#<N>` reaches its merge without a prerequisite or a split turning
44
- up, the run finishes there. An epic is created only when there is a second child to put in it.
41
+ | A split whose children do have an order | `pnpm josh epic "<title>" ... --ordered`, in that order |
45
42
 
46
- **Every guard below applies on this path unchanged** — 30 children, 10 Issues filed, 3 consecutive
47
- failures.
43
+ 4. **Run `pnpm josh epic:audit <E>` now** — there is no epic to audit before step 3.
44
+ 5. **Do not stop.** Continue into the loop against `#<E>`.
48
45
 
49
- **This does not let `fullrun` promote itself.** A `fullrun` that discovered a split still files the
50
- children and the epic and then **stops** (`split-assessment.md` → "Finding a split mid-run stops the
51
- run").
46
+ - **Nothing found means no epic** — the run finishes at `#<N>`'s merge.
47
+ - **Every guard applies unchanged** — 30 children, 10 Issues filed, 3 consecutive failures.
48
+ - **`fullrun` does not promote itself** — it files and **stops** (`split-assessment.md` → "Finding a
49
+ split mid-run stops the run"). `josh epic:next` still refuses an Issue with no task list.
50
+ - **A bare Issue named beside an epic is a mistyped command.** Named alone, the refusal is the answer;
51
+ among several, it is **skipped** — `backlogrun #<E> --only #<N>` exits 0, notes the skip on stderr
52
+ and **never runs `#<N>`**. To do both, type `backlogrun #<N>` after the epic.
52
53
 
53
- **`josh epic:next` is not changed by any of this.** It still refuses an Issue with no task list; the
54
- acceptance of a bare Issue belongs to `backlogrun`.
55
-
56
- **Naming a bare Issue beside an epic is a mistyped command rather than a second entry.** Where one
57
- reference is named, the refusal is the whole answer. Where several are, a task-listless reference is
58
- **skipped** so the other epics keep running — `backlogrun #<E> --only #<N>` with `#<N>` an ordinary Issue exits
59
- 0, notes the skip on standard error, and **never runs `#<N>`**. A run that means to do both types
60
- `backlogrun #<N>` on its own after the epic.
61
54
  ## Each child runs in a delegated unit
62
55
 
63
- **A child is not run in the parent loop's context** — **whatever offers a child — the loop, or a
64
- person clearing a label — the child is handed to a lane, never to the parent.** `pnpm josh delegate
65
- epic-child` answers `delegate`; in a lane the unit is a detached process started by `pnpm josh
66
- lane:launch` (`backlogrun-lanes.md` → "Opening one lane and dispatching its child"), with the invoking
67
- CLI's `worker` profile — Claude Code defaults to Anthropic `claude-opus-5-5` / `medium`
68
- (`docs/josh-commands-run.md` → "`josh lane:dispatch`", the single source).
69
- Where no isolated unit exists, run the child in the parent's context; the hand-off is still asked at
70
- every merge. Rationale: `docs/maintainers/backlogrun-child-rationale.md` → "Why each child runs in a
71
- delegated unit".
72
-
73
- **The parent reads GitHub, never the summary** — `pnpm josh issue:state <N>` (or `run:merge`) is the
74
- verifier; **never advance the loop on the summary alone**.
56
+ **Whatever offers a child — the loop, or a person clearing a label — the child is handed to a lane,
57
+ never run in the parent's context.** `pnpm josh delegate epic-child` answers `delegate`; the unit is a
58
+ detached process from `pnpm josh lane:launch` (`backlogrun-lanes.md` → "Opening one lane and
59
+ dispatching its child") with the CLI's `worker` profile — Claude Code defaults to Anthropic
60
+ `claude-opus-5-5` / `medium` (`docs/josh-commands-run.md` → "`josh lane:dispatch`"). With no isolated
61
+ unit, run the child in the parent's context and still ask the hand-off at every merge.
75
62
 
76
- **The brief names the invocation it descends from** — e.g. `backlogrun #<E> --only`, the child number,
77
- and that the child runs as `fullrun #<N>` under that authorization; the unit refuses a brief without it.
63
+ - **The parent reads GitHub, never the summary** — `pnpm josh issue:state <N>` (or `run:merge`)
64
+ verifies; **never advance the loop on the summary alone**.
65
+ - **The brief names the invocation it descends from** — e.g. `backlogrun #<E> --only`, the child
66
+ number, and that it runs as `fullrun #<N>` under that authorization; the unit refuses a brief without
67
+ it.
78
68
 
79
69
  ### What the summary carries, and how long it may be
80
70
 
81
- **The summary carries only what GitHub does not, in at most 25 lines; the brief states the bound.**
82
- Rationale: `docs/maintainers/backlogrun-child-rationale.md` → "Why the summary is bounded the way it is".
71
+ **Only what GitHub does not, in at most 25 lines; the brief states the bound.**
83
72
 
84
- - **Kept**: `Cause` / `Fix` / `Result`; every verification result not closed the ordinary way, named
85
- as such; observations that could bite later — **the only route a child's discretionary observation
86
- has** (`observation-filing.md` → "A delegated child does not take this route"); decisions not already
87
- logged; what was left undone, and under whose authority.
88
- - **Cut**: the changed-file list, per-round review detail, and restated rules.
73
+ - **Kept**: `Cause` / `Fix` / `Result`; every verification not closed the ordinary way, named as such;
74
+ observations that could bite later — **a child's only route for one** (`observation-filing.md` → "A
75
+ delegated child does not take this route"); decisions not yet logged; what was left undone, on whose
76
+ authority.
77
+ - **Cut**: the changed-file list, per-round review detail, restated rules.
89
78
 
90
79
  The person-facing report (`prompts/collaboration-workflow/report-format.md` → 「完了報告(セッション向け)」)
91
80
  is unchanged.
92
81
 
93
82
  ## A delegated unit that stopped without reporting
94
83
 
95
- **Hand the child to the unit without blocking on its return, and poll** — a stopped unit leaves no
96
- notification behind. Once its output has been unchanged for the silent-unit window, read
97
- `backlogrun-recovery.md` → "A delegated unit that stopped without reporting" and ask
98
- `pnpm josh run:liveness`.
84
+ **Hand the child off without blocking, and wait on `pnpm josh lane:await <N>`** — a stopped unit
85
+ leaves no notification, so the await's exit is the wake. Once its
86
+ output is unchanged for the silent-unit window, read `backlogrun-recovery.md` → "A delegated unit that
87
+ stopped without reporting" and ask `pnpm josh run:liveness`.
99
88
 
100
89
  ## Audit before the first child
101
90
 
102
- Run `pnpm josh epic:audit <E>` before step 1 below. **When the run began from a bare Issue there is
103
- nothing to audit yet** — that path runs the audit at the moment it creates the epic instead. Errors
104
- stop the run; warnings are read and carried on past. Fixing what it finds is Tier A. Rationale:
105
- `docs/maintainers/backlogrun-child-rationale.md` → "Why the audit runs before the first child".
91
+ Run `pnpm josh epic:audit <E>` before the first child; a run begun from a bare Issue audits when it
92
+ creates the epic. Errors stop the run; warnings are read and passed. Fixing a finding is Tier A.
106
93
 
107
94
  ## `josh latest` runs once per session, not once per child
108
95
 
109
- `josh latest` belongs to the **session**, not to a child. Ask once, the first time the loop below hands
110
- back a child number — before implementing that child — and never again:
96
+ Ask once, the first time the loop hands back a child number, before implementing it:
111
97
 
112
98
  ```bash
113
99
  pnpm josh latest:scope # → required | skip ; the reason on stderr
@@ -117,20 +103,14 @@ pnpm josh latest # on `required` only
117
103
  pnpm josh stash:pop "backlogrun: josh latest #<N>" # only if you stashed above — by message, not a positional pop
118
104
  ```
119
105
 
120
- On `required`, load the `dependency-update` skill; `latest-gate.md` is the single source. **Session,
121
- not run** — each session updates its own checkout, and a resumed `backlogrun` asks again. **The lock
122
- file lands with the first child's `pnpm josh git -y`**; fix a failing bump forward. **`josh latest` is
123
- never run inside a lane** (`pnpm josh latest:guard` refuses it) — with lanes the parent runs it in the
124
- primary checkout (`backlogrun-lanes.md` → "Once per repository, before the first lane opens").
125
-
126
- Rationale: `docs/maintainers/backlogrun-child-rationale.md` → "Why `josh latest` is hoisted to the
127
- session".
106
+ On `required`, load the `dependency-update` skill; `latest-gate.md` is the single source. A resumed
107
+ `backlogrun` asks again. **The lock file lands with the first child's `pnpm josh git -y`**; fix a
108
+ failing bump forward. **Never inside a lane** (`pnpm josh latest:guard` refuses) — the parent runs it
109
+ in the primary checkout (`backlogrun-lanes.md` → "Once per repository, before the first lane opens").
128
110
 
129
111
  ## Preflight — the child's claim asks it
130
112
 
131
- `pnpm josh run:hold <N>`, the first call of the child's `fullrun`, checks for an interrupted run's
132
- leftovers before it claims the tree, and prints the step for each answer (`reclaim` / `resume` /
133
- `park`) on stderr — follow it, and report a reclaim or resume with its stash reference. The answers are
134
- `docs/josh-commands-run.md` → "`josh run:hold`"; rationale:
135
- `docs/maintainers/backlogrun-child-rationale.md` → "Why the preflight is part of the claim".
136
-
113
+ `pnpm josh run:hold <N>`, the child's first call, checks for an interrupted run's leftovers before
114
+ claiming the tree and prints the step for each answer (`reclaim` / `resume` / `park`) on stderr —
115
+ follow it, and report a reclaim or resume with its stash reference (`docs/josh-commands-run.md` →
116
+ "`josh run:hold`").
@@ -1,14 +1,12 @@
1
1
  # `backlogrun` — lanes and concurrency
2
2
 
3
- Point-of-use, read one section at a time from `backlogrun.md` → "The route table".
3
+ Point-of-use, read one section at a time from `backlogrun.md` → "The manifest — the ordered flow".
4
4
 
5
5
  ## Concurrency: as many children per repository as it has free lanes
6
6
 
7
- **One session per repository**, each running only its own repository's children; the per-repository
8
- lane ceiling (`JOSH_LANE_LIMIT`, counted from the `in-progress` listing by `epic:next`) is
9
- `.claude/skills/epic-commands/SKILL.md` → "An `in-progress` issue occupies a lane", and a dependency that crosses a
10
- repository is `.claude/skills/epic-commands/SKILL.md` → "Epics that span repositories". Rationale:
11
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why the lane ceiling is shaped the way it is".
7
+ **One session per repository**, each running only its own repository's children. The lane ceiling is
8
+ `.claude/skills/epic-commands/SKILL.md` → "An `in-progress` issue occupies a lane"; a dependency that
9
+ crosses a repository is `.claude/skills/epic-commands/SKILL.md` → "Epics that span repositories".
12
10
 
13
11
  ## A solo run
14
12
 
@@ -19,65 +17,49 @@ it a defect (not an improvement, refactor, removal or feature)? Is it in kit's o
19
17
  (lint / type check / spell check / unit tests), the code review, the pre-push hook, or the merge
20
18
  checks — not a consumer repository's CI or template? Does it, on `main` now, make unrelated PRs
21
19
  answer wrongly (a false green or a false red)? All three, and the issue carries `run:solo`; any one
22
- missing, and it carries `run:lane`. `backlog:next` and `epic:next --lanes` answer `triage` for an issue
23
- with neither, so an issue a run files carries one of the two from its
24
- filing. **It stops the other lanes for one reason only: a batch run on broken verification leaves
25
- nobody's result trustworthy.** This section is the rule's single source; rationale:
26
- `docs/maintainers/wip-cap-rationale.md` → "Why a solo run"; provenance:
27
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Where each rule came from".
20
+ missing, and it carries `run:lane`. `backlog:next` and `epic:next --lanes` answer `triage` for an
21
+ issue with neither, so a filed issue carries one of the two from its filing. **It stops the other
22
+ lanes for one reason only: a batch run on broken verification leaves nobody's result trustworthy.**
28
23
 
29
24
  ## Lanes — running more than one child at a time
30
25
 
31
- `pnpm josh epic:next <E> --repo <owner/repo> --lanes` answers with **one issue number per line**, up to
32
- the number of free lanes, and each of those children runs in a **lane** of its own: a linked git work
33
- tree with its own branch, its own `.env` and its own dev and preview ports (`docs/josh-commands-run.md` →
34
- "`josh lane:open` / `josh lane:close` / `josh lane:list` / `josh lane:prune`"). **Implementation, the
35
- verification gate and the review run in parallel; the merges stay serial** — each one lands on the
36
- `main` the next is then measured against.
37
-
38
- **A lane child may cut its own turn before the gate.** Implementation done, it ends its process and a
39
- fresh one resumes the same lane from the gate onward — the boundary, the two commands and the resume
40
- verification are `pre-gate-cut.md`, the single source. **The child is told apart from a person, and its
41
- resume stage is handed to it, by a mark the dispatch sets** — `JOSH_LANE_CHILD`, the lane's issue
42
- number (`pre-gate-cut.md` → "The dispatch mark" and "The stage is passed to the resumed child").
43
-
44
- **A lane's review does not inherit the lane, and `pnpm josh review:brief` is what closes that.**
45
- `pnpm josh review:brief` prints the lane's absolute root, branch and HEAD, hands over targets written
46
- `git -C <root> …`, and prints a nonce the review attests with `pnpm josh review:attest <nonce>` from
47
- the checkout it actually read. **The child asks `pnpm josh review:attest --check` before it counts a
48
- round**, and `pnpm josh followup` asks again before it merges; `missing` and `mismatch` are both
49
- refusals. A clean round is the case to check hardest, not the case to skip the check on. Rationale:
50
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why a lane's review needs a brief and an
51
- attestation".
52
-
53
- **A lane's branch is `<N>-lane`, and the issue number leads it so that the commit path accepts it.**
54
- **Never switch the lane to another branch** — a switched lane loses its seat, its listing and its
55
- isolation. So `epic:next` is asked **with** `--lanes`, and everything below runs as written. Rationale:
56
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why the lane branch is `<N>-lane` and never
57
- switched".
58
-
59
- **Report the throughput gain only with its merge-race cost** — every overlap that becomes a conflict
60
- costs a resolution, a re-run gate and a review (`backlogrun-recovery.md` → "Conflicts are not predicted"). Rationale:
61
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why lanes cost as well as buy throughput".
26
+ `pnpm josh epic:next <E> --repo <owner/repo> --lanes` answers **one issue number per line**, up to the
27
+ free lanes. Each child runs in a **lane**: a linked work tree with its own branch, `.env` and ports
28
+ (`docs/josh-commands-run.md` → "`josh lane:open` / `josh lane:close` / `josh lane:list` / `josh
29
+ lane:prune`"). **Implementation, the verification gate and the review run in parallel; the merges
30
+ stay serial.**
31
+
32
+ **A lane child may cut its own turn before the gate** — `pre-gate-cut.md`, the single source. The
33
+ child is told apart from a person, and handed its resume stage, by `JOSH_LANE_CHILD`
34
+ (`pre-gate-cut.md` → "The dispatch mark" and "The stage is passed to the resumed child").
35
+
36
+ **A lane's review does not inherit the lane, and `pnpm josh review:brief` is what closes that**: it
37
+ prints the lane's root, branch and HEAD, targets written `git -C <root> …`, and a nonce the review
38
+ attests with `pnpm josh review:attest <nonce>`. **The child asks `pnpm josh review:attest --check`
39
+ before it counts a round**, and `pnpm josh followup` asks again before merging; `missing` and
40
+ `mismatch` are refusals. A clean round is checked hardest.
41
+
42
+ **A lane's branch is `<N>-lane`. Never switch the lane to another branch** — it loses its seat,
43
+ listing and isolation. So `epic:next` is asked **with** `--lanes`.
44
+
45
+ **Report the throughput gain only with its merge-race cost** (`backlogrun-recovery.md` → "Conflicts
46
+ are not predicted").
62
47
 
63
48
  ### Once per repository, before the first lane opens
64
49
 
65
- In the **primary checkout**, in this order, never again per lane: `pnpm josh ms`; `pnpm josh
66
- latest:scope` and the update on `required` (`backlogrun-child.md` → "`josh latest` runs once per
67
- session, not once per child"); `pnpm josh lane:prune`; `pnpm josh run:tidy`.
50
+ In the **primary checkout**, in order, never per lane: `pnpm josh ms`; `pnpm josh latest:scope` and the
51
+ update on `required` (`backlogrun-child.md` → "`josh latest` runs once per session, not once per
52
+ child"); `pnpm josh lane:prune`; `pnpm josh run:tidy`.
68
53
 
69
- **The rewritten lock file reaches a pull request through the first lane.** In the primary checkout,
70
- only if the update rewrote anything, `git stash push -u -m "backlogrun: josh latest before lanes"`, and
71
- record it on that first child's Issue. **The first lane's `pnpm josh lane:launch "$n" --stash
72
- "backlogrun: josh latest before lanes"` pops it by message** — never a positional `stash pop` on the
73
- shared stack. **Under `backlog:drive` the driver passes `--stash`, never you**; the push stays the
74
- parent's, before the driver starts.
54
+ **The rewritten lock file reaches a pull request through the first lane.** Only if the update rewrote
55
+ anything: `git stash push -u -m "backlogrun: josh latest before lanes"` in the primary checkout, and
56
+ record it on the first child's Issue. **The first lane's `pnpm josh lane:launch "$n" --stash
57
+ "backlogrun: josh latest before lanes"` pops it by message** — never a positional `stash pop`. **Under
58
+ `backlog:drive` the driver passes `--stash`, never you**; the push stays the parent's.
75
59
 
76
60
  ### Opening one lane and dispatching its child
77
61
 
78
- **One command opens the lane, prepares it, and dispatches the child — `pnpm josh lane:launch`** (over
79
- `lane:open`, `stash:pop` and `lane:dispatch`, each guard unchanged; rationale:
80
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why `lane:launch` folds the lane steps into one"):
62
+ **One command opens the lane, prepares it, and dispatches the child — `pnpm josh lane:launch`**:
81
63
 
82
64
  ```bash
83
65
  pid=$(pnpm josh lane:launch "$n") || exit 1 # the child's pid on stdout, nothing else
@@ -85,98 +67,77 @@ pid=$(pnpm josh lane:launch "$n") || exit 1 # the child's pid on stdout, nothi
85
67
 
86
68
  | It answers | What the run does |
87
69
  | --- | --- |
88
- | a pid | The child runs; poll it |
70
+ | a pid | The child runs; wait on it with `lane:await` |
89
71
  | empty, non-zero, `full` | No free lane; wait for one |
90
72
  | empty, non-zero, `already-open` or a failed install | **Park that child and name `pnpm josh lane:close <N>`** — a lock the lane cannot build is a person's to fix |
91
73
  | `lane:open` reports a reused `<N>-lane` on stderr | The way back to a child parked after it pushed — **a reused branch is not a fresh lane** |
92
74
 
93
- **Nothing switches the lane's branch.** In a lane `lane:open`'s answer replaces `pnpm josh run:hold`'s
94
- preflight, and the child claims `run:hold` inside the lane, keyed on its own git directory.
75
+ **Nothing switches the lane's branch.** In a lane, `lane:open`'s answer replaces `pnpm josh
76
+ run:hold`'s preflight; the child claims `run:hold` inside the lane.
95
77
 
96
78
  ### Handing the child over
97
79
 
98
- The child runs as `fullrun #<N>` in that lane, and neither `josh latest` nor a progress watcher is
99
- started there. Everything else — the plan, the gate, `/code-review`, `pnpm josh git`,
100
- `pnpm josh followup` — is unchanged, and `pnpm josh followup` releases that lane's hold at the merge.
101
-
102
- **The child is started as a process of its own, not as a subagent of this session** — `lane:launch`'s
103
- final step, the `lane:dispatch` it runs after the lane is opened and prepared, whose pid it returns.
104
- The bullets below describe that dispatch:
105
-
106
- - **It records where the child writes as it starts it** — the dispatch's own
107
- `<temp>/josh-lane-dispatch-<N>.log`.
108
- - **A refusal is an empty capture beside a non-zero exit**, and every refusal also sends a `warning`
109
- Telegram — no lane open, a path that could not be recorded, a launch that failed. **Park that child
110
- and name the log the message carries**; do not re-dispatch into the same lane without reading it.
111
- - **A child that started with nowhere to write exits zero and warns.** The launcher starts the session
112
- even when it could not open the log, so the child really is running. **Poll that lane on the process
113
- trace alone**, because its log will never grow.
114
- - **The child is started as `fullrun #<N>` with the lane as its working directory.** The batch a
115
- person approved by typing `backlogrun` covers the child.
116
- - **It passes `--permission-mode bypassPermissions`, never `--dangerously-skip-permissions`.** A
117
- current Claude Code ignores the mode `.claude/settings.json` declares, and a new lane worktree is
118
- never a trusted workspace; that file's `deny` list still refuses what it names, so the run reports
119
- what stopped rather than loosening it.
120
-
121
- **Start each child without blocking on it, and poll them all** — a silent one is
122
- `backlogrun-recovery.md` → "A delegated unit that stopped without reporting", read in that child's
123
- lane.
124
-
125
- **`pnpm josh ms` is the parent's now, not the child's.** No lane can switch to the
126
- default branch, so the refresh moves to the primary checkout **before each `lane:open`** — the ref the
127
- lane is cut from.
80
+ The child runs as `fullrun #<N>` in that lane, with neither `josh latest` nor a progress watcher.
81
+ Everything else is unchanged; `pnpm josh followup` releases the lane's hold at the merge.
82
+
83
+ **The child is started as a process of its own, not as a subagent of this session** (`lane:dispatch`,
84
+ `lane:launch`'s final step):
85
+
86
+ - **It records where the child writes** — `<temp>/josh-lane-dispatch-<N>.log`.
87
+ - **A refusal is an empty capture beside a non-zero exit**, with a `warning` Telegram. **Park that
88
+ child and name the log the message carries**; never re-dispatch into the same lane without reading it.
89
+ - **A child that started with nowhere to write exits zero and warns** — **wait on that lane with
90
+ `lane:await`, which reads the process trace alone**.
91
+ - **The child is started as `fullrun #<N>` with the lane as its working directory**; the typed
92
+ `backlogrun` covers it.
93
+ - **It passes `--permission-mode bypassPermissions`, never `--dangerously-skip-permissions`.**
94
+ `.claude/settings.json`'s `deny` list still refuses what it names; report what stopped, never loosen it.
95
+
96
+ **Start each child without blocking on it, then wait on `backlog:drive` or `lane:await`**
97
+ (`scripts/run/run-poll-hook.ts`) — a silent one is
98
+ `backlogrun-recovery.md` → "A delegated unit that stopped without reporting", read in that child's lane.
99
+
100
+ **`pnpm josh ms` is the parent's now, not the child's** — run it in the primary checkout **before
101
+ each `lane:open`**.
128
102
 
129
103
  ### Conflicts are not predicted
130
104
 
131
105
  **A child whose pull request conflicts with `main` resolves it in its own lane rather than stopping** —
132
- read `backlogrun-recovery.md` → "Conflicts are not predicted" when `pnpm josh followup` reports the
133
- conflict.
106
+ read `backlogrun-recovery.md` → "Conflicts are not predicted" when `pnpm josh followup` reports it.
134
107
 
135
108
  ### What happens to a lane
136
109
 
137
110
  | When | The lane | Why |
138
111
  | --- | --- | --- |
139
- | The child **merged** | `pnpm josh lane:close <N>` | `followup` released the hold and the branch is on `main`; nothing in that tree is wanted |
140
- | The child was **parked before its commit** | **Left open**, its uncommitted work in place, its directory and held seat recorded on the Issue | The stash stack is shared by every work tree, so a parallel lane can pop another's entry — the tree itself is the safe place for the work. `lane:close` is a **forced** removal that would take it. `pnpm josh lane:launch <N>` dispatches the released child into the kept lane rather than refusing it as `already-open` — only a lane a child was already dispatched into; a failed-install lane is still refused |
141
- | The child was **parked after its commit and push** | **Left open**, its directory and held seat recorded on the Issue | The tree is clean because committed. What `lane:close` would take is the **local branch**, which is the resume path |
142
- | The child hit a **merge conflict** | **Left open** — the resolution happens in it | The child resolves in place (`backlogrun-recovery.md` → "Conflicts are not predicted"). A park under that section's four conditions takes the row above |
143
- | The child stopped on **`needs-human-review`** | **Left open and untouched** | The uncommitted work *is* the artifact a person has to look at. Name the lane directory in the stop report and in the Telegram |
144
- | The child **failed** | Whichever of the two parked rows applies, plus the consecutive-failure count | Same reasoning; only the counter differs. **A merge conflict is not this row** — it takes the row above, and it is not counted |
145
- | **`lane:open` failed on the install** | `pnpm josh lane:close <N>`, then park the child | A lane exists that no `pnpm josh …` runs in and the next `lane:open` answers `already-open`. Closing frees the seat; parking is right because the cause is one a person fixes. Carry pnpm's reason into the park note |
146
- | The lane is **spent** — no child working in it, its Issue closed, not one this run launched and has not collected with `run:merge`, a clean tree, no commit that is on no remote | Nothing to do — `pnpm josh lane:prune` closes it | Nothing in it is wanted, so no one has to type the close. Any other lane is kept and `lane:prune` says why on standard error |
147
- | The run was **interrupted** | Nothing to do — the work tree survives on disk | The next session's `pnpm josh lane:prune` closes what git no longer has a tree for. **Park that child**, naming the lane and `pnpm josh lane:close <N>` as the way out |
148
-
149
- **A lane closed after a push is reopened by `pnpm josh lane:open <N>`**, which attaches to a local
150
- `<N>-lane` or creates one from `origin/<N>-lane`, saying on standard error which it reused. **The branch
151
- still has to have reached the remote for that to hold** — a child parked before its commit has nothing
152
- on `origin`, which is why that row keeps its lane open rather than closing it. Rationale:
153
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why a committed child's lane is kept".
112
+ | The child **merged** | `pnpm josh lane:close <N>` | Nothing in that tree is wanted |
113
+ | The child was **parked before its commit** | **Left open**, its uncommitted work in place, its directory and held seat recorded on the Issue | The shared stash stack is unsafe; `lane:close` is a **forced** removal. `pnpm josh lane:launch <N>` re-dispatches into the kept lane (a failed-install lane is still refused) |
114
+ | The child was **parked after its commit and push** | **Left open**, its directory and held seat recorded on the Issue | `lane:close` would take the **local branch**, the resume path |
115
+ | The child hit a **merge conflict** | **Left open** — the resolution happens in it | `backlogrun-recovery.md` → "Conflicts are not predicted"; a park there takes the row above |
116
+ | The child stopped on **`needs-human-review`** | **Left open and untouched** | The uncommitted work is what a person looks at. Name the lane directory in the stop report and Telegram |
117
+ | The child **failed** | Whichever of the two parked rows applies, plus the consecutive-failure count | **A merge conflict is not this row**, and is not counted |
118
+ | **`lane:open` failed on the install** | `pnpm josh lane:close <N>`, then park the child | Frees the seat; a person fixes the cause. Carry pnpm's reason into the park note |
119
+ | The lane is **spent** — no child working in it, its Issue closed, not one this run launched and has not collected with `run:merge`, a clean tree, no commit that is on no remote | Nothing to do — `pnpm josh lane:prune` closes it | Any other lane is kept, with the reason on standard error |
120
+ | The run was **interrupted** | Nothing to do — the work tree survives on disk | **Park that child**, naming the lane and `pnpm josh lane:close <N>` |
121
+
122
+ **A lane closed after a push is reopened by `pnpm josh lane:open <N>`** (a local `<N>-lane`, or one
123
+ from `origin/<N>-lane`). A child parked before its commit has nothing on `origin`, so its lane stays open.
154
124
 
155
125
  **Which row a child takes is decided by what `followup` printed, not by reading the situation.** **What
156
- it prints is `PR checks failed (merge conflict)`** — that string is what reaches you;
157
- `mergeStateStatus: DIRTY` is the internal spelling `git-pr-checks-eval.ts` compares against, never an
158
- output line to search for. That string sends the child to resolve the conflict in the lane it is
159
- standing in. Do not grep the output for `mergeable_state`: that is the REST field name, normalized away
160
- before anything prints it.
126
+ it prints is `PR checks failed (merge conflict)`** — resolve in the lane. Never search for
127
+ `mergeStateStatus: DIRTY` or `mergeable_state`; neither is printed.
161
128
 
162
129
  **A kept lane holds its seat. Say it in the park comment**: the lane directory, that its seat is held,
163
- and `pnpm josh lane:close <N>` as the way to give it back.
130
+ and `pnpm josh lane:close <N>` to give it back.
164
131
 
165
- **Release the hold on either parked arm, and leave the lane before closing it.** `pnpm josh followup`
166
- releases the working-tree hold at the **merge**, so a parked child's is still held: run
167
- `pnpm josh run:release <N>` in the lane — **a release names the run it belongs to**, and the child's own
168
- number is what that record carries. **A `needs-human-review` stop is not a park and keeps its hold.**
169
- `lane:close` does not release the hold for you — the record is keyed to the work tree's git directory,
170
- so removing the tree strands it. And `cd` out of the lane **before** `pnpm josh lane:close <N>`: the
171
- close removes the directory the shell is sitting in.
132
+ **Release the hold on either parked arm, and leave the lane before closing it**: `pnpm josh
133
+ run:release <N>` in the lane (**a release names the run it belongs to**); `lane:close` does not
134
+ release it. `cd` out of the lane **before** `pnpm josh lane:close <N>`. **A `needs-human-review` stop is
135
+ not a park and keeps its hold.**
172
136
 
173
- **A `needs-human-review` stop ends the run, and the lanes already in flight are allowed to finish.** No
174
- new lane is opened, and no unit is killed mid-gate. When the others have merged or parked, report and
175
- stop.
137
+ **A `needs-human-review` stop ends the run, and the lanes already in flight are allowed to finish** —
138
+ no new lane opens, no unit is killed mid-gate; then report and stop.
176
139
 
177
140
  ### CI concurrency
178
141
 
179
- **`JOSH_LANE_LIMIT` lowers the ceiling with no code** when CI jobs start to queue. Whether queueing
180
- bites is read from the multi-day backlog timing report — a `checks-wait` that grows with the lane count
181
- is the queueing. Rationale: `docs/maintainers/backlogrun-lanes-rationale.md` → "Why CI concurrency is
182
- capped by the lane limit".
142
+ **`JOSH_LANE_LIMIT` lowers the ceiling with no code** when CI jobs queue — a `checks-wait` growing
143
+ with the lane count in the backlog timing report.