@joshuafolkken/kit 1.1387.0 → 1.1453.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 (278) hide show
  1. package/.claude/skills/epic-commands/SKILL.md +1 -1
  2. package/.claude/skills/epic-commands/epic-bundle.md +5 -0
  3. package/.claude/skills/workflow-commands/backlogrun-lanes.md +5 -3
  4. package/.claude/skills/workflow-commands/backlogrun-park.md +2 -0
  5. package/.claude/skills/workflow-commands/backlogrun-steps.md +13 -10
  6. package/.claude/skills/workflow-commands/backlogrun.md +3 -2
  7. package/.claude/skills/workflow-commands/chain-rule.md +4 -2
  8. package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
  9. package/.claude/skills/workflow-commands/halfrun.md +1 -1
  10. package/.claude/skills/workflow-commands/issue-comments.md +6 -0
  11. package/.claude/skills/workflow-commands/kickoff.md +12 -13
  12. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  13. package/.claude/skills/workflow-commands/observation-ledger.md +3 -2
  14. package/.claude/skills/workflow-commands/pre-gate-cut.md +5 -3
  15. package/.claude/skills/workflow-commands/prerequisite.md +6 -0
  16. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  17. package/.claude/skills/workflow-commands/split-assessment.md +2 -2
  18. package/README.md +27 -4
  19. package/dist/hooks/audit-provision.js +2 -2
  20. package/dist/hooks/batch-guard.js +7 -7
  21. package/dist/hooks/{chunk-2YSW3CXH.js → chunk-3C4XRYG6.js} +35 -11
  22. package/dist/hooks/{chunk-GJ7JPIHN.js → chunk-5C7L6FRC.js} +2704 -190
  23. package/dist/hooks/{chunk-FZ6FUSBM.js → chunk-723HKZO5.js} +1 -1
  24. package/dist/hooks/{chunk-STDSEPWU.js → chunk-D3NJXN5M.js} +4 -4
  25. package/dist/hooks/{chunk-NEC4AT4Z.js → chunk-DGT54IH5.js} +4 -0
  26. package/dist/hooks/{chunk-LMWBRJIP.js → chunk-EF5GQ6WS.js} +3 -3
  27. package/dist/hooks/{chunk-JBBMAPC4.js → chunk-IX6TTTI6.js} +4 -0
  28. package/dist/hooks/{chunk-IYVOLN6A.js → chunk-LBFYEOXJ.js} +3 -3
  29. package/dist/hooks/{chunk-SL4GQ2XP.js → chunk-MBJYQPEK.js} +106 -23
  30. package/dist/hooks/{chunk-WNFJLBXI.js → chunk-NO4AALP5.js} +3 -3
  31. package/dist/hooks/{chunk-J3KSS7II.js → chunk-OLMO72ON.js} +1 -1
  32. package/dist/hooks/{chunk-DCY2GWHC.js → chunk-SHYUQOIS.js} +5 -5
  33. package/dist/hooks/{chunk-EAQEGME7.js → chunk-UT7YC3N2.js} +1 -1
  34. package/dist/hooks/{chunk-EBSHN25W.js → chunk-W5ZKGTSY.js} +4 -4
  35. package/dist/hooks/{chunk-GNDJ7NJ7.js → chunk-Y3GKIKGW.js} +209 -56
  36. package/dist/hooks/{chunk-U32VSRNG.js → chunk-Z4XI7CZS.js} +89 -34
  37. package/dist/hooks/codex-hook-adapter.js +15 -15
  38. package/dist/hooks/duplicate-read-guard.js +8 -8
  39. package/dist/hooks/format-edited.js +5 -5
  40. package/dist/hooks/inputs.json +261 -201
  41. package/dist/hooks/investigation-guard.js +8 -8
  42. package/dist/hooks/pretool-guard.js +14 -14
  43. package/dist/hooks/session-lang.js +69 -16
  44. package/dist/hooks/stop-guard.js +13 -38
  45. package/dist/josh.js +95 -19
  46. package/package.json +4 -3
  47. package/prompts/collaboration-workflow/issue-template.md +10 -8
  48. package/prompts/review.md +30 -4
  49. package/scripts/agent/claude-agent-argv.ts +13 -1
  50. package/scripts/auth/auth-setup-cli.ts +101 -0
  51. package/scripts/auth/claude-token-output.ts +78 -0
  52. package/scripts/auth/claude-token.ts +68 -0
  53. package/scripts/auto-ok/auto-ok-judge-cli.ts +125 -0
  54. package/scripts/auto-ok/auto-ok-judge-read.ts +95 -0
  55. package/scripts/auto-ok/auto-ok-judge-write.ts +109 -0
  56. package/scripts/auto-ok/auto-ok-judge.ts +67 -0
  57. package/scripts/backlog/backlog-drive-cli.ts +14 -0
  58. package/scripts/backlog/backlog-drive-epic.ts +24 -8
  59. package/scripts/backlog/backlog-drive-launch.ts +3 -0
  60. package/scripts/backlog/backlog-drive-named-offer.ts +7 -2
  61. package/scripts/backlog/backlog-drive-named.ts +4 -2
  62. package/scripts/backlog/backlog-drive-unread.ts +56 -0
  63. package/scripts/backlog/backlog-drive.ts +38 -11
  64. package/scripts/backlog/backlog-overlap.ts +22 -5
  65. package/scripts/backlog/backlog-ready.ts +1 -3
  66. package/scripts/backlog/backlogrun-args.ts +13 -2
  67. package/scripts/backlog/backlogrun-cli.ts +91 -19
  68. package/scripts/backlog/backlogrun-launch.ts +24 -0
  69. package/scripts/backlog/backlogrun-replace.ts +166 -0
  70. package/scripts/backlog/backlogrun-stop.ts +178 -0
  71. package/scripts/behavior/behavior-cli.ts +6 -1
  72. package/scripts/doctor/doctor-io.ts +60 -9
  73. package/scripts/doctor/doctor.ts +20 -1
  74. package/scripts/document/document-byte-budget.ts +3 -3
  75. package/scripts/epic/epic-bundle-cli.ts +8 -8
  76. package/scripts/epic/epic-bundle-referenced.ts +2 -5
  77. package/scripts/epic/epic-bundle.ts +39 -4
  78. package/scripts/exports/unused-members-cli.ts +2 -1
  79. package/scripts/followup/followup-checks-event.ts +82 -0
  80. package/scripts/followup/git-followup-finish.ts +16 -2
  81. package/scripts/followup/git-followup-workflow.ts +5 -2
  82. package/scripts/followup/git-pr-followup-checks.ts +18 -4
  83. package/scripts/followup/git-pr-followup-wrapup.ts +5 -0
  84. package/scripts/followup/git-pr-followup.ts +4 -1
  85. package/scripts/fresh-machine/fresh-machine-cli.ts +204 -0
  86. package/scripts/fresh-machine/fresh-machine-docker.ts +65 -0
  87. package/scripts/fresh-machine/fresh-machine-image.ts +62 -0
  88. package/scripts/fresh-machine/fresh-machine-log.ts +61 -0
  89. package/scripts/fresh-machine/fresh-machine-patterns.ts +175 -0
  90. package/scripts/fresh-machine/fresh-machine-run.ts +215 -0
  91. package/scripts/fresh-machine/fresh-machine-script.ts +45 -0
  92. package/scripts/fresh-machine/fresh-machine-spec.ts +57 -0
  93. package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +34 -0
  94. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +31 -0
  95. package/scripts/gate/gate-report.ts +70 -15
  96. package/scripts/gate/project-checks.ts +18 -4
  97. package/scripts/gate/scoped-green.ts +2 -1
  98. package/scripts/gate/verification-gate.ts +4 -3
  99. package/scripts/gh/gh-author-association.ts +14 -0
  100. package/scripts/gh/git-gh-conditional.ts +66 -0
  101. package/scripts/gh/git-gh-exec.ts +1 -1
  102. package/scripts/gh/git-gh-issue-read.ts +6 -3
  103. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  104. package/scripts/gh/git-gh-issue-write.ts +5 -1
  105. package/scripts/gh/git-gh-issue.ts +13 -1
  106. package/scripts/gh/git-pr-checks-eval.ts +13 -0
  107. package/scripts/gh/git-pr-checks-parse.ts +8 -1
  108. package/scripts/gh/git-pr-checks-watch.ts +11 -4
  109. package/scripts/gh/git-pr-checks.ts +36 -2
  110. package/scripts/git/git-command.ts +16 -4
  111. package/scripts/git/git-schemas.ts +1 -0
  112. package/scripts/git/git-spawn-sync.ts +1 -1
  113. package/scripts/hooks/pretool-guard.ts +3 -1
  114. package/scripts/init/hook-command-rewrite.ts +31 -0
  115. package/scripts/init/init-actions.ts +7 -4
  116. package/scripts/init/init-ai-copy.ts +34 -11
  117. package/scripts/init/init-basic.ts +9 -4
  118. package/scripts/init/init-bootstrap.ts +6 -2
  119. package/scripts/init/init-dry-run-report.ts +150 -0
  120. package/scripts/init/init-dry-run.ts +189 -0
  121. package/scripts/init/init-install.ts +8 -1
  122. package/scripts/init/init-logic-toolchain.ts +76 -0
  123. package/scripts/init/init-logic.ts +2 -0
  124. package/scripts/init/init.ts +62 -42
  125. package/scripts/init/kit-setup-state.ts +11 -17
  126. package/scripts/init/own-formatter.ts +21 -0
  127. package/scripts/init/project-profile.ts +60 -12
  128. package/scripts/init/start-dry-run.ts +70 -0
  129. package/scripts/init/start-exec.ts +27 -1
  130. package/scripts/init/start-plan.ts +23 -3
  131. package/scripts/init/start-setup-pr.ts +13 -24
  132. package/scripts/init/start-steps.ts +62 -1
  133. package/scripts/init/start.ts +38 -17
  134. package/scripts/init/workflow-mark.ts +35 -0
  135. package/scripts/init/working-tree.ts +116 -0
  136. package/scripts/issue/issue-ack-cli.ts +84 -0
  137. package/scripts/issue/issue-auto-ok.ts +68 -99
  138. package/scripts/issue/issue-file-cli.ts +17 -17
  139. package/scripts/issue/issue-file.ts +1 -6
  140. package/scripts/issue/issue-labels.ts +46 -10
  141. package/scripts/issue/issue-release-cli.ts +69 -23
  142. package/scripts/issue/issue-release.ts +3 -1
  143. package/scripts/issue/issue-state-cli.ts +14 -4
  144. package/scripts/issue/issue-watch-diff.ts +152 -0
  145. package/scripts/issue/issue-watch-gate.ts +81 -0
  146. package/scripts/issue/issue-watch-hook.ts +54 -0
  147. package/scripts/issue/issue-watch.ts +240 -0
  148. package/scripts/issue/measure-rerun-cli.ts +3 -4
  149. package/scripts/josh/josh-command-map.ts +4 -0
  150. package/scripts/josh/josh-commands-ai.ts +11 -0
  151. package/scripts/josh/josh-commands-backlog.ts +2 -2
  152. package/scripts/josh/josh-commands-development.ts +1 -1
  153. package/scripts/josh/josh-commands-issue.ts +10 -3
  154. package/scripts/josh/josh-commands-lane.ts +11 -2
  155. package/scripts/josh/josh-commands-project.ts +26 -2
  156. package/scripts/josh/josh-verdict.ts +33 -4
  157. package/scripts/josh/process-identity.ts +32 -6
  158. package/scripts/lane/claude-lane-broker.ts +142 -0
  159. package/scripts/lane/lane-await.ts +6 -2
  160. package/scripts/lane/lane-broker-server.ts +69 -0
  161. package/scripts/lane/lane-cache.ts +37 -7
  162. package/scripts/lane/lane-capacity.ts +8 -6
  163. package/scripts/lane/lane-child-invocation.ts +1 -0
  164. package/scripts/lane/lane-cli.ts +15 -1
  165. package/scripts/lane/lane-close.ts +15 -6
  166. package/scripts/lane/lane-dispatch.ts +36 -10
  167. package/scripts/lane/lane-environment.ts +1 -1
  168. package/scripts/lane/lane-launch-cli.ts +13 -4
  169. package/scripts/lane/lane-ledger.ts +21 -3
  170. package/scripts/lane/lane-measure-cli.ts +10 -2
  171. package/scripts/lane/lane-open.ts +9 -1
  172. package/scripts/lane/lane-preserve.ts +49 -0
  173. package/scripts/lane/lane-reap.ts +20 -5
  174. package/scripts/lane/lane-registry.ts +6 -0
  175. package/scripts/lane/lane-restart-cli.ts +51 -0
  176. package/scripts/lane/lane-restart.ts +175 -0
  177. package/scripts/lane/lane-session-broker.ts +363 -0
  178. package/scripts/lane/lane-spent.ts +195 -0
  179. package/scripts/lane/lane-stage-stats.ts +27 -3
  180. package/scripts/lane/lane-stop-stats.ts +96 -0
  181. package/scripts/lane/openai-lane-supervisor.ts +2 -2
  182. package/scripts/lane/process-tools.ts +31 -0
  183. package/scripts/lib/buffered-process.ts +36 -2
  184. package/scripts/lib/pnpm-reach.ts +27 -0
  185. package/scripts/lib/status-icons.ts +5 -1
  186. package/scripts/lint/lint-parallel.ts +19 -2
  187. package/scripts/observations/observation-ledger-home.ts +1 -0
  188. package/scripts/observations/observation-ledger-migrate.ts +3 -15
  189. package/scripts/release/release-issue-close.ts +133 -0
  190. package/scripts/release/release-publish.ts +12 -1
  191. package/scripts/repo/repository-labels.ts +11 -1
  192. package/scripts/review/comment-ranges.ts +199 -0
  193. package/scripts/review/review-attest-cli.ts +21 -6
  194. package/scripts/review/review-brief-cli.ts +24 -7
  195. package/scripts/review/review-code-tree.ts +119 -0
  196. package/scripts/review/review-comment-round.ts +114 -0
  197. package/scripts/review/review-record-cli.ts +39 -17
  198. package/scripts/review/review-round2-cli.ts +16 -5
  199. package/scripts/review/review-round2.ts +30 -10
  200. package/scripts/review/review-stamps.ts +22 -1
  201. package/scripts/rules/implementation-cut.ts +3 -3
  202. package/scripts/rules/pre-gate-cut.ts +1 -1
  203. package/scripts/run/board/run-board-checks.ts +42 -0
  204. package/scripts/run/board/run-board-cli.ts +2 -0
  205. package/scripts/run/board/run-board-every.ts +3 -1
  206. package/scripts/run/board/run-board-fit.ts +16 -5
  207. package/scripts/run/board/run-board-fresh.ts +64 -0
  208. package/scripts/run/board/run-board-header.ts +129 -53
  209. package/scripts/run/board/run-board-labels.ts +47 -4
  210. package/scripts/run/board/run-board-lane-event.ts +66 -0
  211. package/scripts/run/board/run-board-layout.ts +57 -9
  212. package/scripts/run/board/run-board-now.ts +234 -0
  213. package/scripts/run/board/run-board-operation-read.ts +75 -0
  214. package/scripts/run/board/run-board-operation.ts +150 -0
  215. package/scripts/run/board/run-board-phase.ts +26 -1
  216. package/scripts/run/board/run-board-plan.ts +4 -6
  217. package/scripts/run/board/run-board-read.ts +49 -3
  218. package/scripts/run/board/run-board-reason.ts +124 -0
  219. package/scripts/run/board/run-board-render-checks.ts +55 -0
  220. package/scripts/run/board/run-board-render-legend.ts +12 -3
  221. package/scripts/run/board/run-board-render-slot.ts +2 -2
  222. package/scripts/run/board/run-board-render-tail.ts +128 -0
  223. package/scripts/run/board/run-board-render-thanks.ts +50 -0
  224. package/scripts/run/board/run-board-render-title.ts +58 -0
  225. package/scripts/run/board/run-board-render.ts +96 -80
  226. package/scripts/run/board/run-board-row-yield.ts +32 -0
  227. package/scripts/run/board/run-board-setup.ts +61 -13
  228. package/scripts/run/board/run-board-state.ts +10 -0
  229. package/scripts/run/board/run-board-status.ts +66 -7
  230. package/scripts/run/board/run-board-thanks-csv.ts +71 -0
  231. package/scripts/run/board/run-board-thanks-read.ts +112 -0
  232. package/scripts/run/board/run-board-thanks.ts +53 -0
  233. package/scripts/run/board/run-board-tick.ts +50 -21
  234. package/scripts/run/board/run-board-usual.ts +44 -0
  235. package/scripts/run/carry/run-carry-args.ts +9 -1
  236. package/scripts/run/carry/run-carry-cli.ts +2 -45
  237. package/scripts/run/carry/run-carry-end.ts +73 -0
  238. package/scripts/run/carry/run-carry.ts +8 -1
  239. package/scripts/run/entry/run-entry-cli.ts +5 -0
  240. package/scripts/run/event/run-event-checks.ts +54 -0
  241. package/scripts/run/event/run-event-render.ts +2 -0
  242. package/scripts/run/event/run-event-scope.ts +1 -0
  243. package/scripts/run/event/run-event-setup.ts +55 -11
  244. package/scripts/run/event/run-event-stream.ts +27 -11
  245. package/scripts/run/merge/run-merge-cli.ts +7 -4
  246. package/scripts/run/merge/run-merge-ship.ts +61 -0
  247. package/scripts/run/merge/run-merge-steps.ts +7 -14
  248. package/scripts/run/merge/run-merge-token.ts +16 -2
  249. package/scripts/run/run-headless.ts +1 -0
  250. package/scripts/run/run-step.ts +2 -0
  251. package/scripts/run/ship/run-ship-cli.ts +22 -2
  252. package/scripts/run/ship/run-ship-return.ts +31 -13
  253. package/scripts/run/ship/run-ship-review-steps.ts +17 -4
  254. package/scripts/run/ship/run-ship-stage.ts +1 -0
  255. package/scripts/run/wake/run-wake-await.ts +130 -0
  256. package/scripts/run/wake/run-wake-cli.ts +60 -71
  257. package/scripts/run/wake/run-wake-describe.ts +34 -2
  258. package/scripts/run/wake/run-wake-driver.ts +11 -4
  259. package/scripts/run/wake/run-wake-session.ts +20 -3
  260. package/scripts/run/wake/run-wake-stop.ts +37 -0
  261. package/scripts/run/wake/run-wake-supervise.ts +44 -0
  262. package/scripts/sync/claude-settings-merge.ts +144 -0
  263. package/scripts/sync/sync-ai-files.ts +28 -3
  264. package/scripts/sync/sync.ts +15 -0
  265. package/scripts/test/project-test-script.ts +73 -0
  266. package/scripts/test/skip-marker.ts +14 -1
  267. package/scripts/test/test-related.ts +3 -2
  268. package/scripts/test/test-unit-guard.ts +78 -14
  269. package/scripts/time-runtime/time-reported-failure.ts +11 -3
  270. package/scripts/uninstall/distributed-files.ts +92 -0
  271. package/scripts/uninstall/uninstall-plan.ts +119 -0
  272. package/scripts/uninstall/uninstall-report.ts +61 -0
  273. package/scripts/uninstall/uninstall.ts +206 -0
  274. package/templates/AGENTS.basic.md +4 -0
  275. package/templates/GEMINI.basic.md +6 -0
  276. package/dist/hooks/chunk-6V5OPIUU.js +0 -13
  277. package/scripts/lane/openai-review-broker.ts +0 -262
  278. package/scripts/run/board/run-board-track.ts +0 -22
