@joshuafolkken/kit 1.1128.0 → 1.1166.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 (192) hide show
  1. package/.claude/agents/investigator.md +17 -0
  2. package/.claude/settings.json +5 -4
  3. package/.claude/skills/epic-commands/SKILL.md +27 -239
  4. package/.claude/skills/epic-commands/epic-bundle.md +115 -0
  5. package/.claude/skills/epic-commands/execution-waves.md +126 -0
  6. package/.claude/skills/workflow-commands/SKILL.md +48 -194
  7. package/.claude/skills/workflow-commands/background-commands.md +1 -1
  8. package/.claude/skills/workflow-commands/backlogrun-child.md +12 -123
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +11 -60
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +10 -8
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +19 -175
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +155 -0
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +64 -144
  14. package/.claude/skills/workflow-commands/backlogrun.md +5 -4
  15. package/.claude/skills/workflow-commands/chain-rule.md +3 -2
  16. package/.claude/skills/workflow-commands/delegation.md +7 -3
  17. package/.claude/skills/workflow-commands/entry-sequence.md +62 -0
  18. package/.claude/skills/workflow-commands/followup.md +104 -181
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +8 -9
  20. package/.claude/skills/workflow-commands/fullrun.md +16 -73
  21. package/.claude/skills/workflow-commands/halfrun.md +10 -36
  22. package/.claude/skills/workflow-commands/into-target.md +4 -4
  23. package/.claude/skills/workflow-commands/issue-comments.md +7 -8
  24. package/.claude/skills/workflow-commands/issue-scout.md +6 -6
  25. package/.claude/skills/workflow-commands/kickoff.md +6 -6
  26. package/.claude/skills/workflow-commands/needs-human-review.md +6 -6
  27. package/.claude/skills/workflow-commands/observation-filing.md +21 -172
  28. package/.claude/skills/workflow-commands/observation-ledger.md +150 -0
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -93
  30. package/.claude/skills/workflow-commands/prerequisite.md +6 -6
  31. package/.claude/skills/workflow-commands/progress-watcher.md +90 -0
  32. package/.claude/skills/workflow-commands/prrun.md +5 -5
  33. package/.claude/skills/workflow-commands/retrospective.md +9 -9
  34. package/.claude/skills/workflow-commands/split-assessment.md +2 -2
  35. package/.claude/skills/workflow-commands/target-repository.md +2 -2
  36. package/.claude/skills/workflow-commands/working-tree-hold.md +7 -5
  37. package/.codex/hooks.json +4 -4
  38. package/AGENTS.md +1 -6
  39. package/CLAUDE.md +58 -120
  40. package/GEMINI.md +1 -6
  41. package/SECURITY.md +1 -0
  42. package/dist/CLAUDE.md +58 -120
  43. package/dist/hooks/batch-guard.js +4 -4
  44. package/dist/hooks/{chunk-MKVGBQPA.js → chunk-5KTCMCOT.js} +14 -1
  45. package/dist/hooks/{chunk-NXYMNPUQ.js → chunk-A6P7PN7P.js} +59 -21
  46. package/dist/hooks/{chunk-77J7IEQM.js → chunk-ANJ2WGFD.js} +1 -1
  47. package/dist/hooks/{chunk-4JZDP5X5.js → chunk-DYAVAM6S.js} +572 -127
  48. package/dist/hooks/{chunk-7HVB7SZG.js → chunk-ENA7P5FB.js} +4 -4
  49. package/dist/hooks/{chunk-M7QKEKWO.js → chunk-GU5MATVE.js} +214 -85
  50. package/dist/hooks/chunk-GYNGP7HI.js +56 -0
  51. package/dist/hooks/{chunk-5SD2YM7Z.js → chunk-URJA6XY4.js} +4 -4
  52. package/dist/hooks/{chunk-XYUIQOW3.js → chunk-V2BTOZHT.js} +6 -4
  53. package/dist/hooks/{chunk-AIOIOMPX.js → chunk-ZDZ555YH.js} +225 -78
  54. package/dist/hooks/codex-hook-adapter.js +10 -10
  55. package/dist/hooks/duplicate-read-guard.js +5 -5
  56. package/dist/hooks/format-edited.js +2 -2
  57. package/dist/hooks/inputs.json +186 -184
  58. package/dist/hooks/investigation-guard.js +5 -5
  59. package/dist/hooks/pretool-guard.js +11 -10
  60. package/dist/hooks/stop-guard.js +5 -5
  61. package/dist/josh.js +33 -3
  62. package/dist/version/index.js +5 -1
  63. package/package.json +7 -4
  64. package/prompts/collaboration-workflow/file-edits.md +11 -10
  65. package/prompts/collaboration-workflow/gh-rest.md +2 -4
  66. package/prompts/collaboration-workflow/glossary.md +1 -1
  67. package/prompts/collaboration-workflow/issue-citation.md +5 -9
  68. package/prompts/collaboration-workflow/issue-template.md +40 -115
  69. package/prompts/collaboration-workflow/operating-rules.md +4 -5
  70. package/prompts/collaboration-workflow/output-bounds.md +12 -78
  71. package/prompts/collaboration-workflow/overview.md +7 -13
  72. package/prompts/collaboration-workflow/plan-comment.md +11 -39
  73. package/prompts/collaboration-workflow/principles.md +3 -4
  74. package/prompts/collaboration-workflow/report-format.md +28 -74
  75. package/prompts/collaboration-workflow/residency.md +12 -109
  76. package/prompts/collaboration-workflow/rule-delivery.md +98 -97
  77. package/prompts/collaboration-workflow/shell-body.md +3 -13
  78. package/prompts/collaboration-workflow/turn-batching.md +14 -88
  79. package/prompts/collaboration-workflow/upstream-interrupt.md +12 -14
  80. package/prompts/collaboration-workflow/wip-cap.md +6 -45
  81. package/prompts/collaboration-workflow.md +1 -13
  82. package/prompts/review-rubric.md +8 -71
  83. package/prompts/review.md +25 -55
  84. package/prompts/testing-guide.md +18 -67
  85. package/scripts/agent/agent-role-profile.ts +1 -1
  86. package/scripts/agent/codex-hooks.ts +3 -12
  87. package/scripts/backlog/backlog-budget.ts +1 -1
  88. package/scripts/backlog/backlog-drive-cli.ts +4 -3
  89. package/scripts/backlog/backlog-drive-offer-argv.ts +10 -1
  90. package/scripts/backlog/backlog-offer.ts +6 -6
  91. package/scripts/behavior/behavior-rules.ts +11 -4
  92. package/scripts/delegation/delegation-policy.ts +9 -1
  93. package/scripts/delegation/investigation-guard.ts +1 -1
  94. package/scripts/delegation/investigation-reads.ts +109 -23
  95. package/scripts/discovery/repo-discovery.ts +21 -7
  96. package/scripts/discovery/repo-origin.ts +26 -0
  97. package/scripts/discovery/repo-party.ts +42 -1
  98. package/scripts/document/backlogrun-parent-read-set.ts +14 -15
  99. package/scripts/document/capped-print.ts +74 -0
  100. package/scripts/document/document-byte-budget.ts +34 -20
  101. package/scripts/document/document-section-cli.ts +4 -3
  102. package/scripts/document/entry-read-budget.ts +21 -9
  103. package/scripts/document/lane-child-read-set.ts +12 -14
  104. package/scripts/document/read-set-cli.ts +4 -4
  105. package/scripts/document/read-set-point-of-use.ts +10 -2
  106. package/scripts/document/resident-budget.ts +47 -0
  107. package/scripts/epic/epic-shape.ts +10 -13
  108. package/scripts/epic/epic-solo.ts +1 -1
  109. package/scripts/exports/unused-members-cli.ts +7 -3
  110. package/scripts/gate/scoped-green.ts +25 -14
  111. package/scripts/gh/git-gh-api-path.ts +7 -0
  112. package/scripts/hooks/pretool-guard-cli.ts +2 -2
  113. package/scripts/hooks/pretool-guard.ts +45 -2
  114. package/scripts/hooks/run-hook.sh +41 -0
  115. package/scripts/init/claude-kit-only-settings.ts +29 -0
  116. package/scripts/init/hook-command-rewrite.ts +18 -35
  117. package/scripts/init/hook-launch.ts +21 -32
  118. package/scripts/init/init-copy-content.ts +8 -2
  119. package/scripts/init/initial-commit.ts +24 -0
  120. package/scripts/init/start-exec.ts +16 -3
  121. package/scripts/init/start-steps.ts +8 -12
  122. package/scripts/issue/issue-auto-ok.ts +95 -0
  123. package/scripts/issue/issue-file-cli.ts +53 -7
  124. package/scripts/issue/issue-file.ts +28 -5
  125. package/scripts/issue/issue-labels.ts +12 -12
  126. package/scripts/issue/issue-rank.ts +1 -1
  127. package/scripts/issue/issue-read-cli.ts +4 -3
  128. package/scripts/issue/issue-read.ts +2 -2
  129. package/scripts/issue/issue-report-failures.ts +6 -2
  130. package/scripts/issue/issue-scout-cli.ts +2 -2
  131. package/scripts/issue/issue-state-cli.ts +2 -2
  132. package/scripts/issue/issue-state.ts +2 -2
  133. package/scripts/issue/issue-wip.ts +70 -0
  134. package/scripts/josh/hook-decision.ts +17 -0
  135. package/scripts/josh/josh-commands-development.ts +10 -0
  136. package/scripts/josh/josh-commands-issue.ts +2 -2
  137. package/scripts/josh/josh-commands-lane.ts +1 -1
  138. package/scripts/josh/josh-commands-project.ts +7 -0
  139. package/scripts/lane/lane-await.ts +46 -2
  140. package/scripts/lane/lane-cli.ts +11 -13
  141. package/scripts/lines/bytes-command.ts +29 -6
  142. package/scripts/observations/observation-ledger-line.ts +1 -1
  143. package/scripts/release/github-release-environment.ts +1 -0
  144. package/scripts/release/github-release.ts +103 -17
  145. package/scripts/release/release-progress.ts +167 -0
  146. package/scripts/release/release-publish.ts +19 -8
  147. package/scripts/release/release-tag.ts +22 -8
  148. package/scripts/rules/decision-oracle-stage.ts +1 -1
  149. package/scripts/rules/decision-oracle.ts +6 -6
  150. package/scripts/rules/delivered-rules.ts +11 -11
  151. package/scripts/rules/direct-pr-create.ts +110 -0
  152. package/scripts/rules/file-body.ts +98 -42
  153. package/scripts/rules/filing-cap.ts +2 -2
  154. package/scripts/rules/filing-offer.ts +1 -1
  155. package/scripts/rules/gh-api.ts +18 -1
  156. package/scripts/rules/implementation-cut.ts +3 -1
  157. package/scripts/rules/lane-background.ts +67 -10
  158. package/scripts/rules/permission-guards.ts +10 -2
  159. package/scripts/rules/stop-rules.ts +4 -4
  160. package/scripts/rules/test-declared-commit.ts +1 -1
  161. package/scripts/rules/third-party-write.ts +56 -12
  162. package/scripts/run/run-carry-cli.ts +3 -1
  163. package/scripts/run/run-carry-conversation.ts +94 -0
  164. package/scripts/run/run-carry-reclaim.ts +37 -0
  165. package/scripts/run/run-carry.ts +21 -5
  166. package/scripts/run/run-cut-handoff.ts +21 -1
  167. package/scripts/run/run-entry-cli.ts +11 -3
  168. package/scripts/run/run-hold-cli.ts +16 -2
  169. package/scripts/run/run-label.ts +50 -0
  170. package/scripts/run/run-merge-steps.ts +12 -4
  171. package/scripts/run/run-merge.ts +1 -1
  172. package/scripts/run/run-prep-cli.ts +6 -2
  173. package/scripts/run/run-prep.ts +17 -0
  174. package/scripts/run/run-ship-preflight.ts +34 -3
  175. package/scripts/run/run-ship-review-steps.ts +1 -1
  176. package/scripts/run/run-ship-review.ts +26 -5
  177. package/scripts/run/run-step-cli.ts +20 -7
  178. package/scripts/run/run-wake-driver.ts +24 -1
  179. package/scripts/run/run-wake-session.ts +2 -1
  180. package/scripts/test/test-declared-logic.ts +1 -1
  181. package/scripts/test/test-related.ts +1 -6
  182. package/scripts/test/test-unit-guard.ts +21 -7
  183. package/scripts/time-runtime/time-batch-guard.ts +52 -16
  184. package/scripts/time-runtime/time-density-hook.ts +20 -2
  185. package/scripts/time-runtime/time-density.ts +4 -3
  186. package/scripts/time-runtime/time-markers.ts +15 -4
  187. package/scripts/time-runtime/time-spans.ts +4 -0
  188. package/scripts/version/npm-registry.ts +11 -1
  189. package/templates/workflows/ci.yml +9 -1
  190. package/templates/workflows/github-release.yml +13 -25
  191. package/.claude/skills/workflow-commands/followup-reference.md +0 -118
  192. package/dist/hooks/chunk-QVLT52OV.js +0 -464
