@joshuafolkken/kit 1.1455.0 → 1.1471.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 (211) hide show
  1. package/.claude/skills/dependency-update/SKILL.md +26 -55
  2. package/.claude/skills/epic-commands/SKILL.md +87 -148
  3. package/.claude/skills/epic-commands/epic-bundle.md +45 -77
  4. package/.claude/skills/epic-commands/execution-waves.md +44 -81
  5. package/.claude/skills/verify-ui/SKILL.md +25 -50
  6. package/.claude/skills/workflow-commands/background-commands.md +36 -47
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +72 -85
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +91 -121
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +73 -117
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +7 -9
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +11 -20
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +43 -52
  13. package/.claude/skills/workflow-commands/chain-rule.md +24 -34
  14. package/.claude/skills/workflow-commands/followup.md +57 -76
  15. package/.claude/skills/workflow-commands/issue-comments.md +43 -60
  16. package/.claude/skills/workflow-commands/kickoff.md +65 -74
  17. package/.claude/skills/workflow-commands/observation-filing.md +62 -107
  18. package/.claude/skills/workflow-commands/observation-ledger.md +56 -111
  19. package/.claude/skills/workflow-commands/pre-gate-cut.md +89 -138
  20. package/.claude/skills/workflow-commands/prerequisite.md +10 -15
  21. package/.claude/skills/workflow-commands/progress-watcher.md +21 -26
  22. package/.claude/skills/workflow-commands/retrospective.md +31 -50
  23. package/.claude/skills/workflow-commands/split-assessment.md +34 -58
  24. package/.claude/skills/workflow-commands/working-tree-hold.md +54 -71
  25. package/CLAUDE.md +6 -5
  26. package/dist/CLAUDE.md +6 -5
  27. package/dist/hooks/batch-guard.js +6 -6
  28. package/dist/hooks/{chunk-7WQBPLUN.js → chunk-43ZHT22P.js} +31 -15
  29. package/dist/hooks/{chunk-LIAFCXL7.js → chunk-AS74OU3D.js} +23 -7
  30. package/dist/hooks/{chunk-3C4XRYG6.js → chunk-E7OIKX5Z.js} +17 -12
  31. package/dist/hooks/{chunk-Z4XI7CZS.js → chunk-EUMACUK2.js} +18 -12
  32. package/dist/hooks/{chunk-WNLVGT7E.js → chunk-H5HVWYXK.js} +4 -4
  33. package/dist/hooks/{chunk-HHI6FO3R.js → chunk-IIGFYXKC.js} +345 -240
  34. package/dist/hooks/{chunk-GPLGZ6IC.js → chunk-J47HU5H5.js} +14 -3
  35. package/dist/hooks/{chunk-OLMO72ON.js → chunk-K4EOONYM.js} +1 -1
  36. package/dist/hooks/{chunk-D5QBTOCZ.js → chunk-K4LMBQC2.js} +4 -4
  37. package/dist/hooks/{chunk-TBJFTSUY.js → chunk-KC5AK2GF.js} +8 -6
  38. package/dist/hooks/chunk-SHGPANFB.js +56 -0
  39. package/dist/hooks/{chunk-5H4SSDSD.js → chunk-YHBZAJSV.js} +3 -3
  40. package/dist/hooks/{chunk-HFGWYGUV.js → chunk-YYPI7SJZ.js} +5 -5
  41. package/dist/hooks/codex-hook-adapter.js +13 -13
  42. package/dist/hooks/duplicate-read-guard.js +7 -7
  43. package/dist/hooks/format-edited.js +3 -3
  44. package/dist/hooks/inputs.json +216 -214
  45. package/dist/hooks/investigation-guard.js +7 -7
  46. package/dist/hooks/pretool-guard.js +12 -12
  47. package/dist/hooks/session-lang.js +6 -5
  48. package/dist/hooks/stop-guard.js +18 -14
  49. package/dist/josh.js +5 -6
  50. package/dist/managed-marker/index.js +1 -2
  51. package/dist/version/index.js +15 -12
  52. package/eslint/base.js +2 -1
  53. package/eslint/rules/unicorn.js +16 -0
  54. package/package.json +3 -3
  55. package/prompts/coding-standards.md +12 -22
  56. package/prompts/collaboration-workflow/file-edits.md +26 -44
  57. package/prompts/collaboration-workflow/gh-rest.md +20 -36
  58. package/prompts/collaboration-workflow/glossary.md +5 -7
  59. package/prompts/collaboration-workflow/issue-citation.md +7 -13
  60. package/prompts/collaboration-workflow/issue-template.md +29 -29
  61. package/prompts/collaboration-workflow/operating-rules.md +35 -44
  62. package/prompts/collaboration-workflow/output-bounds.md +15 -15
  63. package/prompts/collaboration-workflow/overview.md +14 -19
  64. package/prompts/collaboration-workflow/plan-comment.md +13 -13
  65. package/prompts/collaboration-workflow/principles.md +50 -53
  66. package/prompts/collaboration-workflow/proposal-request.md +1 -9
  67. package/prompts/collaboration-workflow/report-format.md +32 -49
  68. package/prompts/collaboration-workflow/residency.md +10 -10
  69. package/prompts/collaboration-workflow/rule-delivery.md +9 -9
  70. package/prompts/collaboration-workflow/shell-body.md +10 -20
  71. package/prompts/collaboration-workflow/turn-batching.md +8 -14
  72. package/prompts/collaboration-workflow/upstream-interrupt.md +26 -34
  73. package/prompts/collaboration-workflow/wip-cap.md +24 -30
  74. package/prompts/collaboration-workflow.md +24 -25
  75. package/prompts/refactoring.md +33 -43
  76. package/prompts/review-rubric.md +84 -129
  77. package/prompts/review.md +111 -141
  78. package/prompts/sonar-hotspot-handling.md +22 -50
  79. package/prompts/testing-guide.md +48 -99
  80. package/scripts/adopt/adopt-toolkits.ts +2 -4
  81. package/scripts/agent/agent-exit-record.ts +23 -1
  82. package/scripts/agent/codex-agent-argv.ts +7 -2
  83. package/scripts/backlog/backlog-budget-cli.ts +1 -2
  84. package/scripts/backlog/backlog-drive-carried.ts +26 -0
  85. package/scripts/backlog/backlog-drive-cli.ts +10 -5
  86. package/scripts/backlog/backlog-drive-named.ts +2 -4
  87. package/scripts/backlog/backlog-drive-restore.ts +19 -1
  88. package/scripts/backlog/backlog-drive-seats.ts +27 -0
  89. package/scripts/backlog/backlog-drive.ts +11 -6
  90. package/scripts/backlog/backlog-ready.ts +13 -6
  91. package/scripts/behavior/behavior-rules.ts +3 -2
  92. package/scripts/cost-runtime/codex-usage.ts +4 -2
  93. package/scripts/cost-runtime/cost-cli.ts +1 -2
  94. package/scripts/delegation/investigation-guard.ts +1 -1
  95. package/scripts/delegation/investigation-reads.ts +1 -1
  96. package/scripts/discovery/repo-discovery.ts +4 -2
  97. package/scripts/discovery/repo-origin.ts +2 -4
  98. package/scripts/doctor/doctor-logic.ts +6 -3
  99. package/scripts/document/document-byte-budget.ts +27 -27
  100. package/scripts/document/document-byte-check.ts +1 -2
  101. package/scripts/document/entry-read-budget.ts +2 -2
  102. package/scripts/epic/epic-audit-rationale.ts +8 -2
  103. package/scripts/epic/epic-bundle-cli.ts +1 -2
  104. package/scripts/epic/epic-chains.ts +6 -2
  105. package/scripts/epic/epic-close-comment.ts +1 -2
  106. package/scripts/gate/verification-gate.ts +7 -2
  107. package/scripts/gh/git-pr.ts +6 -2
  108. package/scripts/git/git-common-directory.ts +3 -3
  109. package/scripts/git/git-diff-reads.ts +16 -9
  110. package/scripts/git/git-execa-error.ts +1 -2
  111. package/scripts/hooks/format-edited-file.ts +10 -4
  112. package/scripts/hooks/pre-push-unit.ts +15 -4
  113. package/scripts/hooks/pretool-guard.ts +23 -29
  114. package/scripts/hooks/step-zero-notice.ts +3 -2
  115. package/scripts/init/hook-command-rewrite.ts +6 -2
  116. package/scripts/init/init-logic-deploy-vps.ts +4 -2
  117. package/scripts/issue/behavior-change-lint.ts +12 -6
  118. package/scripts/issue/issue-scout-cli.ts +3 -2
  119. package/scripts/josh/file-map-stamp.ts +1 -3
  120. package/scripts/josh/hook-decision.ts +17 -2
  121. package/scripts/lane/lane-await.ts +3 -2
  122. package/scripts/lane/lane-child-invocation.ts +14 -1
  123. package/scripts/lane/lane-guard-policy.ts +4 -4
  124. package/scripts/lane/lane-ledger.ts +9 -0
  125. package/scripts/lane/lane-load.ts +9 -2
  126. package/scripts/lane/lane-measure-cli.ts +2 -0
  127. package/scripts/lane/lane-parked.ts +18 -0
  128. package/scripts/lane/lane-process-load.ts +125 -0
  129. package/scripts/lane/lane-process-stats.ts +93 -0
  130. package/scripts/lane/lane-registry.ts +8 -3
  131. package/scripts/lane/lane-session-broker.ts +29 -5
  132. package/scripts/lane/lane-spent.ts +14 -3
  133. package/scripts/lane/lane-stats.ts +1 -0
  134. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  135. package/scripts/overrides/lockfile-overrides.ts +1 -3
  136. package/scripts/propagate/propagate.ts +1 -2
  137. package/scripts/release/release-progress.ts +3 -2
  138. package/scripts/report/report-lint.ts +7 -4
  139. package/scripts/review/review-record-cli.ts +6 -2
  140. package/scripts/rules/destructive-command.ts +6 -9
  141. package/scripts/rules/direct-filing.ts +3 -7
  142. package/scripts/rules/early-heartbeat.ts +7 -18
  143. package/scripts/rules/file-body.ts +6 -13
  144. package/scripts/rules/filing-cap.ts +3 -6
  145. package/scripts/rules/git-force.ts +5 -9
  146. package/scripts/rules/implementation-cut.ts +37 -35
  147. package/scripts/rules/index-guard.ts +4 -7
  148. package/scripts/rules/issue-comments.ts +5 -15
  149. package/scripts/rules/josh-git-bare.ts +3 -6
  150. package/scripts/rules/lane-background.ts +10 -21
  151. package/scripts/rules/lane-carry-conflict.ts +7 -17
  152. package/scripts/rules/lane-interactive-ask.ts +6 -11
  153. package/scripts/rules/lane-park.ts +5 -13
  154. package/scripts/rules/lane-split-park.ts +2 -7
  155. package/scripts/rules/lane-switch-main.ts +9 -12
  156. package/scripts/rules/oracle-consulted.ts +4 -5
  157. package/scripts/rules/piped-verification.ts +81 -31
  158. package/scripts/rules/poll-loop.ts +7 -17
  159. package/scripts/rules/pre-gate-cut.ts +7 -21
  160. package/scripts/rules/prior-comment-read.ts +7 -5
  161. package/scripts/rules/protected-files.ts +5 -9
  162. package/scripts/rules/raw-field-body.ts +3 -7
  163. package/scripts/rules/rule-body-guard.ts +4 -11
  164. package/scripts/rules/run-tail-rule.ts +6 -22
  165. package/scripts/rules/shell-body-trigger.ts +4 -6
  166. package/scripts/rules/shell-segments.ts +7 -0
  167. package/scripts/rules/stop-rules.ts +16 -29
  168. package/scripts/rules/test-declared-commit.ts +4 -10
  169. package/scripts/rules/third-party-write.ts +5 -10
  170. package/scripts/rules/worktree-guard.ts +5 -12
  171. package/scripts/run/board/run-board-github.ts +11 -3
  172. package/scripts/run/board/run-board-idle.ts +31 -0
  173. package/scripts/run/board/run-board-read.ts +9 -12
  174. package/scripts/run/board/run-board-reason.ts +7 -3
  175. package/scripts/run/board/run-board-state.ts +4 -0
  176. package/scripts/run/board/run-board-status.ts +18 -3
  177. package/scripts/run/board/run-board-thanks.ts +7 -2
  178. package/scripts/run/board/run-board-tick.ts +32 -7
  179. package/scripts/run/carry/run-carry-args.ts +1 -3
  180. package/scripts/run/carry/run-carry-conversation.ts +7 -2
  181. package/scripts/run/cut/run-cut-cli.ts +15 -20
  182. package/scripts/run/cut/run-cut-decline.ts +72 -0
  183. package/scripts/run/cut/run-cut-ready.ts +74 -0
  184. package/scripts/run/cut/run-cut-report.ts +13 -0
  185. package/scripts/run/cut/run-cut.ts +10 -1
  186. package/scripts/run/hold/run-hold-cli.ts +14 -3
  187. package/scripts/run/hold/run-hold.ts +6 -3
  188. package/scripts/run/merge/run-merge-cli.ts +30 -7
  189. package/scripts/run/merge/run-merge-ship.ts +59 -1
  190. package/scripts/run/merge/run-merge.ts +3 -2
  191. package/scripts/run/run-ending.ts +31 -3
  192. package/scripts/run/run-parent-cut-hook.ts +5 -10
  193. package/scripts/run/run-preflight.ts +1 -2
  194. package/scripts/run/run-stop-notify.ts +1 -2
  195. package/scripts/run/run-watcher-guard.ts +6 -3
  196. package/scripts/run/ship/run-ship-review-steps.ts +13 -4
  197. package/scripts/run/ship/run-ship-review.ts +15 -2
  198. package/scripts/run/tidy/run-tidy-cli.ts +3 -3
  199. package/scripts/run/tidy/run-tidy-lanes.ts +3 -2
  200. package/scripts/safe-chain/project-config.ts +7 -2
  201. package/scripts/sync/sync-hook-safety.ts +8 -2
  202. package/scripts/test/unit-worker-share.ts +3 -2
  203. package/scripts/time-runtime/time-batch-guard.ts +3 -3
  204. package/scripts/time-runtime/time-hook-transcript.ts +3 -2
  205. package/scripts/time-runtime/time-shell.ts +10 -0
  206. package/scripts/version/effective-upstream.ts +3 -4
  207. package/scripts/version/kit-version-config.ts +8 -2
  208. package/scripts/version/latest-corepack.ts +1 -2
  209. package/scripts/version/release-hold.ts +11 -4
  210. package/scripts/version/version-commands.ts +12 -4
  211. package/dist/hooks/chunk-UT7YC3N2.js +0 -56