@@ -150,7 +150,7 @@ worked form.
150
150
 
151
151
  **An `in-progress` issue occupies a lane rather than the whole repository.** The occupancy is counted
152
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 6**) is what gets offered. At zero the answer is `wait`
153
+ what is left of `JOSH_LANE_LIMIT` (**default 4**) is what gets offered. At zero the answer is `wait`
154
154
  and the holders are named on standard error. A parked child releases its lane; one stopped by
155
155
  `needs-human-review` goes on holding one, because its uncommitted work is still in that checkout.
156
156
 
@@ -9,6 +9,11 @@ settle. `Nothing to bundle.` needs neither.
9
9
  already recorded between them. **A similar title never counts on its own** — "related" expands
10
10
  without limit, and the threshold is what keeps an unrelated issue out.
11
11
 
12
+ **The release issue is neither a candidate nor a subject**, like an epic. `issue:file --release` records
13
+ every change awaiting publication as its blocker, so that relation is mechanical, not a sign of shared
14
+ work. Counted as a signal, it would put the release and an unrelated change in one epic. A
15
+ `blocked-by` or a prose reference between any other two issues still counts.
16
+
12
17
  **The search is not limited to the open backlog.** Every issue number the subject's body names is read
13
18
  on its own, whatever its state. A **closed** reference counts only when an open epic already tracks