@@ -1,6 +1,6 @@
1
1
  # 独立した呼び出しは同じターンに載せる(joshuafolkken/kit#1304)
2
2
 
3
- `CLAUDE.md` →「Put every call that does not depend on another's result in the same turn」の正典。**常駐側にはトリガと判断基準の 1 行だけが残り、規則本文は `pnpm josh batch:guard` が効く瞬間に配送する**(joshuafolkken/kit#1524、下の「なぜ resident ではなく引き金つき配送に置くか」)。
3
+ `CLAUDE.md` →「Put every call that does not depend on another's result in the same turn」の正典。**常駐側にはトリガと判断基準の 1 行だけが残り、規則本文は `pnpm josh batch:guard` が効く瞬間に配送する**(joshuafolkken/kit#1524、`rule-delivery.md`、`docs/maintainers/turn-batching-rationale.md` → "Why it left residency (joshuafolkken/kit#1524)")。実測・却下した機構案・経緯は `docs/maintainers/turn-batching-rationale.md` にある。
4
4
 
5
5
  ## 何を求めているか
6
6
 
@@ -11,111 +11,37 @@
11
11
  - no → **その呼び出しは、依存していない他の呼び出しと同じターンに載せる**
12
12
  - yes → 結果を待つ。別のターンになるのが正しい
13
13
 
14
- 依存していない呼び出しを 1 つずつ別のターンに出す形が、この規則が禁じているものである。ファイルを 3 つ読むために 3 ターン使う、同じファイルの離れた 3 箇所を直すために 3 ターン使う、`git status` と `pnpm josh issue:state` と `pnpm josh latest:scope` を 3 ターンに分ける — いずれも後続の入力が前の結果を使っていない。
15
-
16
- ## なぜターン数が費用なのか
17
-
18
- **費用は仕事の量ではなく往復の回数にある。** joshuafolkken/kit#1295 の run(1,471 秒 / 153 ターン)で実測した:
19
-
20
- | 種別 | 回数 | ツール実行時間の合計 |
21
- | ---------------------------------------------------------------- | ---: | -------------------: |
22
- | `Edit` | 34 | 48 秒 |
23
- | 読み取り系の小さな `Bash`(`grep` 12 / `sed` 11 / `cat` 4 ほか) | 32 | 6 秒 |
24
-
25
- **ツール自体が動いていたのは合わせて約 54 秒**である。同じ 66 往復が消費した壁時計は 66 × 9〜13 秒 ≒ 600〜850 秒で、1 桁違う。1 ターンあたりの壁時計は 9〜13 秒の狭い帯に収まるので、**ターン数がそのまま run の下限を決めている。**
26
-
27
- ゲート短縮が run を縮めなかった経緯は `docs/maintainers/turn-batching-rationale.md` →「ゲートを削っても run が縮まなかった理由」。
14
+ ファイルを 3 つ読むために 3 ターン使う、同じファイルの離れた 3 箇所を直すために 3 ターン使う、`git status` と `pnpm josh issue:state` を別ターンに分ける — いずれも禁じられた形である。**費用は仕事の量ではなく往復の回数にある。** 1 ターンの壁時計はほぼ一定なので、ターン数が run の下限を決める(実測は `docs/maintainers/turn-batching-rationale.md` → "Why the number of turns is the cost")。
28
15
 
29
16
  ## 判断基準は「依存の有無」であって、呼び出しの種類ではない
30
17
 
31
- 読み取りだけの規則ではない。**`Edit` も同じ規則の対象である** — 同じファイルの離れた領域や、別々のファイルへの編集は、互いの結果を使っていないので同じターンに載る(実測の内訳は `docs/maintainers/turn-batching-rationale.md` →「`Edit` が最大の単一項目だった理由」)。
32
-
33
- 逆に、**依存があるなら分けるのが正しい。** 次はいずれも 1 つ前の結果を入力に使うので、同じターンに載せてはならない。
34
-
35
- - `grep` の結果を見てから、その行番号で `sed -n` を出す
36
- - `git switch` の成否を見てから `pnpm josh latest:scope` を出す
37
- - Edit の対象文字列を確かめるために先にファイルを読む(**Edit の前に読むことは省略できない**)
18
+ **`Edit` も同じ規則の対象である** — 別々のファイルや同じファイルの離れた領域への編集は、互いの結果を使っていないので同じターンに載る。逆に、**依存があるなら分けるのが正しい**: `grep` の結果の行番号で `sed -n` を出す、`git switch` の成否を見てから次を出す、Edit の前に対象を読む(**Edit の前に読むことは省略できない**)。
38
19
 