@@ -43,23 +43,16 @@ Rationale: `docs/maintainers/backlogrun-recovery-rationale.md` → "Why the poll
43
43
 
44
44
  ## Conflicts are not predicted
45
45
 
46
- **The child merges `origin/main` into its lane before its gate now, so this path is the fallback rather
47
- than the first line.** Every `fullrun` runs `pnpm josh main:merge` ahead of the gate
48
- (`chain-rule.md` → "origin/main is merged in before the gate", the single source), so an overlap
49
- already on `main` is resolved before the gate reads the tree. What this section covers is an overlap
50
- that lands on `main` *after* it, which `followup` still reports as a conflict.
46
+ **This path is the fallback**: every `fullrun` runs `pnpm josh main:merge` ahead of the gate
47
+ (`chain-rule.md` → "origin/main is merged in before the gate"), so it covers an overlap that lands on
48
+ `main` *after* it. **Nothing here forecasts which children will overlap** — a conflicting pull request
49
+ comes back `mergeStateStatus: DIRTY`, which `git-pr-checks-eval.ts` reads as a **failure**, so `pnpm josh
50
+ followup` ends that child with a named conflict in about ten seconds.
51
51
 
52
- **Nothing here forecasts which children will overlap.** The overlap surfaces where GitHub already
53
- reports it: a pull request that conflicts with its base comes back `mergeStateStatus: DIRTY`, which
54
- `git-pr-checks-eval.ts` reads as a **failure** rather than polling through it — so `pnpm josh followup`
55
- ends that child with a named conflict in about ten seconds.
56
-
57
- **That child does not stop: it resolves the conflict in its own lane.** It is **not** counted against
58
- the consecutive-failure guard either way.
59
-
60
- **The merge direction is `origin/main` into the lane's branch, never a rebase**, and no step below
61
- rewrites a pushed commit. Rationale: `docs/maintainers/backlogrun-recovery-rationale.md` → "Why a conflict
62
- is resolved in the lane rather than handed to a person".
52
+ **That child does not stop: it resolves the conflict in its own lane**, uncounted by the
53
+ consecutive-failure guard. **The merge direction is `origin/main` into the lane's branch, never a
54
+ rebase**; no step rewrites a pushed commit (`docs/maintainers/backlogrun-recovery-rationale.md` → "Why a
55
+ conflict is resolved in the lane rather than handed to a person").
63
56
 
64
57
  1. **Resolve in the lane.** `git fetch origin main`, merge `origin/main` into the lane's branch, resolve
65
58
  in place. Do not close the lane, open another, or switch its branch.
@@ -96,7 +89,5 @@ Meeting any of the four, the child is parked — `needs-decision` plus a comment
96
89
  it was, read against `backlogrun-park.md` → "Only a person's judgement carries `needs-decision`" — and its lane is **kept**, because the pushed branch is the resume path
97
90
  (`backlogrun-lanes.md` → "What happens to a lane").
98
91
 
99
- **Leave the tree clean before parking: `git merge --abort` precedes a park under conditions 1, 2 or 4.**
100
- Conditions 1 and 2 are read mid-merge with conflict markers still in the tree, condition 4 after a merge
101
- that is resolved but not committed; condition 3 fires before any merge is started, so there is nothing
102
- to abort.
92
+ **Leave the tree clean before parking: `git merge --abort` precedes a park under conditions 1, 2 or 4**
93
+ (condition 3 fires before any merge starts).
@@ -1,26 +1,30 @@
1
1
  # `backlogrun` — the detailed procedure behind the manifest
2
2
 
3
- Point-of-use, read one section at a time from `backlogrun.md` → "The route table"; how the driver runs the loop on its own is `docs/maintainers/backlogrun-driver.md`.
3
+ Point-of-use, read one section at a time from `backlogrun.md` → "The route table"; how the driver runs the loop on its own is `docs/maintainers/backlogrun-driver.md`. Reasons:
4
+
5
+ - `docs/maintainers/backlogrun-steps-rationale.md` → "Why the authorization boundary is shaped this way"
6
+ - `docs/maintainers/backlogrun-steps-rationale.md` → "Why a session cut does not end the run"
7
+ - `docs/maintainers/backlogrun-steps-rationale.md` → "Why the plan and the decision pass come first"
8
+ - `docs/maintainers/backlogrun-steps-rationale.md` → "Why the loop's contract is shaped this way"
9
+ - `docs/maintainers/backlogrun-steps-rationale.md` → "Why the idle watch lasts 8 hours from when the hands became free"
10
+ - `docs/maintainers/backlogrun-steps-rationale.md` → "Why the cost check skips a watch"
11
+ - `docs/maintainers/backlogrun-steps-rationale.md` → "Where each rule came from"
4
12
 
5
13
  ## What one invocation approves
6
14
 
7
15
  **One `backlogrun` approves every merge of every issue `pnpm josh backlog:next` offers** — `auto-ok`
8
16
  issues, every child of an epic whose root carries it, and a run's own filing once `pnpm josh
9
17
  epic:bundle` (Tier A, `observation-filing.md`) has placed it under such a root. **A named issue is
10
- approved by the keyword and its number, not by `auto-ok`** ("Named issues run first, in order"). What
11
- runs is stated by the keyword and its arguments, never inferred from a request's shape. **Two repairs
12
- that would bound this the other way are prohibited** — dropping a run's own filings, and requiring a
13
- person's `auto-ok` on a child; the brake below bounds it. A Tier C action inside a child still stops that child.
18
+ approved by the keyword and its number, not by `auto-ok`**. What runs is stated by the keyword and its
19
+ arguments, never inferred. **Two repairs that would bound this the other way are prohibited** —
20
+ dropping a run's own filings, and requiring a person's `auto-ok` on a child; the brake below bounds it.
21
+ A Tier C action inside a child still stops that child.
14
22
 
15
23
  **`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
-
22
- Rationale: `docs/maintainers/backlogrun-steps-rationale.md` → "Why the authorization boundary is shaped this way";
23
- provenance of each rule: `docs/maintainers/backlogrun-steps-rationale.md` → "Where each rule came from"
24
+ `auto-ok: not applied` with the reason (`scripts/issue/issue-auto-ok.ts`). Every filing, the
25
+ retrospective's included, is judged the same way: the excluded labels, then the body's `- 人の判断:`
26
+ declaration (`issue-template.md`). **Declare `- 人の判断: 要` when the new issue needs a person's
27
+ judgement** — a Tier B toss-up or a Tier C action inside it; `--no-auto-ok` withholds it too.
24
28
 
25
29
  ### The brake that replaces the promise
26
30
 
@@ -33,30 +37,26 @@ provenance of each rule: `docs/maintainers/backlogrun-steps-rationale.md` → "W
33
37
  | **Ten filings per invocation** | additions to the pool on **every** filing route (`prerequisite.md`) — `route:tier-a`, `route:interrupt` and a review branch-2 filing are exempt from the depth test (`observation-filing.md`), never from this ceiling | `run:carry --filed` |
34
38
  | The WIP cap on open issues | the pool across invocations | `prompts/collaboration-workflow/wip-cap.md` |
35
39
 
36
- **This section is the single source of how the `epic:bundle` obligation and this authorization
37
- boundary meet.** `observation-filing.md` points here rather than restating it.
40
+ **This section is the single source of how the `epic:bundle` obligation and this boundary meet.**
38
41
 
39
42
  ## Named issues run first, in order
40
43
 
41
- **`backlogrun #N1 #N2 …` runs the named issues before it touches the pool**,
42
- in the order typed, **one at a time — no lanes**, each as a full `fullrun` in a delegated unit
43
- (`backlogrun-child.md` → "Each child runs in a delegated unit"); the parent reads each one's state back
44
- with `pnpm josh issue:state <N>`, never the unit's summary. `pnpm josh backlog:plan #N1 #N2 …` renders
45
- the order, and `scripts/backlog/backlog-named.ts` is its single source.
44
+ **`backlogrun #N1 #N2 …` runs the named issues before it touches the pool**, in the order typed, **one
45
+ at a time — no lanes**, each as a `fullrun` in a delegated unit (`backlogrun-child.md` → "Each child
46
+ runs in a delegated unit"), read back with `pnpm josh issue:state <N>`. `pnpm josh backlog:plan #N1
47
+ #N2 …` renders the order (`scripts/backlog/backlog-named.ts`).
46
48
 
47
- **A named issue that cannot finish parks, and the rest of the named list is skipped**; the run then
48
- drains the pool, and the report lists what was not started (`backlog_named.after_failure`). A
49
- `needs-human-review` named issue stops the whole run (`needs-human-review.md`). **`--only` runs the
50
- named list and stops there, draining no pool** — a failure under `--only` ends the run, and `--only`
51
- with no named issues is refused before anything starts (`backlog_named.startup`).
49
+ **A named issue that cannot finish parks, and the rest of the named list is skipped**; the run drains
50
+ the pool and reports what was not started (`backlog_named.after_failure`). A `needs-human-review` named
51
+ issue stops the whole run. **`--only` runs the named list and stops there, draining no pool** — a
52
+ failure ends the run, and `--only` with no named issues is refused (`backlog_named.startup`).
52
53
 
53
54
  ## The session cut is inside the invocation
54
55
 
55
56
  **Typing `backlogrun` once authorizes the declared budget, and a session cut does not end the run** —
56
- the next session picks the same invocation up from the carry record (`backlogrun-progress.md` → "The
57
- hand-off"). The record keeps the opening invocation string, `--only` and the named list included; a
58
- resumed session runs `remaining` from `--json`. The contract is `docs/josh-commands-run.md` →
59
- "`josh run:carry`".
57
+ the next session resumes the invocation from the carry record (`backlogrun-progress.md` → "The
58
+ hand-off"), which keeps the invocation string, `--only` and the named list; it runs `remaining` from
59
+ `--json` (`docs/josh-commands-run.md` → "`josh run:carry`").
60
60
 
61
61
  ```bash
62
62
  pnpm josh run:carry --begin "backlogrun --max 5 --idle 30" --owner "$PPID"
@@ -64,9 +64,9 @@ pnpm josh run:carry --json # r
64
64
  pnpm josh run:wake --start # same turn as --begin; `running` under `josh backlogrun`
65
65
  ```
66
66
 
67
- **Always pass `--owner "$PPID"`**, and ask it before the plan, in the same turn as the first `pnpm josh
68
- ms`. **The record is the parent loop's, and a lane never touches it**; count into it with `--merged <N>`
69
- and `--filed 1`, and **`--cut` is the session's last write**.
67
+ **Always pass `--owner "$PPID"`**, before the plan, in the same turn as the first `pnpm josh ms`. **The
68
+ record is the parent loop's; a lane never touches it**. Count with `--merged <N>` and `--filed 1`;
69
+ **`--cut` is the session's last write**.
70
70
 
71
71
  | It answers | What the run does |
72
72
  | --- | --- |
@@ -85,30 +85,27 @@ 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 run** — `pnpm josh run:wake --list` reads it, `pnpm josh backlogrun
89
- --stop` stops it (`docs/josh-commands.md` → "`josh backlogrun`").
90
-
91
- Rationale: `docs/maintainers/backlogrun-steps-rationale.md` → "Why a session cut does not end the run"
88
+ **A person keeps control** — `pnpm josh run:wake --list` reads it, `pnpm josh backlogrun --stop` stops
89
+ it (`docs/josh-commands.md` → "`josh backlogrun`").
92
90
 
93
91
  ## The plan, before the first child starts
94
92
 
95
93
  **Report the plan before anything is dispatched. The plan is one command's output** — `pnpm josh
96
- backlog:plan`, rendered from the same
97
- pool `backlog:next` answers from. Report all four of its sections (Ready now, Waiting, Waiting on a
98
- person, Out of scope) to the person in the session language, with any truncated-listing `⚠`.
94
+ backlog:plan`, from the pool `backlog:next` answers from. Report all four sections (Ready now, Waiting,
95
+ Waiting on a person, Out of scope) in the session language, with any truncated-listing `⚠`.
99
96
 
100
97
  ### Resolve what the plan can resolve, before starting
101
98
 
102
99
  **Settle every `needs-decision` issue the plan listed in one pass**, from one `pnpm josh issue:read <N>
103
- <N> …` call (body and comments, `issue-comments.md`):
100
+ <N> …` call (`issue-comments.md`):
104
101
 
105
102
  - **An answer already in the issue** — record it as a comment and **remove the label** (Tier A).
106
103
  **Never measure in order to decide**: a question needing a benchmark or a run stays labelled.
107
104
  - **A person's judgement** — apply `needs-decision` (`backlogrun-park.md` → "Only a person's judgement
108
- carries `needs-decision`"); the next plan classifies it by the label alone.
109
- - **Order and isolate** — a native `blocked-by` where one must land first;
110
- `run:solo` on all three `backlogrun-lanes.md` → "A solo run" conditions, **every other one `run:lane`**,
111
- commenting the reason.
105
+ carries `needs-decision`").
106
+ - **Order and isolate** — a native `blocked-by` where one must land first; `run:solo` on all three
107
+ `backlogrun-lanes.md` → "A solo run" conditions, **every other one `run:lane`**, commenting the
108
+ reason.
112
109
  - **`priority:high`** only on a cited ground (a stated deadline, a person's written policy), commented;
113
110
  **never remove it**.
114
111
  - **Report `pnpm josh backlog:plan --waves`** with the plan, never an order derived by hand; then start
@@ -116,9 +113,7 @@ person, Out of scope) to the person in the session language, with any truncated-
116
113
 
117
114
  **`needs-decision`, `run:solo`, `run:lane` and `priority:high` are the only workflow labels a run
118
115
  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.
120
-
121
- Rationale: `docs/maintainers/backlogrun-steps-rationale.md` → "Why the plan and the decision pass come first"
116
+ `pnpm josh issue:file` or `pnpm josh auto-ok:judge`.
122
117
 
123
118
  ## The loop
124
119
 
@@ -140,11 +135,7 @@ section the row names:
140
135
  | `window` | Hand the loop back as is | — |
141
136
 
142
137
  **A candidate only in another repository is never a token** — report it with its checkout. The budgets,
143
- verdicts and stops are the driver's own: `docs/maintainers/backlogrun-driver.md` (rationale:
144
- `docs/maintainers/backlogrun-steps-rationale.md` → "Why the idle watch lasts 8 hours from when the hands became free";
145
- `docs/maintainers/backlogrun-steps-rationale.md` → "Why the cost check skips a watch").
146
-
147
- Rationale: `docs/maintainers/backlogrun-steps-rationale.md` → "Why the loop's contract is shaped this way"
138
+ verdicts and stops are the driver's own: `docs/maintainers/backlogrun-driver.md`.
148
139
 
149
140
  ## What runs once per session, not once per issue
150
141
 
@@ -58,42 +58,32 @@ These are the gate → review → PR → merge facts other documents cite; this
58
58
  rule came from and why it holds: `docs/maintainers/chain-rule-rationale.md` → "Where each rule came
59
59
  from", `docs/maintainers/chain-rule-rationale.md` → "Why the orchestration facts hold".
60
60
 
61
- - **The gate runs beside this review, not in front of it** — `pnpm josh gate` is started when the review
62
- starts and joined before the commit. A red gate is fixed and re-run whatever the review concluded, and
63
- there is no path to a commit on a gate nobody read.
64
- - **origin/main is merged in before the gate** — `pnpm josh main:merge` merges `origin/<default>` into
65
- the branch before the gate and the review start. It is the last edit, so the scoped pair and the gate
66
- run once over it. A conflict here fires `backlogrun-recovery.md` → "Conflicts are not predicted"
67
- early. **This is the one place a conflicted merge's procedure is written**:
68
- `main:merge` refuses before merging when uncommitted changes touch a path the default branch also
69
- changed, or when the index still holds unresolved or staged paths — commit the work first with
70
- `pnpm josh git -y`, then rerun it, and **never stash around the merge**. A merge that stops on a
71
- conflict is finished the same way: remove the markers, then `pnpm josh git -y` stages the resolution
72
- and records the merge commit. That commit is the sanctioned flow, so it is **Tier A** — a lane child
73
- never stops to ask a person for `git add`, and the `Stop` hook sends back a reply that does.
74
- - **A single check answers once per tree** — while implementing, re-run a single check by name
75
- (`pnpm josh lint:related`, `pnpm josh cspell:dot`, `pnpm josh test:related`, or the project's type
76
- check) after every edit; a repeat of the same command with the same arguments over a tree nothing has
77
- touched since buys only a copy of the answer already in hand. In kit a detached `pnpm josh ship` also
78
- checks the metrics totals before the hand-off, so the implementing session accepts a grown total with
79
- its reason, as the ship's output names.
80
- - **The pull request opens between the rounds, so CI runs beside round 2** — `pnpm josh git -y` sits
81
- between the two review rounds. Round 1 runs on the uncommitted tree and its High/Medium findings are
82
- fixed before anything is committed; the verification pass over those fixes then runs against the open
83
- pull request, beside the CI the commit started.
84
- - **The round-2 fix commit is pushed before its gate** — a fix the second round makes in place is
85
- pushed (`pnpm josh git -y` again, a follow-up commit) before its `pnpm josh gate`, so the gate runs
86
- inside the CI wait and is joined before `pnpm josh followup` rather than in front of it.
87
- - **A clean second round issues the merge in the same turn** — the turn that reads a clean second round
88
- issues `pnpm josh followup`, after any branch-2 filing and `pnpm josh epic:bundle` and never in a turn
89
- of its own. Clean has two halves: no confirmed High is standing, and nothing was routed to branch 1 of
90
- the disposition.
91
- - **The review runs in a subagent, never a main-line skill load** — `/code-review` is spawned through
92
- the `Agent` tool in its own context, as the agent type step 1 names.
61
+ - **The gate runs beside this review, not in front of it** — started with the review, joined before the
62
+ commit. A red gate is fixed and re-run whatever the review concluded.
63
+ - **origin/main is merged in before the gate** — `pnpm josh main:merge` is the last edit, so the scoped
64
+ pair and the gate run once over it; a conflict fires `backlogrun-recovery.md` → "Conflicts are not
65
+ predicted" early. **This is the one place a conflicted merge's procedure is written**: `main:merge`
66
+ refuses when uncommitted changes touch a path the default branch also changed, or the index holds
67
+ unresolved or staged paths — commit first with `pnpm josh git -y`, rerun, and **never stash around the
68
+ merge**. A merge stopped on a conflict: remove the markers, then `pnpm josh git -y` stages the
69
+ resolution and records the merge commit — **Tier A**; a lane child never asks a person for `git add`.
70
+ - **A single check answers once per tree** — re-run one check by name (`pnpm josh lint:related`,
71
+ `pnpm josh cspell:dot`, `pnpm josh test:related`, or the type check) after every edit, never twice
72
+ over an untouched tree. In kit a detached `pnpm josh ship` also checks the metrics totals; accept a
73
+ grown total with its reason, as its output names.
74
+ - **The pull request opens between the rounds, so CI runs beside round 2** — round 1 runs on the
75
+ uncommitted tree and its High/Medium fixes land before the commit; the verification pass runs against
76
+ the open pull request.
77
+ - **The round-2 fix commit is pushed before its gate** — `pnpm josh git -y` again, so the gate runs
78
+ inside the CI wait and is joined before `pnpm josh followup`.
79
+ - **A clean second round issues the merge in the same turn** — `pnpm josh followup`, after any branch-2
80
+ filing and `pnpm josh epic:bundle`. Clean: no confirmed High standing, nothing routed to branch 1.
81
+ - **The review runs in a subagent, never a main-line skill load** — `/code-review` through the `Agent`
82
+ tool, as the agent type step 1 names.
93
83
  - **The brief names the checkout, and a review that read another one is refused** — `pnpm josh
94
- review:brief` prints the checkout root, branch and HEAD and a nonce; the review runs `pnpm josh
84
+ review:brief` prints the checkout root, branch, HEAD and a nonce; the review runs `pnpm josh
95
85
  review:attest <nonce>` from the tree it read, and `pnpm josh review:attest --check` must answer `ok`
96
- before the run or `pnpm josh followup` acts on the verdict, or it is discarded.
86
+ before anything acts on the verdict.
97
87
 
98
88
  This file is the single source of the gate → review → PR → merge chain rule; other documents reference
99
89
  it rather than restating it. `prompts/collaboration-workflow/plan-comment.md` keeps Step 3.
@@ -1,10 +1,9 @@
1
1
  # Finishing a run — `pnpm josh followup`
2
2
 
3
3
  Everything between a green CI and a merged PR: the command, the merge it authorizes, the notifications,
4
- the reviewer scan, the config report and the release ask. `fullrun` and `backlogrun` end here;
5
- `halfrun` never reaches this file, because it stops before the commit. This file is the single source
6
- of the rule. Where each rule came from: `docs/maintainers/followup-rationale.md` → "Where each rule
7
- came from".
4
+ the reviewer scan, the config report and the release ask. `fullrun` and `backlogrun` end here; `halfrun`
5
+ stops before the commit. This file is the single source. Where each rule came from:
6
+ `docs/maintainers/followup-rationale.md` → "Where each rule came from".
8
7
 
9
8
  ## Run `pnpm josh followup`
10
9
 
@@ -20,85 +19,75 @@ bullets. Use the file option whenever it contains a command or path.
20
19
  It waits for required CI, checks CodeRabbit and top-level AI review comments, sends the completion
21
20
  Telegram, merges by default, posts the Issue report, closes completed epics, removes `in-progress`,
22
21
  and releases the hold. Only `--no-merge` stops the merge; `--merge` is a deprecated no-op. **A pull
23
- request already merged by hand** (a `prrun` stop) skips the CI wait, the AI review scan and the merge
24
- and runs only the post-merge tail; a completion report already on the Issue is not posted or notified
25
- twice, so re-running is safe. Keep the default Issue target. Ignore a finding only after verifying it
26
- is inapplicable; rate-limit text is not a finding.
22
+ request already merged by hand** (a `prrun` stop) runs only the post-merge tail; a report already on the
23
+ Issue is not posted twice, so re-running is safe. Keep the default Issue target. Ignore a finding only
24
+ after verifying it is inapplicable; rate-limit text is not a finding.
27
25
 
28
- **A red rate-limited CodeRabbit check is cleared by a retrigger, not a bypass.** Wait out the window
29
- the rate-limit comment states, post `@coderabbitai review` on the pull request, and rerun `followup`.
30
- Bypassing the check is Tier C — only on explicit user instruction, and only when the stated window is
31
- impractically long or the retrigger is rate-limited again.
26
+ **A red rate-limited CodeRabbit check is cleared by a retrigger, not a bypass.** Wait out the stated
27
+ window, post `@coderabbitai review` on the pull request, and rerun `followup`. Bypassing is Tier C — on
28
+ explicit user instruction only, when the window is impractically long or the retrigger is rate-limited
29
+ again.
32
30
 
33
- A pre-merge failure stops the run; an unverifiable AI finding or CI failure needing input receives a
34
- `confirmation` Telegram. Post-merge cleanup failures are named and do not undo the merge; run the
35
- named recovery without rerunning it. Because notification precedes merge, the printed result is
36
- authoritative.
31
+ A pre-merge failure stops the run; an unverifiable AI finding or CI failure needing input sends a
32
+ `confirmation` Telegram. A post-merge cleanup failure is named and does not undo the merge; run the
33
+ named recovery without rerunning `followup`. The printed result is authoritative.
37
34
 
38
- After success, run `pnpm josh ms`; in a lane its refusal is expected and the parent uses
39
- `pnpm josh lane:close <N>`. Never delete the branch unless requested. The sections below are read
40
- after execution, when its output needs reading.
35
+ After success, run `pnpm josh ms`; in a lane it refuses and the parent uses `pnpm josh lane:close <N>`.
36
+ Never delete the branch unless requested. The sections below are read when the output needs reading.
41
37
 
42
38
  ## The options
43
39
 
44
40
  | Option | What it is |
45
41
  | --- | --- |
46
- | `--no-merge` | **The only flag that stops the merge** — leave it out and the command merges |
47
- | `--notify-target` | `pr` \| `issue` \| `both`, defaulting to `issue`. **Keep the default** — the workflow puts no completion report on the pull request |
48
- | `--notify-message` / `--notify-message-file` | The completion comment body in the two-layer report shape — `Cause: / Fix: / Result:`, then `Details:` bullets, never a bare `Added … / Changed …` list. **Use the file form whenever the report names a command or a path** (`prompts/collaboration-workflow/shell-body.md`); `-` reads stdin |
49
- | `--coderabbit-ignore-reason` | The reason comment for leaving CodeRabbit line comments unresolved |
50
- | `--ai-review-ignore-reason` | The reason comment for leaving an AI-review blocker (Claude Review / a CodeRabbit summary) unresolved |
51
- | `--issue-number` | The Issue number — or give it positionally as `"<title> #<number>"`; with neither, the PR body's `closes #N` supplies it |
42
+ | `--no-merge` | **The only flag that stops the merge** |
43
+ | `--notify-target` | `pr` \| `issue` \| `both`, default `issue`. **Keep the default** |
44
+ | `--notify-message` / `--notify-message-file` | The completion comment in the two-layer shape — `Cause: / Fix: / Result:`, then `Details:` bullets, never a bare `Added … / Changed …` list. **Use the file form whenever the report names a command or a path** (`prompts/collaboration-workflow/shell-body.md`); `-` reads stdin |
45
+ | `--coderabbit-ignore-reason` | Why CodeRabbit line comments stay unresolved |
46
+ | `--ai-review-ignore-reason` | Why an AI-review blocker (Claude Review / a CodeRabbit summary) stays unresolved |
47
+ | `--issue-number` | The Issue number — or positionally as `"<title> #<number>"`; with neither, the PR body's `closes #N` |
52
48
 
53
49
  ## `auto-merge` — Default `fullrun` behavior
54
50
 
55
- Invoking `fullrun` is itself the explicit authorization to merge; the user adds no keyword.
51
+ Invoking `fullrun` is itself the explicit authorization to merge.
56
52
 
57
- - **Always run `pnpm josh ms` after a successful merge** — it returns the tree to the default branch
58
- with the merge commit pulled. **In a lane, `pnpm josh lane:close <N>` is the terminal step instead**:
59
- `josh ms` refuses there, and the refresh is the parent's.
60
- - **Green CI is not authorization to merge while AI review findings are open.** On a blocker
61
- `followup` sends a `confirmation` Telegram and exits non-zero — fix and re-run. SonarCloud is not
62
- scanned here; the required `SonarQube` check carries it.
53
+ - **Always run `pnpm josh ms` after a successful merge**. **In a lane, `pnpm josh lane:close <N>` is the
54
+ terminal step instead** — `josh ms` refuses there.
55
+ - **Green CI is not authorization to merge while AI review findings are open.** A blocker sends a
56
+ `confirmation` Telegram and exits non-zero — fix and re-run. SonarCloud is carried by the required
57
+ `SonarQube` check.
63
58
  - **Verify a CodeRabbit finding before bypassing it.** Never pass `--coderabbit-ignore-reason`
64
59
  reflexively: a SHA pin flagged "not matching the tag" is checked with `gh api
65
60
  repos/<owner>/<repo>/commits/<tag> --jq '.sha'`, and the bypass cites that command.
66
- - **The merge is `followup`'s, not yours** — it calls the REST merge endpoint from inside a node
67
- script, and `.claude/settings.json` refuses `gh pr merge` and its `gh api` spellings (`CLAUDE.md` →
68
- "Git Rules"). Do **not** pass `--delete-branch` unless the user asks.
61
+ - **The merge is `followup`'s, not yours** — `.claude/settings.json` refuses `gh pr merge` and its
62
+ `gh api` spellings (`CLAUDE.md` → "Git Rules"). Do **not** pass `--delete-branch` unless asked.
69
63
  - **A failed merge** (branch protection, a conflict) is reported and stops the run — never retried with
70
- other flags or past a protection. To skip the merge, use `kickoff` or say "do not merge" in the same
71
- turn and pass `--no-merge`.
64
+ other flags. To skip the merge, use `kickoff` or say "do not merge" in the same turn and pass
65
+ `--no-merge`.
72
66
 
73
67
  ## Completion notifications: always via `pnpm josh followup`
74
68
 
75
- **Never send a `completion` Telegram with `pnpm josh notify`** — `followup` sends it with the PR URL,
76
- which the manual CLI does not fill in. `pnpm josh notify` stays the tool for `planning`,
77
- `confirmation`, `kickoff_retry` and `failure`. **It fires before the merge**, so a received ✅ is not
78
- proof the PR merged — read what the command printed; a silent run is a failed run.
69
+ **Never send a `completion` Telegram with `pnpm josh notify`** — `followup` fills in the PR URL.
70
+ `pnpm josh notify` stays the tool for `planning`, `confirmation`, `kickoff_retry` and `failure`. **It
71
+ fires before the merge**, so a ✅ is not proof the PR merged — read what the command printed.
79
72
 
80
- **Always run it in the foreground** — the deliberate exception to `background-commands.md`, because
81
- nearly every later step reads its result. The CI wait defaults to 32 minutes, so give the call the
82
- largest timeout it accepts (`timeout: 600000` in Claude Code). Where the harness detaches an
83
- over-running command, wait for its report; where it kills the call, set `JOSH_CI_TIMEOUT_SECONDS` to fit
84
- and re-run once CI has settled. Re-run it after every follow-up commit.
73
+ **Always run it in the foreground** — the exception to `background-commands.md`. The CI wait defaults
74
+ to 32 minutes; give the call the largest timeout it accepts (`timeout: 600000` in Claude Code). Where the
75
+ harness detaches the call, wait for its report; where it kills it, set `JOSH_CI_TIMEOUT_SECONDS` and
76
+ re-run once CI has settled. Re-run after every follow-up commit.
85
77
 
86
78
  **The count of unreleased merges is surfaced at completion — not a version.** It prints `🚚 unreleased
87
- merges on main: <n>` and puts the count in the Telegram. **Do not report a shipped version**: a child
88
- no longer bumps, so `package.json` names the previous release. What the run does about it is "When
89
- `pnpm josh release` runs" below.
79
+ merges on main: <n>`. **Do not report a shipped version** — a child no longer bumps. See "When `pnpm
80
+ josh release` runs" below.
90
81
 
91
82
  ## Reading the stage-timing block
92
83
 
93
- The command closes with one `followup stage: <name> <seconds>` row per stage and a
94
- `followup stages total:` line, so where it spent its time is read, not guessed.
84
+ One `followup stage: <name> <seconds>` row per stage, then `followup stages total:`.
95
85
 
96
- - **A failed run prints it too**, up to the stage that threw, named `interrupted` — a short block is
97
- the run stopping early, not the printer breaking. The `merge` row appears only on a run that merged.
86
+ - **A failed run prints it too**, up to the stage that threw, named `interrupted`. The `merge` row
87
+ appears only on a run that merged.
98
88
  - **A row named `<a>-and-<b>` is a batch of requests sent together**; `checks-wait` is never
99
- overlapped, because it is the merge gate.
100
- - **The total is the sum of the stages**, not the wall clock — the post-merge tail (record clears, the
101
- hold release, the next-issue listing) sits outside it.
89
+ overlapped.
90
+ - **The total is the sum of the stages**, not the wall clock — the post-merge tail sits outside it.
102
91
 
103
92
  A `failure` Telegram is sent **by hand, exactly once**, and only when recovery is given up:
104
93
 
@@ -108,36 +97,30 @@ pnpm josh notify --task-type failure --issue-url "<issue-url>" --body-file <reas
108
97
 
109
98
  ## AI reviewer comment scan
110
99
 
111
- `followup` scans top-level PR comments from AI reviewers **independently of CI status**, so a finding
112
- posted after CI goes green is not silently shipped.
100
+ `followup` scans top-level PR comments from AI reviewers **independently of CI status**.
113
101
 
114
102
  - **Blockers are structural, not NLP**: a Claude Review body with `### Issues`, `### Problem`,
115
103
  `#### Logic bug` or a numbered `### 1. …` heading; a CodeRabbit `Actionable comments posted: N` with
116
104
  N > 0. Rate-limit notices and sign-offs (`All issues resolved ✓`) match nothing.
117
105
  - **A standing blocker without `--ai-review-ignore-reason`** sends a `confirmation` Telegram and exits
118
- non-zero; with it, the reason is posted to the PR and the run proceeds.
119
- - **A comment listing that could not be read is a standing blocker** — never an empty listing that
120
- passes.
106
+ non-zero; with it, the reason is posted and the run proceeds.
107
+ - **A comment listing that could not be read is a standing blocker**.
121
108
  - **Temporary**: CodeRabbit is non-blocking end to end — out of the default required checks
122
- (restore via `JOSH_REQUIRED_CHECKS`), its actionable count and unreadable line-comment listing are
123
- audit notes rather than blockers. When it is reverted:
109
+ (restore via `JOSH_REQUIRED_CHECKS`); its findings are audit notes. Reverting it:
124
110
  `docs/maintainers/followup-rationale.md` → "The temporary CodeRabbit exemption".
125
111
 
126
112
  ## Config file reporting
127
113
 
128
114
  `followup` matches every changed path against what `josh sync` distributes (`AI_COPY_FILES`,
129
115
  `AI_COPY_FILE_MAPPINGS`, `AI_COPY_DIRECTORIES`, `SYNCED_PATHS`) and **reports** the claimed paths in the
130
- completion notification and the Issue report. **It stops nothing**
131
- (`docs/maintainers/followup-rationale.md` → "Why config claims are reported, not stopped").
132
- `pnpm josh sync:scope` gives the same answer on demand; there is no flag to pass.
116
+ notification and the Issue report. **It stops nothing** (`docs/maintainers/followup-rationale.md` →
117
+ "Why config claims are reported, not stopped"). `pnpm josh sync:scope` gives the same answer.
133
118
 
134
119
  ## When `pnpm josh release` runs
135
120
 
136
- **The release point is a position plus a command's answer, never a judgement.**
137
-
138
- **The position: once per invocation, after the last merge** — a lone `fullrun`'s only one, a
139
- `backlogrun`'s **last** child, never once per child. In a lane the parent asks it, in the primary
140
- checkout, after the last lane is closed.
121
+ **The release point is a position plus a command's answer, never a judgement.** **The position: once
122
+ per invocation, after the last merge** — a lone `fullrun`'s only one, a `backlogrun`'s **last** child.
123
+ With lanes the parent asks it, in the primary checkout, after the last lane is closed.
141
124
 
142
125
  ```bash
143
126
  pnpm josh release:scope # → required | skip | unknown
@@ -149,11 +132,9 @@ pnpm josh release:scope # → required | skip | unknown
149
132
  | `skip` | the count is zero — nothing is waiting to ship | Say so in one line and finish |
150
133
  | `unknown` | the count could not be read | **Report it as `unknown`** — it is never read as `skip` |
151
134
 
152
- **The run never types `pnpm josh release` itself.** It opens and merges a PR of its own and starts
153
- the tag → publish → `production` chain — outward-facing and effectively irreversible, so Tier C.
154
- Typing `fullrun` authorizes this Issue's merge and nothing past it; a person types the release in the
155
- primary checkout, on the default branch, with a clean tree. `release:scope` counts nothing of its own —
156
- it reads the same fetch-then-count `followup` uses for the Telegram line, so the two cannot disagree.
135
+ **The run never types `pnpm josh release` itself** — it starts the tag → publish → `production` chain,
136
+ outward-facing and effectively irreversible, so Tier C. A person types it in the primary checkout, on
137
+ the default branch, with a clean tree.
157
138
 
158
139
  **On `required`, the release request cites the open release Issue** — the one `issue:file --release` / `issue:release <N>` links blockers to — with a number-link
159
140
  (`prompts/collaboration-workflow/issue-citation.md`). List it with