14
19
  it, since the answer worth recovering is `add_to_epic`; an epic created over a closed issue has
@@ -113,9 +113,10 @@ The bullets below describe that dispatch:
113
113
  trace alone**, because its log will never grow.
114
114
  - **The child is started as `fullrun #<N>` with the lane as its working directory.** The batch a
115
115
  person approved by typing `backlogrun` covers the child.
116
- - **It does not pass `--dangerously-skip-permissions`.** What the child may do is the checkout's own
117
- `.claude/settings.json` to decide; a headless child reaches `gh` and merges through `pnpm josh
118
- followup` without the flag, and the run reports what stopped rather than loosening it.
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.
119
120
 
120
121
  **Start each child without blocking on it, and poll them all** — a silent one is
121
122
  `backlogrun-recovery.md` → "A delegated unit that stopped without reporting", read in that child's
@@ -142,6 +143,7 @@ conflict.
142
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 |
143
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 |
144
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 |
145
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 |
146
148
 
147
149
  **A lane closed after a push is reopened by `pnpm josh lane:open <N>`**, which attaches to a local
@@ -103,6 +103,8 @@ It never carries:
103
103
 
104
104
  - a choice with a clearly better default — that is Tier A: decide it and record it as an Issue comment;
105
105
  - whether to run something already planned and opted in with `auto-ok` — the opt-in is that decision;