39
20
  ## 検証ゲートとレビューは往復を減らす対象ではない
40
21
 
41
- **ゲート・レビュー・差分の読み取りを、往復を減らす名目で弱めてはならない。** これは joshuafolkken/kit#1304 の受け入れ条件そのものである。具体的には:
22
+ **ゲート・レビュー・差分の読み取りを、往復を減らす名目で弱めてはならない。** `pnpm josh gate` の出力を絞って失敗の内訳を読まずに進む、`git diff main...HEAD` を一部だけ読んで「指摘なし」とする(`output-bounds.md`)、走らせるべきチェックを落とす — いずれも禁止。**往復を減らすのは「同じ仕事を少ないターンで出す」ことであって、「仕事を減らす」ことではない。**
42
23
 
43
- - `pnpm josh gate` の出力を絞り込んで読む、失敗の内訳を読まずに次へ進む — いずれも禁止
44
- - `git diff main...HEAD` を一部だけ読んでレビューを「指摘なし」と結論づける — 禁止(`output-bounds.md` →「切り詰められた出力を、完全な出力として読まない」と同じ理由)
45
- - 単発の再実行(`pnpm josh lint:related` / `pnpm josh test:related`)をまとめるために、走らせるべきチェックを落とす — 禁止
24
+ ## ガードが見えないところ — ここでは自分で規則を当てる
46
25
 
47
- **往復を減らすのは「同じ仕事を少ないターンで出す」ことであって、「仕事を減らす」ことではない。** 減らしてよいのはターンの数だけである。
26
+ ガードは閉じた履歴(結果が返ったターンの並び)から判定し、共有ターゲットを持つ呼び出しは依存とみなして止めない。機構は `docs/josh-commands-automation.md` →「`josh batch:guard`」、却下した案は `docs/maintainers/turn-batching-rationale.md` → "Rejected mechanisms"、範囲が広がった経緯は `docs/maintainers/turn-batching-rationale.md` → "How the guard's scope grew"。
48
27
 
49
- ## 機構で強制しない理由(却下した案)
50
-
51
- - **PreToolUse フックが「1 件の呼び出しだけを見て、それが独立かどうかを判定する」。** 採れない。**呼び出しの独立性は、1 件の呼び出しからは観測できない。** フックが見るのはこれから走る 1 件だけで、それが直前の結果に依存しているかどうかはフックの入力に無い。依存している正当な直列実行(`grep` → `sed -n`、Edit の前の読み取り)を止めてしまい、しかも止めた側は理由を説明できない。`output-bounds.md` が「形で見分ける案は実データ上で外れる」として PreToolUse guard を却下したのと同じ形である。
52
-
53
- **却下したのはこの判定のしかたであって、`PreToolUse` という機構そのものではない。** joshuafolkken/kit#1390 は**まさに `PreToolUse` フックとして** `pnpm josh batch:guard` を実装し、`.claude/settings.json` で配布している。判定に使うのは、いま出そうとしている 1 件ではなく**閉じた履歴** — 結果が返り終わったターンの並び — である。単発呼び出しのターンが 2 つ続いたことは 1 件からは見えないが、履歴からは見える。上に並べた懸念は、それぞれ設計で避けてある。依存は**共有ターゲット**で見るので `grep` → `sed -n` は止まらず、**書き込みも読み取りとまったく同じ基準で拒否され**(joshuafolkken/kit#1762)、**手元の呼び出しが直前の列と共有ターゲットを持つときは拒否を取り下げる**(書き込み同士を含む)。拒否は 1 つの単発連続につき **1 回だけ**である(窓を超える連続は `docs/maintainers/turn-batching-rationale.md` →「`batch:guard` の拒否窓」)。委譲された子やレビューエージェントは、親の記録を共有せず、それぞれに配送される(`docs/maintainers/turn-batching-rationale.md` →「フォークへの配送の実装(joshuafolkken/kit#1424)」)。機構の全体は `docs/josh-commands-automation.md` →「`josh batch:guard`」にある。範囲が `Bash|Edit|Read` に広がった経緯(joshuafolkken/kit#1509 を含む)は `docs/maintainers/turn-batching-rationale.md` →「書き込みが範囲に入った経緯(joshuafolkken/kit#1762)」、`docs/maintainers/turn-batching-rationale.md` →「読み取りが範囲に入った経緯(joshuafolkken/kit#1798)」、`docs/maintainers/turn-batching-rationale.md` →「事務コマンドが範囲に入った経緯(joshuafolkken/kit#1875)」。
54
-
55
- **ガードが見えないところ — ここでは自分で規則を当てる。**
56
-
57
- - **塞ぎきれないのは「いま中断しているターンの中身」であり、これは transcript から観測できないので設計上残る。** 同じファイルへの編集 3 件を 1 ターンにまとめた場合、先頭だけが拒否され残り 2 件が適用されることはある。**ただし壊れるのではなく失敗する** — 再発行された編集は書いたときの本文に一致するか、一致せずに報告されるかのどちらかである。
58
- - **ファイル全体を書き出す `Write` だけは拒否しない。** 再発行された `Write` は本文を照合しないので、そのターンの兄弟が適用した編集を無言で上書きしうる。根拠は `docs/maintainers/turn-batching-rationale.md` →「中断中のターンと `Write` の除外の根拠」。
59
- - **連続を切るのは「そもそもまとめられない呼び出し」、すなわち結果を次の呼び出しが必要とする委譲である。**
60
- - **`pnpm josh …` は読み取り専用サブコマンドの allow-list(`READ_JOSH_SUBCOMMANDS`)に載るものだけが bundleable である。** 書き込む・外部送信するサブコマンド(`run:progress --mark` はマーカーを書き、`notify` は送信し、`main:sync` / `epic` / `run:hold` は状態を書く)は allow-list に**入れない**。連鎖した行(`&&` / `|` / `>` など)は、先頭の `pnpm` が後続の変更を隠すため読みとしては信用せず、通常判定に落とす。
61
- - ツールを 1 つも呼ばないターンと、ガードが `off` のレーン子 — それぞれ下の「事後の計測」と「実装中の独立編集に効く合成コマンド」。
62
-
63
- - **複数編集を 1 呼び出しにまとめるツールを前提にする。** 前提にできない。この repository が対象とする harness には常に存在するとは限らず、存在しない側では規則が一度も発火しない。`pnpm josh` はどの harness にも存在するので、書き込みは合成コマンド `pnpm josh edit:files` で畳む(下節)。経緯は `docs/maintainers/turn-batching-rationale.md` →「複数編集ツールの前提を joshuafolkken/kit#2366 が反証した経緯」。
64
- - **ターンごとに件数の下限を課す。** 却下。依存が連続する区間では 1 件が正しい答えであり、下限は正しい振る舞いを罰する。上限も下限も持たないのが正しく、**代わりに事後の計測を置く**(次節)。
65
-
66
- harness 側の一般的な指示(「依存のない呼び出しは同じブロックで出す」)は**すでに存在していて、実測では発火していなかった** — 4 本の run で 1 往復あたり 1.13 / 1.04 / 1.03 / 1.00 呼び出し。帰結は `docs/maintainers/turn-batching-rationale.md` →「一般指示が発火しなかったことの帰結」。
28
+ - **いま中断しているターンの中身は見えない。** 同じターンの編集の先頭だけが拒否されることがあるが、壊れるのではなく失敗する — 再発行は本文に一致するか、一致せず報告される
29
+ - **ファイル全体を書き出す `Write` は拒否しない**(再発行が兄弟の編集を上書きしうるため)
30
+ - **`pnpm josh …` は読み取り専用の allow-list(`READ_JOSH_SUBCOMMANDS`)だけが bundleable** — 書き込む・送信するサブコマンドと、連鎖した行(`&&` / `|` / `>`)は通常判定に落ちる
31
+ - **ツールを呼ばないターンと、ガードが `off` のレーン子** — 下の計測と合成コマンドが受け持つ
67
32
 
68
33
  ## 事後の計測 — 実行タイミングレポートの `Round trips:`
69
34
 