106
+ - a wait for the next published release — a dependency, `pnpm josh issue:release <N> --wait`
107
+ (`prerequisite.md`);
106
108
  - a defect in the running repository's own run tooling — the run fixes it and resumes
107
109
  (`prompts/collaboration-workflow/upstream-interrupt.md` → "実行中のリポジトリ自身のラン機構の不具合").
108
110
 
@@ -12,12 +12,12 @@ runs is stated by the keyword and its arguments, never inferred from a request's
12
12
  that would bound this the other way are prohibited** — dropping a run's own filings, and requiring a
13
13
  person's `auto-ok` on a child; the brake below bounds it. A Tier C action inside a child still stops that child.
14
14
 
15
- **`pnpm josh issue:file` decides the `auto-ok` default and prints it** — `auto-ok: applied` or
16
- `auto-ok: not applied` with the reason; `scripts/issue/issue-auto-ok.ts` is the single source. **Pass
17
- `--no-auto-ok` only when the new issue needs a person's judgement** — a Tier B toss-up or a Tier C
18
- action inside it. The retrospective's filings take the same default and count against the same brake.
19
- **A filing a person asked for declares `--requested` and takes no default** — `auto-ok` only when they
20
- named it (`kickoff.md` → "Words typed after `new`").
15
+ **`pnpm josh issue:file` judges `auto-ok` and prints it** — `auto-ok: applied` or
16
+ `auto-ok: not applied` with the reason; `scripts/issue/issue-auto-ok.ts` is the single source. Every
17
+ filing is judged the same way, whoever asked for it: the excluded labels, then the body's
18
+ `- 人の判断:` declaration (`issue-template.md`). **Declare `- 人の判断: 要` when the new issue needs a
19
+ person's judgement** — a Tier B toss-up or a Tier C action inside it; `--no-auto-ok` withholds it too.
20
+ The retrospective's filings are judged the same way and count against the same brake.
21
21
 
22
22
  Rationale: `docs/maintainers/backlogrun-steps-rationale.md` → "Why the authorization boundary is shaped this way";
23
23
  provenance of each rule: `docs/maintainers/backlogrun-steps-rationale.md` → "Where each rule came from"
@@ -61,7 +61,7 @@ resumed session runs `remaining` from `--json`. The contract is `docs/josh-comma
61
61
  ```bash
62
62
  pnpm josh run:carry --begin "backlogrun --max 5 --idle 30" --owner "$PPID"
63
63
  pnpm josh run:carry --json # read it back in a resumed session
64
- pnpm josh run:wake --start # same turn as --begin
64
+ pnpm josh run:wake --start # same turn as --begin; `running` under `josh backlogrun`
65
65
  ```
66
66
 
67
67
  **Always pass `--owner "$PPID"`**, and ask it before the plan, in the same turn as the first `pnpm josh
@@ -85,7 +85,8 @@ named epic's children", never the root as a standalone `fullrun`, then ask `pnpm
85
85
  a child number or `complete` continues; only `stop` or a failure records `pnpm josh run:carry --done <E>
86
86
  --owner "$PPID"`.
87
87
 
88
- **A person keeps control of the supervisor** — `pnpm josh run:wake --list` / `--stop`.
88
+ **A person keeps control of the run** — `pnpm josh run:wake --list` reads it, `pnpm josh backlogrun
89
+ --stop` stops it (`docs/josh-commands.md` → "`josh backlogrun`").
89
90
 
90
91
  Rationale: `docs/maintainers/backlogrun-steps-rationale.md` → "Why a session cut does not end the run"
91
92
 
@@ -114,7 +115,8 @@ person, Out of scope) to the person in the session language, with any truncated-
114
115
  the loop, leaving whatever is still labelled parked.
115
116
 
116
117
  **`needs-decision`, `run:solo`, `run:lane` and `priority:high` are the only workflow labels a run
117
- applies by hand** — never `auto-ok` or `needs-human-review` (`needs-human-review.md`).
118
+ applies by hand** — never `needs-human-review` (`needs-human-review.md`), and `auto-ok` only through
119
+ `pnpm josh issue:file` or `pnpm josh auto-ok:judge`, which check the exclusions first.
118
120
 
119
121
  Rationale: `docs/maintainers/backlogrun-steps-rationale.md` → "Why the plan and the decision pass come first"
120
122
 
@@ -129,7 +131,8 @@ section the row names:
129
131
  | Handed back | What the session does | Read |
130
132
  | --- | --- | --- |
131
133
  | `triage` | Label each issue stderr names `run:solo` or `run:lane` (`blocked-by` where one must land first) | "Resolve what the plan can resolve, before starting" above |
132
- | `offer` | Report what stderr printed; **never pick an issue by hand** | — |
134
+ | `judge` | For each number `pnpm josh auto-ok:judge` prints, read the issue (`pnpm josh issue:read <N>`) and answer `--apply <N> --lane\|--solo` or `--decline <N> --reason "<why>"` | `docs/josh-commands-backlog.md` → "`josh auto-ok:judge`" |
135
+ | `offer` | Report what stderr printed — a failed offer, or a named issue whose state stayed unreadable; **never pick an issue by hand** | — |
133
136
  | `launch #N` | Read the lane's log and park `#N` | `backlogrun-park.md` → "park and continue" |
134
137
  | `merge [<token>] #N` | `environment` ends the run; the others re-read the child | `backlogrun-progress.md` → "Running a named epic's children" |
135
138
  | `epic #N` | A named epic's turn | "The session cut is inside the invocation" above |