70
- 強制の代わりに、**結果が毎回の計測に出る。**
71
-
72
- ```
73
- Round trips:
74
- tool calls 104 over 153 turn(s)
75
- round trips 104 1.00 calls per round trip
76
- ⚠ independent calls are going out one per turn (floor 1.50 calls per round trip)
77
- ```
78
-
79
- - **round trip は「1 ターンがまとめて出した呼び出しのかたまり」1 つ**であって、呼び出し 1 件ではない。まとめて出せば呼び出し数はそのままで往復だけが減る — つまりこの数字は、仕事を減らさずに費用だけ下げたかどうかを直接見せる
80
- - **しきい値は 1.50 呼び出し/往復。** 下回ると 1 行の指摘が出る。少しでもまとめている run は超えるので、これは程度を採点するのではなく**まとめていないこと**を検出する
81
- - **`tool-less turns` の行は、ツールを 1 つも呼ばなかったターン数**(`turn_count − round_trips`、joshuafolkken/kit#1875)。`batch:guard` は発話だけのターンを拒否できない — 呼ぶツールが無く `PreToolUse` が発火しないので、唯一の梃子がこの事後計測である。`Bundling:` はこれを構造上見られない(まとめる対象を持たないターンは列に入らない)。発話だけのターンは自分で減らす(実測は `docs/maintainers/turn-batching-rationale.md` →「`tool-less turns` の実測」)
82
- - 実装は `scripts/time-runtime/time-round-trips.ts`、詳細は `docs/josh-commands.md` の `time` コマンドの項
35
+ 強制の代わりに、結果が毎回の計測に出る。**round trip は 1 ターンがまとめて出した呼び出しのかたまり 1 つ**で、しきい値 1.50 呼び出し/往復を下回ると 1 行の指摘が出る。`tool-less turns` はツールを 1 つも呼ばなかったターン数で、`batch:guard` が拒否できない発話だけのターンは自分で減らす。実装は `scripts/time-runtime/time-round-trips.ts`、詳細は `docs/josh-commands.md` の `time` の項、読み方と実測は `docs/maintainers/turn-batching-rationale.md` → "Reading the round-trip measurement"。
83
36
 
84
37
  ## 実装中の独立編集に効く合成コマンド(joshuafolkken/kit#2202)
85
38
 
86
- **フックが届かない一区間が残っていた — レーン子の実装中の独立編集である。** レーン子(headless `claude -p`)ではガードが `off` なので(#2178)、別々のファイルへ `Read` → `Edit` を交互に出す並びは誰にも止められない。経緯は `docs/maintainers/turn-batching-rationale.md` →「合成コマンドに至った経緯(joshuafolkken/kit#2202)」。
87
-
88
- **しかし 1 手前に確定している — Step 0 が変更ごとに対象ファイルを列挙する。** `pnpm josh read:files` はその点で読み取りを畳む合成コマンドである。`report-format.md` が Step 0 の継ぎ目(`josh lines` の隣)でランをここへ導く**手順**である。
89
-
90
- **梃子の本体は読み取りと編集の脱交互化(de-interleave)。** 交互の並びで編集を分けているのは直前の読み取りへの依存で、読み取りを 1 回に畳めば続く別ファイルへの編集は互いにも直前の読み取りにも依存せず 1 ターンに載る。#2178 の並び — `Read A` / `Edit A` / `Read B` / `Edit B` … の **9 ターン** — が、`read:files A B C D` → `Edit A` + `Edit B` + `Edit C` + `Edit D` の **2 ターン**になる。
91
-
92
- 上限超過時は `read:files` が「Read ツールで 1 ターンにまとめて読め」と返しフォールバックでも読み取りは畳まれたまま。詳細は `docs/josh-commands-automation.md` →「`josh read:files`」。
93
-
94
- 書き込みは `pnpm josh edit:files` で畳む(joshuafolkken/kit#2366) — 編集を **プラン(`=====` のパスヘッダ+ git conflict マーカー対)** として受け取り 1 呼び出しで適用し、各編集は content-addressed なので `old` が 1 箇所に一致しなければ拒否して報告する。#2493 で `-`(標準入力)を受け、依存編集は `dependent` で拒否する。詳細は `docs/josh-commands-automation.md` →「`josh edit:files`」。
39
+ レーン子ではガードが `off` なので、`Read` → `Edit` の交互の並びは誰にも止められない。**Step 0 が対象ファイルを列挙した時点で、`pnpm josh read:files <path> …` で読み取りを 1 回に畳み、続く別ファイルへの編集を 1 ターンに載せる**(`report-format.md` が導く)。書き込みは `pnpm josh edit:files` で畳む(joshuafolkken/kit#2366) — プランを 1 呼び出しで適用し、`old` が 1 箇所に一致しなければ拒否する。形式は `docs/josh-commands-automation.md` →「`josh read:files`」と「`josh edit:files`」、経緯は `docs/maintainers/turn-batching-rationale.md` → "The composite commands"。
95
40
 
96
41
  ## ガード発火時にも合成コマンドを手渡す(joshuafolkken/kit#2311)
97
42
 
98
- ガードが**単発の読み取り連続**で発火したとき、通知はその読み取りを畳む `pnpm josh read:files <path> …` を貼り付け可能な形で手渡す — モデルが 1 ターンで確実に出せる単一の呼び出しである。経緯は `docs/maintainers/turn-batching-rationale.md` →「ガード通知に合成コマンドを載せた経緯(joshuafolkken/kit#2311)」。
99
-
100
- **読み取りに限り、2 件以上のときだけ。** 書き込みは `read:files` の対象外なので除外し、読み取り 1 件は既に単発なので畳むものがない。
101
-
102
- **書き込み側も同じ地点で手渡す(joshuafolkken/kit#2366)。** 単発 `Edit` の連続でガードが発火したとき、通知はその編集を名指し、それらのファイルにわたる `pnpm josh edit:files` の畳み込みを添える(`write_fold_directive`)。読み取りはパスだけで畳めるが編集は本文を伴うので、貼り付け可能なのはコマンドとファイル名までで、プラン本体はモデルが書く — それでも並列 `tool_use` ブロックではなく 1 ターンで出せる単一呼び出しに落ちる。`Edit` だけを数え、content-address できない `Write`(既に独自の通知を持つ)は除く。
103
-
104
- ## なぜ resident ではなく引き金つき配送に置くか(joshuafolkken/kit#1524)
105
-
106
- **この規則は常駐から外れている。** `pnpm josh batch:guard` が、単発呼び出しのターンが 3 つ続いた次の呼び出し(`Bash` / `Edit` / `Read`)を拒否し、そこで規則本文を突きつける — 規則が効く瞬間そのものである。配送の判定基準と機構は `rule-delivery.md` にある。
107
-
108
- 常駐から外した根拠は `docs/maintainers/turn-batching-rationale.md` →「常駐から外した根拠(joshuafolkken/kit#1524)」。
109
-
110
- **引き金が発火しないターンでは何も起きず、それが正しい。** 発火しないということは往復あたりの呼び出し数が下限(1.50)を上回っているということであり、規則が守られている状態と一致する。
111
-
112
- 配送文(`scripts/time-runtime/time-batch-guard.ts` の `REASON`、および `time-density.ts` の実行時 1 行)が運ぶのは次の 2 点である。常駐側に残していたのと同じ内容であり、削っていない。
113
-
114
- 1. 別の呼び出しの結果に依存しない呼び出しは、同じターンに載せる
115
- 2. 判断基準は「依存の有無」であって呼び出しの種類ではない(読み取りも編集も同じ)。かつ、往復を減らすことは仕事を減らすことではない
116
-
117
- 実測値・却下した機構案・計測の読み方はこのファイルと `docs/maintainers/turn-batching-rationale.md` にあり、配送文からは落としている。
43
+ 単発の読み取り(2 件以上)の連続でガードが発火すると、通知はそれを畳む `pnpm josh read:files` を貼り付け可能な形で渡す。単発 `Edit` の連続では、それらのファイルにわたる `pnpm josh edit:files` を添える(プラン本体はモデルが書く)。渡されたら、その 1 呼び出しで出し直す。
118
44
 
119
45
  ## マーカーテスト
120
46
 
121
- `scripts/rules/turn-batching-rule.test.ts` が固定する。内訳は `docs/maintainers/turn-batching-rationale.md` →「マーカーテストが固定するもの」。
47
+ `scripts/rules/turn-batching-rule.test.ts` が固定する。内訳は `docs/maintainers/turn-batching-rationale.md` → "What the marker test pins"。
@@ -4,37 +4,35 @@
4
4
 
5
5
  ### 無条件ルール: 起票は確認なし、停止は必ず
6
6
 
7
- **この手順に「これは今の作業をブロックするか?」という判定は一切存在しない。** 上流の欠陥は、ブロックするものもしないものも、**発見した時点で**同じ手順を通る。例外はない。
7
+ **この手順に「これは今の作業をブロックするか?」という判定は一切存在しない。** 上流の欠陥は、ブロックするものもしないものも、**発見した時点で**同じ手順を通る。例外はない。判定を置かない理由は `docs/maintainers/upstream-interrupt-rationale.md` → "Why there is no blocking test" にある。
8
8
 
9
- - **トリガーは「発見」であって「ブロックし始めたとき」ではない**。ブロック判定は作業を先へ進めたい圧力の下で下されるため、回避策が最も魅力的な瞬間に「ブロックしない」へ倒れる。しかも「ブロックするか」の線は発見時点には存在しない — 非ブロックに見えた欠陥が完了ゲートで初めて牙を剥いたときには、既に手心が加えられた後である。判定そのものを置かないことで、一時凌ぎがツリーに入る前にルールが発火する
10
- - **起票は Tier A(確認なし)**。起票してよいか、どのリポジトリへ起票するか、いずれもユーザー確認を取らない。起票は元々このルールが指示している行動であり、確認は何も生まない。**ただしこれが成り立つのは対象が first-party のときだけ**であり、third-party リポジトリへの書き込みは Tier C として明示指示を要する(→「第三者リポジトリへの書き込みは Tier C(明示指示が必要)」)
9
+ - **トリガーは「発見」であって「ブロックし始めたとき」ではない**
10
+ - **起票は Tier A(確認なし)**。起票してよいか、どのリポジトリへ起票するか、いずれもユーザー確認を取らない。対象は first-party に限る(→「第三者リポジトリへの書き込みは Tier C(明示指示が必要)」)
11
11
  - **停止は無条件**。Issue が存在する状態にしてから停止する。上流の修正を待つか先送りするかは、Issue を目の前にしたユーザーが決める
12
- - **多少の冗長さは許容コスト**。ユーザーが素通りさせたはずの発見で停止しても往復 1 回で済むが、見送るべきだった発見を素通りさせると、回避策が全消費者に配布されるリポジトリへ入る。たまに外す判断より、毎回適用する一律ルールを採る
13
- - **`backlogrun` の中では、停止の範囲がセッション全体ではなくその子 Issue に限定される**。起票は変わらず無条件(first-party なら Tier A)で、回避策の禁止も変わらない。変わるのは停止の及ぶ範囲だけであり、該当の子に `needs-decision` を付けて park し、依存していない他の子へ進む(→「backlogrun — 子 Issue の無人実行」)。回避策を書かせないという本来の目的は、起票と回避策禁止が保たれることで維持される
12
+ - **`backlogrun` の中では、停止の範囲がセッション全体ではなくその子 Issue に限定される**。起票と回避策の禁止は変わらない。該当の子に `needs-decision` を付けて park し、依存していない他の子へ進む(→ `.claude/skills/workflow-commands/backlogrun-park.md` → "park and continue")
14
13
 
15
14
  手順:
16
15
 
17
16
  1. **現在の作業を退避する**: `git stash push -u -m "upstream-interrupt: paused #<N>"`(WIP コミットでも可)。退避したことを忘れないよう、この時点で stash を作る。メッセージ付きで積むのは、復元をメッセージで特定するため(下記ステップ 5)
18
17
  2. **進行中の Issue に状況を明記する**: `pnpm josh issue:comment <N> --body-file <path>` で、(a) 作業を stash したこと、(b) 中断理由(どの別パッケージの・どんな問題で中断したか)、(c) 対象パッケージに作成した新 Issue へのリンクを `## Upstream issues` 見出しの下に `owner/repo#N` 形式で、を記載する。これにより「なぜこの Issue が一時停止しているか」と「何を待っているのか」が後から監査できる(→「起票元へのバックリンク」)
19
- 3. **対象パッケージのリポジトリに新しい Issue を作成する(確認なし)**: `pnpm josh issue:file "<root-cause title>" --body-file <body-file> --depth <n> --route tier-a --repo <owner>/<repo>`(`route:tier-a` は実装中の Tier A 起票を経路として集計するためのラベル — joshuafolkken/kit#1083。付与するのは first-party の場合だけで、third-party はコマンド自身が拒否し起票しない)。本文の検査、本文が宣言する分類ラベルの付与、`## Origin` 節の確認、起票先での重複探し、`epic:bundle` はこのコマンドが実行する(`docs/josh-commands-automation.md` → `josh issue:file`)。分類の単一ソースは `prompts/collaboration-workflow/issue-template.md`。根本原因・再現・期待結果を Step 1 のテンプレに沿って記載し、**本文に `## Origin` 節を置いて起票元 Issue を `owner/repo#N` 形式で書く**(→「起票元へのバックリンク」)。上流 Issue は欠陥を、起票元 Issue は証拠を持つため、リンクがないと上流 Issue は後から解釈できなくなる。ここで「起票してよいか」を尋ねて停止してはならない。**ただし確認なしで起票してよいのは対象が first-party のときだけ**で、third-party(owner が自リポジトリと一致しないリポジトリ)なら起票せずに停止する(→「第三者リポジトリへの書き込みは Tier C(明示指示が必要)」)
18
+ 3. **対象パッケージのリポジトリに新しい Issue を作成する(確認なし)**: `pnpm josh issue:file "<root-cause title>" --body-file <body-file> --depth <n> --route tier-a --repo <owner>/<repo>`(`route:tier-a` は実装中の Tier A 起票を経路として集計するためのラベル — joshuafolkken/kit#1083)。本文の検査、本文が宣言する分類ラベルの付与、`## Origin` 節の確認、起票先での重複探し、`epic:bundle` はこのコマンドが実行する(`docs/josh-commands-automation.md` → `josh issue:file`)。分類の単一ソースは `prompts/collaboration-workflow/issue-template.md`。根本原因・再現・期待結果を Step 1 のテンプレに沿って記載し、**本文に `## Origin` 節を置いて起票元 Issue を `owner/repo#N` 形式で書く**(→「起票元へのバックリンク」)。ここで「起票してよいか」を尋ねて停止してはならない
20
19
  4. **`confirmation` Telegram を送って停止する**: 上流 Issue の URL と、何が止まっているかを本文に書く(→ `CLAUDE.md` → "Mid-workflow stop notification (`confirmation`)")。無人実行でも画面外でユーザーが気付ける。停止は Issue が既に存在する状態で行うので、ユーザーは「待つ / 先送りする」を Issue を見ながら 1 語で答えられる
21
20
  5. **元の作業を再開する**: 上流の修正がマージされた、または**ユーザーが先送りを明示判断した**後に `pnpm josh stash:pop "upstream-interrupt: paused #<N>"`(位置指定や引数なしの `git stash pop` は使わない — stash は全 work tree が共有する 1 本のスタックで、別のレーンの stash を取り込む恐れがある)して、退避していた元タスクを続行する。上流 Issue を割り込みで実装するかどうかもユーザーの判断(上流パッケージの実装・PR・マージはそれぞれのワークフロー規則に従う)
22
21
 
23
22
  ### 第三者リポジトリへの書き込みは Tier C(明示指示が必要)
24
23
 
25
- 上の「起票は確認なし」は **first-party の集合**(kit / app-kit / game-kit / jgame)を前提に書かれている。トラッカーが自分たちのもので、重複起票のコストがバックログ 1 行で済むからである。**自分たちが所有しないリポジトリへの書き込みは、これとは別物**として扱う。
24
+ 上の「起票は確認なし」は **first-party**(`pnpm josh repo:party` が `first-party` と答えるリポジトリ)だけに成り立つ。**自分たちが所有しないリポジトリへの書き込みは、これとは別物**として扱う。
26
25
 
27
- - **判定は機械的に行い、判断に委ねない**: `pnpm josh repo:party [<owner/repo>]` が `first-party` / `third-party` / `unknown` の 1 語で答える(対象リポジトリの owner がセッションのリポジトリの owner と一致すれば **first-party**、owner を読めなければ **unknown** で third-party 扱いはしない)。**それ以外は全て third-party** で、fork も、単に contribute しているだけの org リポジトリも third-party に入る。この判定は `delivered-rules.ts` の `third-party-write` ルールが同じ計算を使って third-party への `gh api` 書き込みを拒否する(読み取りは素通し)
28
- - **first-party は従来どおり**: Tier A。確認なしで起票し、双方向バックリンクを書き、停止する。kit / app-kit / game-kit のフローに新しい摩擦は加わらない
29
- - **third-party は書き込みの種別を問わず Tier C**: Issue・コメント・PR・Discussion・レビューのいずれも、**その turn におけるユーザーの明示指示**なしに行ってはならない。公開は外向きかつ実質不可逆で、Issue はユーザーの GitHub アカウント名義で公開され、watcher へ通知され、検索に載る。後からクローズしてもそのいずれも取り消せない。加えて、誰も差し出すと約束していないメンテナの時間を消費する
26
+ - **判定は機械的に行い、判断に委ねない**: `pnpm josh repo:party [<owner/repo>]` が `first-party` / `third-party` / `unknown` の 1 語で答える(対象リポジトリの owner がセッションのリポジトリの owner と一致すれば **first-party**、owner を読めなければ **unknown** で third-party 扱いはしない)。**それ以外は全て third-party** で、fork も、単に contribute しているだけの org リポジトリも third-party に入る
27
+ - **first-party は従来どおり**: Tier A。確認なしで起票し、双方向バックリンクを書き、停止する
28
+ - **third-party は書き込みの種別を問わず Tier C**: Issue・コメント・PR・Discussion・レビューのいずれも、**その turn におけるユーザーの明示指示**なしに行ってはならない。公開は外向きかつ実質不可逆である(`docs/maintainers/upstream-interrupt-rationale.md` → "Why third-party writes are Tier C")
30
29
  - **third-party だと判明したときの手順**: (1) **自分たちの側の Issue** に証拠込みで所見を記録する。見出しは `## Upstream candidate` を使い、`## Upstream issues` は使わない(後者は「起票済み」を主張する見出しであるため)。(2) 報告本文の下書きをその Issue 内に用意し、ユーザーが 1 メッセージで承認できる状態にする。(3) 対象プロジェクト名と報告しようとしている内容を書いた `confirmation` Telegram を送って**停止する**
31
30
  - **third-party 報告の証拠バー**(下書きを提示する前に満たす):
32
31
  - **自プロジェクトの外で成立する最小再現**(対象の依存だけを入れた素の scaffold)。用意できない場合は「プロジェクト組み込みの再現しかない」ことを下書きに明記する
33
32
  - **本文の全主張が検証済み**であること。推測を事実として書かない
34
33
  - 同じ欠陥を扱う**既存 Issue の検索**
35
34
  - **取り下げも外向きの行為**: 既に起票した third-party Issue のクローズ・編集・コメントも、同じく明示指示を要する
36
- - **正しい診断は公開の許可ではない**。sveltejs/kit#16623 の事例では所見自体は上流のソースで検証可能な正しいものだったが、手順として誤っていた。所見の正しさは、この節のどの要求も免除しない
37
- - このルールは横断ドキュメント(CLAUDE.md「Third-party repositories are Tier C」)のカノニカル参照
35
+ - **正しい診断は公開の許可ではない**。所見の正しさは、この節のどの要求も免除しない(事例: `docs/maintainers/upstream-interrupt-rationale.md` → "Why a correct diagnosis is not authorization")
38
36
 
39
37
  ### 検証ゲートを緩めることも「回避策」である
40
38
 
@@ -47,5 +45,5 @@
47
45
  注意:
48
46
 
49
47
  - **即席回避と根本対応は「迷って選ぶもの」ではない**。上流起因と分かった時点で選択肢は根本対応だけであり、「今回は軽いから即席で」という判断はこの手順に存在しない
50
- - 別パッケージへの新 Issue 作成・stash・Issue コメントは可逆かつ低コストな調査/起票操作なので、Tier C(不可逆・共有状態の操作)ではなく Tier A として確認なしで進める。ただし上流パッケージの **マージ等の共有状態操作** は通常どおりそれぞれのワークフローの明示起動を要する。**「可逆かつ低コスト」という前提が成り立つのは自分たちが所有するリポジトリに対してだけ**で、third-party への起票は外向き・実質不可逆なので Tier C になる(→「第三者リポジトリへの書き込みは Tier C(明示指示が必要)」)
51
- - このルールは横断ドキュメント(CLAUDE.md「Cross-package problems → file the upstream Issue, then always stop」)のカノニカル参照
48
+ - 上流パッケージの **マージ等の共有状態操作** は、起票と違って Tier A ではない。通常どおりそれぞれのワークフローの明示起動を要する
49
+ - このルールは横断ドキュメント(CLAUDE.md「Cross-package problems → file the upstream Issue, then stop」)のカノニカル参照
@@ -10,18 +10,11 @@
10
10
 
11
11
  **オープン Issue が上限を超えている状態で新しく起票するときは、先に 1 件閉じる。**
12
12
 
13
- 件数は毎回数える。見積もりでも記憶でもない。
13
+ **件数は `pnpm josh issue:file` が起票の前に数える**(joshuafolkken/kit#3181)。手で数えることも、見積もりや記憶で済ませることもない。数え方・印字・保留の詳細は `docs/josh-commands-automation.md` → "`josh issue:file`" にある。
14
14
 
15
- ```bash
16
- gh api "repos/{owner}/{repo}/issues?state=open&per_page=100" --paginate \
17
- --jq '.[] | select(.pull_request == null) | .number' | wc -l
18
- ```
19
-
20
- - **数えるのは「起票しようとしているリポジトリ」のオープン Issue 全件**である。`{owner}/{repo}` はカレントリポジトリに展開されるので、**別リポジトリへ起票するときはそのリポジトリのパスを直接書く**(例: `repos/joshuafolkken/app-kit/issues?...`)。自リポジトリの件数で他リポジトリへの起票を判断するのは、別のバックログを見ているのと同じである。
21
- - epic も子も含める。epic を除外すると、epic を作ることで上限を回避できてしまう。
22
15
  - **上限は 30。** これを超える 1 件を作る前に 1 件閉じる。エージェントが読む文書(`CLAUDE.md`・`prompts/`・配布 skill)がこの数字を書くのはこの行だけで、一次情報は `scripts/rules/delivered-rules.ts` の `WIP_CAP` である(一致はテストが固定する)。
23
- - **プルリクエストは数えない。** REST の `issues` エンドポイントは PR も返すため、`select(.pull_request == null)` で落とす。この 1 句を省くと、PR が開いているだけで上限に達する。
24
- - **`gh issue list` は使わない。** 配布ドキュメントの実行可能ブロックに置ける `gh` は REST のものだけで、`gh issue list` は GraphQL 経由のためクラウドセッションで 403 になる。
16
+ - コマンドは起票先(`--repo` を付ければそのリポジトリ)のオープン Issue を epic も含めて数え、`wip:` 行に件数・上限・判定を印字する。上限を超えて免除が宣言されていなければ**何も送らずに保留し、免除の問いを印字する**。
17
+ - **免除を宣言するのはこのファイルの判断である** — `--route interrupt`(下の 3 条件)、`--route split` / `--route tier-a`(実行が詰まる起票)はルートそのものが宣言になる。ルートの無い実行が詰まる起票(利用者が `new` と打った入口など)は `--over-cap` を付けて出し直す。裁量起票(`--route review-cap` を含む)に `--over-cap` を付けてはならない。
25
18
 
26
19
  ## なぜ上限が要るのか
27
20
 
@@ -45,7 +38,7 @@ gh api "repos/{owner}/{repo}/issues?state=open&per_page=100" --paginate \
45
38
 
46
39
  ### 実行が詰まる起票 — 上限が効かない側
47
40
 
48
- 前提 Issue(`SKILL.md` → §2d)、別パッケージ起因の割り込み Issue、ユーザーが `new` と打った入口、`issue:scout` が重複無しと答えた新規作業、**そして分割判定が作る子 Issue と epic**。**これらは起票しないと実行が進まない。**
41
+ 前提 Issue(`prerequisite.md`)、別パッケージ起因の割り込み Issue、ユーザーが `new` と打った入口、`issue:scout` が重複無しと答えた新規作業、**そして分割判定が作る子 Issue と epic**。**これらは起票しないと実行が進まない。**
49
42
 
50
43
  - **上限を理由に止めない。** 理由は `docs/maintainers/wip-cap-rationale.md` →「実行が詰まる起票を止めない理由」。
51
44
  - **分割の子がここに入る理由**: 分割を検出した `fullrun` / `halfrun` は「子と epic を起票して **STOP**」と定められている(`fullrun.md` / `halfrun.md`)。**分割するかどうかを決めるのは分割判定の側**で、既定はもう「分割しない」に上がっている — 上限が二重に効く必要はない。
@@ -78,41 +71,9 @@ gh api "repos/{owner}/{repo}/issues?state=open&per_page=100" --paginate \
78
71
  ```
79
72
 
80
73
  2. **超過している事実と、当たった条件の番号を本文に 1 行書く**(例:「オープン 37 件で起票。3 条件のうち 2(文書化された手順が完了できない)に該当」)。**どちらか一方では足りない** — 件数だけでは判定が再現できず、条件だけでは上限の可視化が効かない。
81
- 3. **次に実行されるものとして挿入する。** epic の下にあるなら `pnpm josh epic --add <E> <N>` で、**位置を指定せずに**追加する(`<E>` が epic、`<N>` が起票した割り込み)。**`--before` / `--after` を使ってはならない。** それらは `blocked-by` 関係を実際に書き込むため(`docs/josh-commands-automation.md` →「`josh epic --add`」)、「発見したランをブロックしていない欠陥」という割り込みの定義と矛盾する**偽の依存関係**になり、`epic:next` が実装中の子を「割り込みにブロックされている」として出さなくなる。位置を指定しない追加は依存を一切宣言しない(joshuafolkken/kit#1253)ので、**順序は実行側が持つ** — 次に取り上げるのは実行側の選択であって、宣言された関係ではない(経緯は `docs/maintainers/wip-cap-rationale.md` →「位置を指定しない追加の経緯」)。**先に提示させたいときは `--order-before <M>` を使う**(joshuafolkken/kit#1738)— これはタスクリストの行だけを動かし、依存宣言も `blocked-by` も一切書かないので、上の禁止には当たらない。**禁止しているのは依存を書き込む `--before` / `--after` であって、順序そのものではない。** `epic:next` は runnable な子をタスクリスト順に提示する(joshuafolkken/kit#1583)ため、位置を指定しない追加は「末尾に提示される」を意味する — 割り込みを次に取り上げてほしいなら、行だけを前に出すこの指定がその手段である。**epic の下に無いなら挿入先そのものが無い**ので、この手順は飛ばして 4 だけを行う。
74
+ 3. **次に実行されるものとして挿入する。** epic の下にあるなら `pnpm josh epic --add <E> <N>` で、**位置を指定せずに**追加する(`<E>` が epic、`<N>` が起票した割り込み)。**`--before` / `--after` を使ってはならない。** それらは `blocked-by` を書き込み、「発見したランをブロックしていない欠陥」という割り込みの定義と矛盾する**偽の依存関係**になる。**順序は実行側が持つ** — 先に提示させたいときは、行だけを動かす `--order-before <M>` を使う。仕組みと経緯は `docs/maintainers/wip-cap-rationale.md` →「位置を指定しない追加の経緯」。**epic の下に無いなら挿入先そのものが無い**ので、この手順は飛ばして 4 だけを行う。
82
75
  4. **着手は、既にある承認の内側でのみ、指示を待たずに行う。** `backlogrun` の中なら、打たれたキーワードがバッチを承認しているので、割り込みは次の子として着手してよい。**バッチの外では `CLAUDE.md` →「Explicit invocation required」が変わらず効く** — 起票と挿入まで済ませたうえで、利用者に打つべきコマンド(`fullrun #<N>`)を報告して止まる。**割り込みは上限の例外であって、明示起動規則の例外ではない。**
83
76
 
84
77
  **起票と、実行されるようにするところまでが 1 つのまとまりである。** epic の下にある割り込みを起票だけして追加しなければ、`epic:next` はそれを候補にすら出さない — Issue は残るが実行されないという、コメントに埋もれるのと大差ない状態になる。**epic の外にある割り込みでは、まとまりの後半は 4 の報告そのもの**であり、打つべきコマンドを利用者に渡すまでが 1 回の行為である。上の「ひとまとまりで判定する」がここにも効く。
85
78
 
86
- #### 実行のしかた — `main` で誤答している検証の欠陥は単独で走らせる
87
-
88
- **kit 自身の検証が今の `main` で無関係な PR の判定まで誤らせている欠陥を直す Issue は単独で実行し、バッチを再開するのはそれが `main` へマージされてからとする。** 「着地」はマージであって、PR を開いた時点でもレビューが収束した時点でもない。
89
-
90
- **該当するかは判断ではなく、次の 3 条件で決まる。**
91
-
92
- 1. **欠陥である**(`- 種別: 不具合`)。改善・リファクタ・削除・機能追加は当たらない。
93
- 2. **kit 自身の検証の欠陥である。** 検証とは次の 4 つを指し、配布先リポジトリ向けの CI・テンプレートの不具合は当たらない。
94
- - **検証ゲート**(lint / 型チェック / スペルチェック / 単体テスト)
95
- - **コードレビュー**
96
- - **push 時のフック**
97
- - **マージ時のチェック**
98
- 3. **今の `main` で、その Issue と無関係な PR の判定まで誤らせている**(嘘の緑 / 嘘の赤)。効率の問題や、特定の条件でしか起きないものは当たらない。
99
-
100
- **3 条件すべてに当たれば単独実行、1 つでも外れれば `run:lane`。** 単独実行なら `run:solo` を付け、強制はそれを読む `backlog:next` と `epic:next --lanes` が行う(joshuafolkken/kit#2776)。外れれば(改善、機能追加、文書修正、配布先 CI の修正など)`run:lane` を付け、並列バッチの一員として走らせてよい。どちらもなければ `triage` が返り何も始まらない(joshuafolkken/kit#2779)ので、run が起票する Issue(割り込み・分割・前提)は起票時にどちらかを付ける。**「重大だと感じるか」は判定条件ではない**(起票側の 3 条件と同じ理由)。
101
-
102
- **他レーンを止める根拠は 1 つ — 壊れた検証の上でバッチを回すと、全員の結果が信用できないこと。** 割り込み自身の検証が欠陥の影響下にあることはその Issue 自身の扱い(修正後の検証で確かめる)であって、他レーンを止める根拠にはしない。根拠と、判定を条件にした由来・狭めた経緯は `docs/maintainers/wip-cap-rationale.md` →「単独実行の理由と由来」。
103
-
104
- ## 上限そのものを変えるとき
105
-
106
- **上限の数字は Tier C ではない** — 引き上げも引き下げも、測定を添えて提案してよい。ただし**変更は必ず `WIP_CAP` と「規則」節の 1 行を同じコミットで動かす**。片方だけ動かすと一致を固定するテストが落ちる。
107
-
108
- **引き上げる条件は「窮屈だから」ではない。** オープン件数が 7 日移動平均で減り続けていて、なお上限が起票を止めているとき — つまり装置が目的を果たし終えたときだけである。
109
-
110
- ## 3 つは一緒に動く
111
-
112
- 上限は単独では効かない。**製造側を止めないまま上限だけ入れると、製造は続いたまま実行だけが止まる。** 経緯は `docs/maintainers/wip-cap-rationale.md` →「3 つを 1 コミットで着地させた経緯」。
113
-
114
- | 製造元 | 変更 | 単一ソース |
115
- | ------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------- |
116
- | 分割判定 | 既定を「分割しない」に。目安は単一ソースにある | `.claude/skills/workflow-commands/split-assessment.md` → "The question" |
117
- | レビュー round 2 の残指摘 | 既定を branch 3(PR に 1 行残して落とす)に | `prompts/review.md` → "Three-way disposition after the cap" |
118
- | オープン件数 | WIP 上限 | このファイル |
79
+ **割り込みをバッチの中で単独で走らせるか、並列のレーンで走らせるか**は `.claude/skills/workflow-commands/backlogrun-lanes.md` → "Lanes — running more than one child at a time" が単一ソースである(理由は `docs/maintainers/wip-cap-rationale.md` →「単独実行の理由と由来」)。上限の数字の変え方は `docs/maintainers/wip-cap-rationale.md` →「上限そのものを変えるとき」、上限が分割判定・レビュー上限と一緒に動く理由は `docs/maintainers/wip-cap-rationale.md` →「3 つは一緒に動く」と `docs/maintainers/wip-cap-rationale.md` →「3 つを 1 コミットで着地させた経緯」にある。
@@ -8,7 +8,7 @@
8
8
 
9
9
  **これは人間が読むための索引であり、規則を定める場所ではない。** 常駐の引き金は `CLAUDE.md` に、実行中の操作手順は `.claude/skills/workflow-commands/` に、各話題の規則は下の表のファイルにあり、それぞれが自分の規則の一次情報である。この索引はそれらを言い直さない。
10
10
 
11
- **話題ごとにファイルが分かれている。** 以前はこの内容が 1 本の 169KB のファイルにあり、1 つの節を確かめるだけでも全体を読む必要があった。読んだものはそのセッションの残り全ターンで積み上がった前置きとして課金され続けるため、確認 1 回の費用が会話の長さに比例して効いていた(joshuafolkken/kit#965)。**必要な 1 本だけを開くこと。この索引を入口に、下の表から選ぶ。**
11
+ **必要な 1 本だけを開くこと。この索引を入口に、下の表から選ぶ。** 他の文書からこれらの話題を指すときは、索引を経由せず**本文があるファイルを直接指す**([`residency.md`](./collaboration-workflow/residency.md))。
12
12
 
13
13
  | 話題 | ファイル |
14
14
  | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
@@ -30,15 +30,3 @@
30
30
  | コマンド出力が文脈へ持ち込む量の上限 | [`output-bounds.md`](./collaboration-workflow/output-bounds.md) |
31
31
  | 運用ルール | [`operating-rules.md`](./collaboration-workflow/operating-rules.md) |
32
32
  | 用語集 — lane・cut・hold・park などの定義と単一ソース | [`glossary.md`](./collaboration-workflow/glossary.md) |
33
-
34
- **どの 1 本を開けばよいかを決めるのに必要なのは、この索引だけである。** バイト数はここに書かない — 手で保守した数字は本文より先に古くなり、古い数字は無いより悪い。実サイズは `ls -l prompts/collaboration-workflow/` が答える。
35
-
36
- ## 参照の書き方
37
-
38
- `CLAUDE.md` と `.claude/skills/` からこれらの話題を指すときは、**本文があるファイルを直接指す**(話題ファイル、skill へ単一ソース化済みならその skill。[`residency.md`](./collaboration-workflow/residency.md))。索引や指し先を経由させる形(`prompts/collaboration-workflow.md` → 「節名」)は、読み手に 2 回読みを強いるうえ、節名が変わると黙って行き止まりになる。
39
-
40
- ```md
41
- See `prompts/collaboration-workflow/upstream-interrupt.md`.
42
- ```
43
-
44
- `scripts/claude/collaboration-prompt-split.test.ts` が、文書と skill が指すファイルの実在と、この索引が全ファイルを列挙していることを検査する。
@@ -50,10 +50,8 @@ for every finding that passes test 1, and to say so when the attempt failed**: "
50
50
  is a skipped step.
51
51
 
52
52
  **A distributed artifact is on that list deliberately.** `CLAUDE.md`, `prompts/**`, `.claude/**` and
53
- `docs/**` are reviewed at the same level as runtime code: measured on real documentation-only diffs,
54
- a review found ten real defects each — dangling pointers into removed sections, citations naming the
55
- wrong file, in artifacts distributed to every consumer — that no test covered, because prose is what
56
- they were. A severity rule that ranked documentation below runtime code would contradict that.
53
+ `docs/**` are reviewed at the same level as runtime code — a dangling pointer or a citation naming the
54
+ wrong file reaches every consumer, and no test covers prose.
57
55
 
58
56
  **`high` and `low`.** A `high` is fixed before committing and blocks the merge regardless of round
59
57
  count; a `low` that does not reach the user may be skipped with a one-line reason. This section
@@ -214,73 +212,12 @@ allowed.
214
212
 
215
213
  ### 4. Project conventions (`CLAUDE.md`)
216
214
 
217
- **The gate has already run — do not re-verify what lint enforces.** `pnpm josh gate` precedes this
218
- review, and `pnpm josh format:edited` runs `eslint --fix` and `prettier --write` after every `Edit` /
219
- `Write`, so anything ESLint decides has already failed as an error or been corrected before you read
220
- the diff. Re-checking it inflates the first round's finding count.
221
-
222
- **Settled by lint, and therefore not checked here** — each one verified against the rule that
223
- enforces it, never assumed:
224
-
225
- - **Naming** — `@typescript-eslint/naming-convention` (`eslint/rules/naming-convention.js`).
226
- - **`export default`** — `import/no-default-export` is `error` project-wide (`eslint/rules/import.js`),
227
- switched off only for `*.d.ts` in `eslint/base.js`.
228
- - **Individually named exports of function declarations, and of consts that are not `UPPER_CASE`** —
229
- `no-restricted-syntax` in `eslint/rules/code-quality.js`. **Its selector exempts
230
- `ArrowFunctionExpression`**, so `export const helper = (s: string): string => s` passes it; that
231
- gap is a reader's job, below.
232
- - **File names** — kebab-case through `unicorn/filename-case`.
233
- - **The `*.spec.*` suffix, and a top-level `tests/` directory** — `eslint/rules/test-filename.js`,
234
- wired into `eslint/base.js` itself, so it holds in kit and in every project built on that base
235
- config. **Both bans cover every JS/TS extension** (`.ts` `.tsx` `.mts` `.cts` `.js` `.jsx` `.mjs`
236
- `.cjs`) and neither covers `.svelte`. **A trailing block switching `no-restricted-syntax` off is
237
- what can still take it away** — so read a diff that adds one as a gate defect, per the last
238
- paragraph of this category.
239
- - **Magic numbers** — `@typescript-eslint/no-magic-numbers`; **`any`, unused vars, floating promises
240
- and explicit param and return types** — `eslint/rules/typescript.js` and `eslint/rules/promise.js`.
241
- - **Identical functions and repeated string literals** — `eslint/rules/sonarjs.js`.
242
- - **Every quality limit below.**
243
-
244
- - **Quality limits**: a reference, enforced by `eslint/rules/code-quality.js` and
245
- `eslint/rules/sonarjs.js` rather than re-checked here — function complexity ≤5, nesting ≤2,
246
- function ≤25 lines, file ≤300 lines, params ≤4, statements per function ≤10,
247
- cognitive complexity ≤4 — **the line counts are code lines, not physical lines**: `max-lines` and
248
- `max-lines-per-function` run with `skipBlankLines` and `skipComments`, so read what
249
- `pnpm josh lint` reports rather than `wc -l`, and test files (`*.test.ts` / `*.e2e.ts`) allow
250
- 35 code lines per function instead of 25 — **`*.spec.ts` is not on that list**, because the same
251
- config bans the name outright.
252
-
253
- **What only a reader can see — check these:**
254
-
255
- - **`function` syntax rather than an arrow const** — **no rule enforces this**: there is no
256
- `func-style` and no arrow selector anywhere in `eslint/`, and the named-export selector above
257
- explicitly exempts `ArrowFunctionExpression`. So `const do_thing = (n: number): number => n + 1` and
258
- `export const helper = (s: string): string => s` both lint clean, and this review is the only thing
259
- between either and the default branch. The route-file exemption in `CLAUDE.md` covers the named
260
- route handlers and nothing else.
261
- - **The early-return one-liner** — `curly` is configured `['error', 'multi-line']`, which requires
262
- braces on a multi-line body and never requires the one-liner form. A short `if (x) { return y }`
263
- passes lint, so "single `return` under 100 chars → one-liner `if (x) return y`" is a reader's check.
264
- - **Duplication that is not identical** — `sonarjs/no-identical-functions` sees only functions that
265
- match. Two implementations of one idea in different shapes are invisible to it, and they are exactly
266
- what "No clones — single-source" is about, package boundaries included.
267
- - **A name that satisfies the convention and says the wrong thing** — `naming-convention` checks the
268
- shape, never the meaning. An `is_` prefix on a function that returns a parsed value passes lint and
269
- misleads every caller.
270
- - **Grouping and layout** — a namespace object that collects unrelated functions, or a file whose
271
- contents no longer match what its name says. Structure is not something lint judges.
272
- - **Svelte semantics** — `$state` reassignment, `Props` as an interface name, restricted DOM
273
- manipulation, and `PascalCase.svelte` / `PascalCase.svelte.ts` file names where the project's lint
274
- does not cover them.
275
- - **Test placement beyond the two banned patterns** — the ban above decides the `*.spec.*` suffix and
276
- the top-level `tests/` directory, and nothing else. **A `tests/Foo.svelte` is outside both**, so it
277
- is a reader's check. Colocation itself is what it cannot see: a test that avoids both and still sits
278
- in a directory away from the code it exercises lints clean, and so does an `*.e2e.ts` placed outside
279
- `src/routes/**`.
280
-
281
- **A gate finding that got through is still a finding.** If lint could have caught something and did
282
- not — a disabled rule, an ignored path, an `// eslint-disable` the change added — say so. That is a
283
- defect in the gate, and no other step is looking at it.
215
+ **Do not re-check what lint enforces — the gate has already run; lint does not catch `function`
216
+ syntax over an arrow const (outside named route handlers), the early-return one-liner, duplication
217
+ that is not identical, a name whose shape passes but whose meaning misleads, grouping and file layout,
218
+ Svelte semantics, or test placement beyond the `*.spec.*` / top-level `tests/` bans, so check those.**
219
+ A lint gap the change opens — a disabled rule, an ignored path, an added `eslint-disable`, a block
220
+ switching `no-restricted-syntax` off — is itself a finding.
284
221
 
285
222
  ### 5. i18n
286
223