@@ -35,7 +35,7 @@ is still that one invocation (`backlogrun-steps.md` → "The session cut is insi
35
35
  2. **Begin the carry record before the plan** — `pnpm josh run:carry --begin "<invocation>" --owner
36
36
  "$PPID"` and `pnpm josh run:wake --start`, in the same turn as the first `pnpm josh ms`.
37
37
  3. **What this invocation approves** — the opted-in pool, a run's own filings once bundled, and the
38
- brake that bounds the amount; the route table's row points at the single source of the `auto-ok` default.
38
+ brake that bounds the amount; the route table's row points at the single source of the `auto-ok` rule.
39
39
  4. **Report the plan before the first child** — `pnpm josh backlog:plan`, then resolve every
40
40
  `needs-decision` issue decidable from its body in one pass, recording `blocked-by`, `run:solo` and
41
41
  `run:lane` in the same pass.
@@ -46,6 +46,7 @@ is still that one invocation (`backlogrun-steps.md` → "The session cut is insi
46
46
  session only when it needs judgment.
47
47
  7. **End the record when the run ends** — `run:report`, then `run:carry --end` (or `--end --stopped
48
48
  "<reason>"`) and `run:wake --stop`. An empty plan is not that end; the driver's idle watch decides it.
49
+ A person stops a run from the terminal with `pnpm josh backlogrun --stop`, which makes both calls.
49
50
 
50
51
  ## The route table
51
52
 
@@ -55,7 +56,7 @@ never a whole document (`SKILL.md` → "A section reference is read as a section
55
56
  | The moment | Read |
56
57
  | --- | --- |
57
58
  | The entry: the carry record and its answers | `backlogrun-steps.md` → "The session cut is inside the invocation" |
58
- | What the invocation may merge, and the `auto-ok` default | `backlogrun-steps.md` → "What one invocation approves" |
59
+ | What the invocation may merge, and the `auto-ok` rule | `backlogrun-steps.md` → "What one invocation approves" |
59
60
  | Before the first child: the plan and the decision pass | `backlogrun-steps.md` → "The plan, before the first child starts" |
60
61
  | The driver hands a branch back | `backlogrun-steps.md` → "The loop" |
61
62
  | Once per session | `backlogrun-steps.md` → "What runs once per session, not once per issue" |
@@ -5,7 +5,8 @@
5
5
  This is the execution contract for `fullrun` and `backlogrun`, and for `prrun` up to the pull request: a `prrun` never issues `pnpm josh ship` or a merging `pnpm josh followup` — it opens the pull request with `pnpm josh git -y` and ends by `prrun.md` → "The difference — the end of the run". The record below is reference only.
6
6
  Review results and successful pushes are never turn boundaries.
7
7
 
8
- 0. **A lane child**: `pnpm josh main:merge`, the scoped pair, `pnpm josh ship --detach --review
8
+ 0. **A lane child**: `pnpm josh main:merge`, the self-check (`prompts/review.md` → "Before round 1 —
9
+ the implementer's self-check"), the scoped pair, `pnpm josh ship --detach --review
9
10
  "<title> #<N>"` (`--cite <N>`), then **end the turn** on `launched`/`busy`. A stop relaunches a child
10
11
  whose prompt names `pnpm josh ship --log <N>` and (Anthropic lane) the re-detach to run after
11
12
  the fix — `pnpm josh ship --detach`, `--review` only if the stopped ship carried it and stopped before
@@ -13,7 +14,8 @@ Review results and successful pushes are never turn boundaries.
13
14
  `failed` → step 1. A backgrounded `ship` issued alone is moved to the foreground by the hook
14
15
  rather than refused.
15
16
  1. Run `pnpm josh main:merge`. **Then issue `pnpm josh run:cut <N>` alone, before the scoped pair and
16
- the gate** — the pre-gate cut (a no-op outside a lane). Then run the final scoped lint/test pair and
17
+ the gate** — the pre-gate cut (a no-op outside a lane). Then answer the self-check
18
+ (`prompts/review.md` → "Before round 1 — the implementer's self-check"), run the final scoped lint/test pair and
17
19
  `pnpm josh run:review`: it starts `pnpm josh gate` in the background and prints the `/code-review`
18
20
  brief in one call, so the two overlap. Launch the `/code-review` subagent as the `general-purpose`
19
21
  agent type with that brief (every tool, so `--fix` applies; never a guessed type name).
@@ -45,7 +45,7 @@ primary checkout; a Claude run keeps it.
45
45
  ## The `fullrun new` step list
46
46
 
47
47
  `kickoff new` + `fullrun #N` in one run. Steps: (1) Derive an English title, or use the provided one.
48
- (2) Create Issue: `pnpm josh issue:file "<title>" --body-file <body-file> --depth <n> --requested`,
48
+ (2) Create Issue: `pnpm josh issue:file "<title>" --body-file <body-file> --depth <n>`,
49
49
  with the labels `kickoff.md` → "Words typed after `new`" maps (per
50
50
  `prompts/collaboration-workflow/issue-template.md`) — its duplicate scan runs first, and a candidate
51
51
  that covers the same work stops the run rather than filing a second Issue (`issue-scout.md`). Capture
@@ -42,7 +42,7 @@ back with fixes, treat each as a new round: implement, re-run `pnpm josh gate`,
42
42
 
43
43
  `halfrun new` or `halfrun new "<title>"`: `kickoff new` + `halfrun #<N>` (no Issue exists yet). Steps
44
44
  mirror `fullrun new` (1)–(8): derive an English title (or use the provided one) → create the Issue
45
- (`pnpm josh issue:file "<title>" --body-file <body-file> --depth <n> --requested`, with the labels
45
+ (`pnpm josh issue:file "<title>" --body-file <body-file> --depth <n>`, with the labels
46
46
  `kickoff.md` → "Words typed after `new`" maps, body per
47
47
  `prompts/collaboration-workflow/issue-template.md`; its duplicate scan is read per `issue-scout.md`) → add `in-progress` (as `fullrun new` (3)) → post the agreed plan → stash
48
48
  any pre-existing changes with `git stash push -m "halfrun new: pre-existing changes" -- ':!.josh/observations'`
@@ -91,3 +91,9 @@ never the comment text.
91
91
  **`pnpm josh rule:guard` refuses the body-only read** and hands over the reissue and the conflict rule
92
92
  at the moment they bind (`prompts/collaboration-workflow/rule-delivery.md`). **This file is the rule,
93
93
  not the hook** — a session that runs no hooks still owes the read.
94
+
95
+ ## A person's update mid-run
96
+
97
+ When the hook, `review:attest --check` or `followup` shows an Issue update, read it as above — the
98
+ later text is in force — fix what it changes, then `pnpm josh issue:ack <N>`. The watch and what it
99
+ does not catch: `docs/josh-commands-backlog.md` → "`josh issue:ack`".
@@ -43,8 +43,7 @@ is read on demand when a split is found.
43
43
  - `kickoff new` or `kickoff new "<title>"`: No Issue exists yet. Steps: (0) **Scope assessment** per
44
44
  `split-assessment.md`. If multiple → the **multi-issue split path**; if single → the **single-issue
45
45
  path**. **Single-issue path**: (1) Derive an English title from the conversation, or use the provided
46
- title. (2) Create Issue: `pnpm josh issue:file "<title>" --body-file <body-file> --depth <n>
47
- --requested` plus the labels the words typed after `new` name ("Words typed after `new`", below) (body
46
+ title. (2) Create Issue: `pnpm josh issue:file "<title>" --body-file <body-file> --depth <n>` plus the labels the words typed after `new` name ("Words typed after `new`", below) (body
48
47
  per `prompts/collaboration-workflow/issue-template.md`) — its duplicate scan runs first, and a
49
48
  candidate that covers the same work stops the run rather than filing a second Issue (`SKILL.md` →
50
49
  `issue-scout.md`). Capture `<N>`. (3)
@@ -52,7 +51,7 @@ is read on demand when a split is found.
52
51
  Telegram notification. (5) **Stop** — do not implement. **Multi-issue split path**: (1) For each
53
52
  independent deliverable, derive a focused English title and create a separate Issue with the
54
53
  `route:split` label (its duplicate scan is read per `issue-scout.md`): `pnpm josh issue:file
55
- "<sub-title>" --body-file <body-file> --depth <n> --route split --requested` plus the labels the words typed after `new` name. Capture each Issue number. **When the split is filed into a repository other than
54
+ "<sub-title>" --body-file <body-file> --depth <n> --route split` plus the labels the words typed after `new` name. Capture each Issue number. **When the split is filed into a repository other than
56
55
  the one this session is running in**, every child body gets the `## Origin` backlink described in the
57
56
  cross-package rule the AI documents keep resident, the epic body carries the same link as prose or a
58
57
  plain bullet (never as a checkbox row, which would disable its auto-close), and the originating Issue
@@ -85,15 +84,15 @@ An Issue a consumer can use only once it is published is filed with `--release`
85
84
 
86
85
  ## Words typed after `new`
87
86
 
88
- **An Issue a person asked for is filed with `--requested`** — every `new` entry (each child of its
89
- multi-issue split included), and a request in conversation. A live carry record or an `auto-ok` branch Issue then does not opt it in, so no lane takes
90
- it before the person picks the run; `auto-ok` comes only from the words below (`issue-auto-ok.ts`). A
91
- filing the run decides on its own — observation, retrospective, a split the run finds itself, routed — never declares it.
87
+ **`auto-ok` is judged by `pnpm josh issue:file`, never typed** — by the same criteria as every
88
+ filing: the excluded labels and the body's `- 人の判断:` declaration, and a `不要` declaration also needs a run label
89
+ (`issue-template.md`).
90
+ `auto ok` typed after `new` adds nothing.
92
91
 
93
- **Words after `new`** (`kickoff new auto ok high`) are read like `into <target>`, never inferred. Each
94
- adds its labels to the `--requested` filing; a word not in the table is asked about:
92
+ **Words after `new`** (`kickoff new high`) are read like `into <target>`, never inferred. Each adds its
93
+ labels to the filing; a word not in the table is asked about:
95
94
 
96
- | Typed | Added to `pnpm josh issue:file` |
97
- | --------- | ---------------------------------- |
98
- | `auto ok` | `--label auto-ok --label run:lane` |
99
- | `high` | `--label priority:high` |
95
+ | Typed | Added to `pnpm josh issue:file` |
96
+ | --------- | ------------------------------- |
97
+ | `auto ok` | nothing — `issue:file` judges it |
98
+ | `high` | `--label priority:high` |
@@ -70,7 +70,7 @@ defines, before the create call.
70
70
 
71
71
  - **It is read off the subject, exactly as the table is** — so applying it is not a judgement and not
72
72
  a person's to make, which is what separates it from `auto-ok` and `needs-human-review`. Those two
73
- decide what a run may do (`auto-ok` by `issue:file`'s default for a filing found by opted-in work —
73
+ decide what a run may do (`auto-ok` by `issue:file`'s judgement against the criteria —
74
74
  `backlogrun-steps.md` → "What one invocation approves"); this one records what an Issue is about
75
75
  and withholds nothing.
76
76
  - **Applied at filing, not at completion.**
@@ -106,8 +106,9 @@ could not.
106
106
  and appends nothing. That round reads only, so no commit of the run's follows it; a line in the tree
107
107
  would be pushed onto the open pull request and its CI would start over. `pnpm josh ship --review`
108
108
  does this for a passing round 2. **A round 2 that blocks records in the tree as before** — the fix it
109
- stops for is pushed anyway and carries the lines. The comment's lines are outside the count
110
- `pnpm josh review:findings` and the retrospective read.
109
+ stops for is pushed anyway and carries the lines. Once the Issue is closed, the next round recorded
110
+ to the ledger carries the comment's lines into `<N>-comment-rounds.md` with its own commit, so
111
+ `pnpm josh review:findings` and the retrospective count them (`review-comment-round.ts`).
111
112
  - **`pnpm josh followup` commits any other line appended after the run's commit onto the pull request,
112
113
  before the merge** — the residual path, for an observation recorded between the commit and the
113
114
  merge. After the merge gates and before the CI wait, `followup` reads the tree and, **only when the
@@ -169,9 +169,11 @@ built for the lane child.
169
169
  **The trigger**: `pnpm josh rule:guard` refuses an `Edit` / `Write` in a dispatched lane child whose
170
170
  recent-context cost is over threshold, handing back `pnpm josh run:cut --impl <N> --handoff <path>`.
171
171
  `cut` ends the turn; a fresh process's `run:cut --resume <N>` answers `resume-impl` and continues
172
- implementation — **the implementation resume clears the record**, so the cut may fire again. Outside
173
- a lane, a held run on a measured `over` keeps the hold, sends a `confirmation` Telegram naming
174
- `fullrun #<N>` and ends the turn. The refusal states the rest — **It fires on every threshold crossing,
172
+ implementation — **the implementation resume clears the record**, so the cut may fire again. **A cut
173
+ that relaunches its successor owes no Telegram**, the pre-gate cut as much as this one: nobody has
174
+ anything to act on, and a resume answering `stale` / `busy` sends its own. Outside a lane nothing is
175
+ relaunched, so `run:cut --impl` prints the held run's instruction — on a measured `over` that run
176
+ keeps the hold, sends a `confirmation` Telegram naming `fullrun #<N>` and ends the turn. The refusal states the rest — **It fires on every threshold crossing,
175
177
  not once per run**; **An edit reissued right after a refusal passes**; **An unmeasurable session
176
178
  warrants the cut**; **It is silent between a cut and its resume**. Rationale:
177
179
  `docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose";
@@ -28,6 +28,12 @@ action. `pnpm josh run:merge` enforces the computable half: an unfinished child
28
28
  blocked-by is released to **wait** — no `needs-decision` label, no failure counted — and the backlog
29
29
  offer hands it back once its blockers merge.
30
30
 
31
+ **A wait for the next published release is a dependency too** — never `needs-decision`. Record it
32
+ with `pnpm josh issue:release <M> --wait` (`<M>` blocked by the release Issue, filed when none is
33
+ open), then stash, comment and `pnpm josh run:release <M>` as for a prerequisite below; `fullrun` /
34
+ `halfrun` stop, `backlogrun` continues. Closing the release Issue once a person has published it hands
35
+ `<M>` back to `backlog:next` (`docs/josh-commands-backlog.md` → `josh issue:release`).
36
+
31
37
  **File the prerequisite with the `route:tier-a` label**, so a Tier A filing made during implementation
32
38
  stays countable by filing route afterwards. **This paragraph belongs to the prerequisite row, not to
33
39
  the table** — the label means a filing the run is *blocked by*, so the observation row carries no
@@ -4,7 +4,7 @@
4
4
  not at the entry.** `SKILL.md` → §2's table keeps the rule itself: run what `run:step` prints once,
5
5
  file the improvements worth carrying into the next run, stack the rest, and mark the step done.
6
6
  Everything that decides *how* — what the four sections mean, how the top two are chosen, the
7
- exclusions, and the `auto-ok` default — is here. Read it in full, in the same turn, before filing.
7
+ exclusions, and the `auto-ok` judgement — is here. Read it in full, in the same turn, before filing.
8
8
 
9
9
  **When it fires is not this file's, and not a judgement.** The run driver prints the step the moment the
10
10
  backlog drains — `backlog:offer` marks that drain on the event stream and `run:step` fires the
@@ -56,10 +56,10 @@ Issue, as after any filing.
56
56
 
57
57
  ## `auto-ok`, and closing the step
58
58
 
59
- **What a retrospective files carries `auto-ok`** — it files while the carry record is live, so
60
- `issue:file`'s default applies the label and the next run picks the improvements up without waiting
61
- for a person. **`backlogrun-steps.md` → "What one invocation approves" is that default's single
62
- source**; it is written there, beside the brakes that bound it, rather than restated here. Every brake still counts a retrospective's filings: the
59
+ **What a retrospective files is judged for `auto-ok`** — an improvement that needs no person's
60
+ judgement declares `- 人の判断: 不要`, so `issue:file` applies the label (with the run label `prompts/collaboration-workflow/issue-template.md` requires) and the next run picks it up
61
+ without waiting for a person. **`backlogrun-steps.md` → "What one invocation approves" is that
62
+ judgement's single source**; it is written there, beside the brakes that bound it, rather than restated here. Every brake still counts a retrospective's filings: the
63
63
  ten-per-invocation ceiling, the WIP cap, `--max` and the 150,000-token session budget.
64
64
 
65
65
  **Close with `pnpm josh run:carry --retrospective --summary "<result>" --owner "$PPID"`.** It marks the
@@ -77,8 +77,8 @@ moment that child merges and closes.
77
77
 
78
78
  **Each split child is filed with the `route:split` label** —
79
79
  `pnpm josh issue:file "<sub-title>" --body-file <body-file> --depth <n> --route split` — so the
80
- backlog's composition stays countable by filing route rather than by grepping issue bodies. A split of
81
- a person's `kickoff new` also takes `--requested` (`kickoff.md` → "Words typed after `new`").
80
+ backlog's composition stays countable by filing route rather than by grepping issue bodies. Each child
81
+ is judged for `auto-ok` like any filing (`kickoff.md` → "Words typed after `new`").
82
82
 
83
83
  ## Promote, or create a new epic
84
84
 
package/README.md CHANGED
@@ -6,9 +6,9 @@ kit gives Claude Code or Codex your project's rules and checks.
6
6
 
7
7
  ## The workflow
8
8
 
9
- Type `backlogrun` and the agent takes the Issues you name from plan to merged PR — in parallel, unattended. A live board shows where each one stands:
9
+ `backlogrun` takes your Issues to merged PRs — in parallel, unattended:
10
10
 
11
- ![The backlogrun board: ten Issues running side by side, seven already merged, each with its stage and elapsed time](./docs/images/backlogrun-board.png)
11
+ ![The backlogrun board: ten Issues in one run, three already merged and the rest moving through their stages or waiting for a free lane, with recent findings and decisions below](./docs/images/backlogrun-board.png)
12
12
 
13
13
  [Every keyword, including the ones that stop for you earlier](./docs/how-to/run-issues.md)
14
14
 
@@ -23,7 +23,9 @@ Type `backlogrun` and the agent takes the Issues you name from plan to merged PR
23
23
 
24
24
  ## Quick start
25
25
 
26
- ### With the GitHub workflow
26
+ Pick one setup ([A or B: what differs](./docs/setup/choose.md)):
27
+
28
+ ### A. With GitHub — Issues, PRs and unattended runs
27
29
 
28
30
  Requires [Node.js, pnpm and the gh CLI](./docs/setup/prerequisites.md).
29
31
 
@@ -35,7 +37,17 @@ pnpm exec josh start
35
37
 
36
38
  Next: [tutorial](./docs/tutorial.md)
37
39
 
38
- ### AI assistant only — no GitHub account needed
40
+ #### Your first backlogrun
41
+
42
+ Tell the agent the change you want, then type `kickoff new` to it. The Issue gets the `auto-ok` label when it needs no judgement from you (or add the label to an existing Issue).
43
+
44
+ ```bash
45
+ pnpm josh backlogrun
46
+ ```
47
+
48
+ Details: [Run the backlog unattended](./docs/how-to/run-backlog.md)
49
+
50
+ ### B. Without GitHub — AI assistant only
39
51
 
40
52
  Requires [Node.js and pnpm](./docs/setup/prerequisites.md).
41
53
 
@@ -45,6 +57,17 @@ pnpm --allow-build=esbuild dlx @joshuafolkken/kit init
45
57
 
46
58
  Next: [tutorial](./docs/tutorial.md#without-github-one-change-checked-locally)
47
59
 
60
+ ### Adding kit to an existing project
61
+
62
+ - **Files written:** settings per profile, including Prettier — always on `full`, and on `basic` only when the project has web files and no formatter of its own ([per profile](./docs/init.md#project-profiles)); `--dry-run` previews them.
63
+ - **Overwritten by `josh sync`:** the managed files, such as `.github/workflows/ci.yml` and `AGENTS.md` ([the list](./docs/sync.md#ai-files-overwritten)).
64
+ - **Permissions:** the Claude Code settings kit writes (with `josh start`, or on `full`) set `bypassPermissions` with `Bash(*)`, guarded by a deny list and a hook ([how to opt out](./docs/init.md#claude-code-permission-mode)).
65
+ - **On GitHub:** `josh start` adds labels, and on an existing `main` an Issue and a setup PR that you merge yourself ([the steps](./docs/init.md#josh-init-or-josh-start)).
66
+
67
+ ## Claude Code in a fresh-machine run
68
+
69
+ A `josh fresh:run` scenario that runs Claude Code needs a sign-in saved once with `pnpm josh auth:setup` ([steps](./docs/maintainers/fresh-machine.md#claude-code)).
70
+
48
71
  ## Docs
49
72
 
50
73
  [How-to](./docs/how-to.md) · [All docs](./docs/overview.md)
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env tsx
2
2
  import {
3
3
  timed_fetch
4
- } from "./chunk-FZ6FUSBM.js";
4
+ } from "./chunk-723HKZO5.js";
5
5
  import {
6
6
  error_text
7
7
  } from "./chunk-CDY4NFQG.js";
8
8
  import {
9
9
  PROJECT_ROOT,
10
10
  stamp_file
11
- } from "./chunk-NEC4AT4Z.js";
11
+ } from "./chunk-DGT54IH5.js";
12
12
 
13
13
  // scripts/security/security-audit-provision.ts
14
14
  import { chmodSync, mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
@@ -9,13 +9,13 @@ import {
9
9
  load_environment_file,
10
10
  notice_refusal_path,
11
11
  refusal_path
12
- } from "./chunk-LMWBRJIP.js";
13
- import "./chunk-EAQEGME7.js";
14
- import "./chunk-EBSHN25W.js";
15
- import "./chunk-SL4GQ2XP.js";
16
- import "./chunk-J3KSS7II.js";
17
- import "./chunk-2YSW3CXH.js";
18
- import "./chunk-NEC4AT4Z.js";
12
+ } from "./chunk-EF5GQ6WS.js";
13
+ import "./chunk-UT7YC3N2.js";
14
+ import "./chunk-W5ZKGTSY.js";
15
+ import "./chunk-MBJYQPEK.js";
16
+ import "./chunk-OLMO72ON.js";
17
+ import "./chunk-3C4XRYG6.js";
18
+ import "./chunk-DGT54IH5.js";
19
19
  export {
20
20
  DISABLED_VALUES,
21
21
  SWITCH_ENV_KEY,
@@ -4,7 +4,7 @@ import {
4
4
  PROBE_TIMEOUT_MS,
5
5
  SUITE_TIMEOUT_MS,
6
6
  stamp_file
7
- } from "./chunk-NEC4AT4Z.js";
7
+ } from "./chunk-DGT54IH5.js";
8
8
 
9
9
  // scripts/lib/json-value.ts
10
10
  function parse_or_undefined(text) {
@@ -511,12 +511,19 @@ async function commit(message) {
511
511
  async function delete_branch(branch_name) {
512
512
  await git_spawn.read(["branch", "-d", branch_name]);
513
513
  }
514
- async function commit_count_beyond(base, tip) {
515
- const range = `${base}..${tip}`;
516
- const output = await git_spawn.read(["rev-list", "--count", range]);
514
+ async function read_commit_count(revisions) {
515
+ const output = await git_spawn.read(["rev-list", "--count", ...revisions]);
517
516
  const parsed = Number(output);
518
517
  if (output.length > 0 && Number.isFinite(parsed)) return parsed;
519
- throw new Error(`\`git rev-list --count ${range}\` printed \`${output}\` rather than a count`);
518
+ throw new Error(
519
+ `\`git rev-list --count ${revisions.join(" ")}\` printed \`${output}\` rather than a count`
520
+ );
521
+ }
522
+ async function commit_count_beyond(base, tip) {
523
+ return await read_commit_count([`${base}..${tip}`]);
524
+ }
525
+ async function commit_count_unpushed(branch_name) {
526
+ return await read_commit_count([branch_name, "--not", "--remotes"]);
520
527
  }
521
528
  function is_exit_code_128(cause) {
522
529
  return typeof cause === "object" && cause !== null && "exit_code" in cause && cause.exit_code === "128";
@@ -633,6 +640,7 @@ var git_command = {
633
640
  checkout,
634
641
  commit,
635
642
  commit_count_beyond,
643
+ commit_count_unpushed,
636
644
  delete_branch,
637
645
  push: push2,
638
646
  pull_fast_forward,
@@ -660,6 +668,7 @@ var START_TIME_FORMAT = "lstart=";
660
668
  var PID_FLAG = "-p";
661
669
  var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
662
670
  var LIVENESS_SIGNAL = 0;
671
+ var NO_SUCH_PROCESS = "ESRCH";
663
672
  var LOWEST_REAL_PID = 1;
664
673
  var PROC_START_FIELD_INDEX = 19;
665
674
  var BEACON_SCHEME = "socket:";
@@ -674,15 +683,20 @@ var BEACON_GONE_STATUS = 2;
674
683
  var SOCKET_PROBE_SOURCE = `const net=require('node:net');const socket=net.createConnection(process.argv[1]);socket.once('connect',()=>process.exit(${String(BEACON_LIVE_STATUS)}));socket.once('error',(error)=>process.exit(['ECONNREFUSED','ENOENT'].includes(error.code)?${String(BEACON_GONE_STATUS)}:${String(BEACON_UNKNOWN_STATUS)}));socket.setTimeout(1000,()=>process.exit(${String(BEACON_UNKNOWN_STATUS)}));`;
675
684
  var beacons = /* @__PURE__ */ new Map();
676
685
  var exit_cleanup = { is_registered: false };
677
- function is_live_pid(pid) {
678
- if (pid < LOWEST_REAL_PID) return false;
686
+ function signal_refusal(pid) {
679
687
  try {
680
688
  process.kill(pid, LIVENESS_SIGNAL);
681
- return true;
682
- } catch {
683
- return false;
689
+ return void 0;
690
+ } catch (error) {
691
+ return error.code ?? NO_SUCH_PROCESS;
684
692
  }
685
693
  }
694
+ function is_live_pid(pid) {
695
+ return pid >= LOWEST_REAL_PID && signal_refusal(pid) === void 0;
696
+ }
697
+ function is_present_pid(pid) {
698
+ return pid >= LOWEST_REAL_PID && signal_refusal(pid) !== NO_SUCH_PROCESS;
699
+ }
686
700
  function read_proc_start(pid) {
687
701
  try {
688
702
  const stat = readFileSync(`/proc/${String(pid)}/stat`, "utf8");
@@ -808,6 +822,11 @@ function is_same_process(pid, recorded_start, read3 = read_start) {
808
822
  if (recorded_start === void 0) return void 0;
809
823
  return matches_recorded_start(pid, recorded_start, read3);
810
824
  }
825
+ function is_present_process(pid, recorded_start, read3 = read_start) {
826
+ if (!is_present_pid(pid)) return false;
827
+ if (recorded_start === void 0) return void 0;
828
+ return matches_recorded_start(pid, recorded_start, read3);
829
+ }
811
830
  function is_own_process(pid, recorded_start) {
812
831
  return pid === process.pid && recorded_start === own_start();
813
832
  }
@@ -816,6 +835,8 @@ var process_identity = {
816
835
  is_live_beacon,
817
836
  is_live_pid,
818
837
  is_own_process,
838
+ is_present_pid,
839
+ is_present_process,
819
840
  is_same_process,
820
841
  open_beacon,
821
842
  own_fields,
@@ -2049,6 +2070,7 @@ var run_carry_schema = z2.object({
2049
2070
  owner_pid: z2.number().optional(),
2050
2071
  owner_start: z2.string().optional(),
2051
2072
  owner_transcript: z2.string().optional(),
2073
+ is_owner_headless: z2.boolean().optional(),
2052
2074
  is_handed_off: z2.boolean().optional(),
2053
2075
  done: z2.array(z2.number()).optional(),
2054
2076
  retrospective: z2.boolean().optional(),
@@ -2090,7 +2112,8 @@ function fresh_carry(invocation, owner, now) {
2090
2112
  outages: NO_INCREMENT3,
2091
2113
  owner_pid: owner.pid,
2092
2114
  owner_start: owner.start,
2093
- owner_transcript: owner.transcript
2115
+ owner_transcript: owner.transcript,
2116
+ is_owner_headless: owner.is_headless
2094
2117
  };
2095
2118
  }
2096
2119
  function begin_carry(target, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
@@ -2103,6 +2126,7 @@ function adopt_carry(target, carry, owner = NO_OWNER) {
2103
2126
  owner_pid: owner.pid,
2104
2127
  owner_start: owner.start,
2105
2128
  owner_transcript: owner.transcript,
2129
+ is_owner_headless: owner.is_headless,
2106
2130
  is_handed_off: false
2107
2131
  };
2108
2132
  stamp_file.remove_stamp(target);