review-converge: diff-review 収束ループ
diff-review を呼ぶだけのパイプスキル。レビュー本体(差分収集・レンズ・reviewer 起動・統合報告)は
diff-review の責務で、こちらはその read-only 単発設計に手を触れず、修正と再レビューの繰り返しと
停止判断だけを担う。
修正はメインセッション(あなた)が行う。ループ制御の決定論部分は scripts/converge_state.py が担い、
続行・収束・上限・振動の判定はスクリプトの verdict に従う(自分で判断しない)。
以下、<SKILL_DIR> はこのスキルの base directory(スキル起動時に表示される絶対パス)を指す。
引数
/review-converge [--until <must|want+|want|nit>]
--until: 収束閾値。この重み以上の fix 指摘(境界内)がゼロになったら収束とする。既定 want。
improvement(改善提案)は severity に関わらず収束判定・修正対象から外れる(手順 2 の kind)
- severity の語彙と意味論(must / want+ / want / nit・実害ベースの判定)は diff-review 側の定義が正。
こちらで再定義しない
- 閾値
want なら nit は残っていても収束。must なら want 系も残せる
事前準備
-
起動ゲート(モデル判断で起動したときのみ): このループは修正コミットを伴い複数周回するため、
1 周目に入る前に「対象範囲(base-ref)・適用閾値・上限周回数(既定 5)・レンズ」を提示して
ユーザーの承認を取る。/review-converge で明示起動された場合はこのゲートを省略してよい
-
状態ファイルのパスを決める。
$(git rev-parse --show-toplevel)/tmp-agents/review-converge/$(git rev-parse --abbrev-ref HEAD | tr '/' '-')/review-converge-state.json
に置く。以降 <STATE> と呼ぶ。親ディレクトリは mkdir -p で先に作る(手順 3 の reset は
ファイルを消すだけで、ディレクトリを作る record より先に集約エージェントの統合報告の
書き出しが走るため、作っておかないと 1 周目の書き出しが失敗する)。ブランチ名のサブディレクトリで分けるのは、tmp-agents/ が
worktree 間で symlink 共有されうるためで、分けないとレーン間で状態ファイルと統合報告が衝突する。
セッションの scratchpad は使わない(集約エージェントの書き込みガードが出力先を worktree 内に
拘束しており、hook へ scratchpad のパスを伝える経路が無いため、統合報告の書き出しが拒否される)
-
途中から再開ではなく新規に回す場合、既存の状態を消す:
python3 <SKILL_DIR>/scripts/converge_state.py reset --state <STATE>
-
グラウンドトゥルースと規約の確定(1 周目の前に本体で行い、全周回で固定する): 集約エージェントは
AskUserQuestion を持たないため、diff-review が定める「候補の採否をユーザーに確認する」手順は
集約経由では到達しない(候補を検出したまま 4 周とも未採用・spec レンズ非昇格で回った実例)。
1 周目に入る前に本体で diff-review の「候補の確定手順」を実行する:
<SKILL_DIR>/../diff-review/scripts/collect-diff.sh manifest [<base-ref>] | sed -n '1,/== COMMITS/p'
(GROUND_TRUTH 節は無いこともあるが CONVENTIONS 節は常に出るので、COMMITS 節の手前までを見る)
(diff-review スキルは同じカテゴリの隣に配置される。無ければ diff-review の base directory を確認する)
- manifest の後、diff-review の確定手順どおり Explore エージェントを 1 体起動して規約文書の候補を探す
(指示文・除外・上限 10 件は diff-review SKILL.md のとおり)。
DIFF_REVIEW_CONVENTIONS に none が
含まれるときは起動しない
- GROUND_TRUTH の
候補(規定パス外...) と Explore の規約候補があれば、1 回の AskUserQuestion で
両系統の採否を確認し(質問の要点と候補パスは本文にも列挙する)、採用パスを確定させる。ユーザーが
依頼文でパスを示していれば、その系統の確認を省略して採用する
- 確定した内容を、以降全周回で同じ形で diff-review に渡す(周回ごとに再確認しない)。周回途中で
判断基準が変わると、同じ指摘が出たり消えたりして振動判定を汚染する。渡す形:
- グラウンドトゥルース:
DIFF_REVIEW_GROUND_TRUTH に載せる採用パス / 「候補は使わない」/ 「なし」
- 規約の状態:
DIFF_REVIEW_CONVENTIONS に載せる Explore 採用分の明示注入パス / 「なし(明示注入なし)」。
環境変数で固定するのは Explore 採用分だけ。.claude/rules の paths 照合・祖先 CLAUDE.md などの決定論
探索は毎周回の manifest で再計算され、後の周回で触ったファイルに当たる規約は自然に増える(基準が厳しく
なる方向の単調増加で、振動は生まない)
ループ手順
以下を verdict が continue である限り繰り返す。1 周 = レビュー 1 回 + 修正 1 回。
1. レビューを実施する(集約エージェント経由)
周回のレビューは、このスキル同梱の review-aggregator エージェントを周回ごとに使い捨てで
1 体起動し、その内部で diff-review スキルを実行させる。レンズ数 × 周回数ぶんの reviewer
報告全文を本体セッションのコンテキストへ載せないための構成で、本体には受領突合の結果・
統合報告ファイルのパス・yagni 重点分析・record-ready JSON・GROUND_TRUTH と規約の状態だけが返る。
Agent ツールで review-aggregator を name を付けずに起動する(name を付けると teammate になり、
返却が完了通知ではなく idle 通知になってターン境界まで届かない)。結果は完了通知として後のターンに届くので、
通知による起床で待ち、sleep のポーリングはしない。prompt に次を全て含める(欠けると中止して返ってくる):
- 対象範囲(base-ref)と、下記「diff-review への引き継ぎ規定」の該当内容
(レンズ指定・グラウンドトゥルースの状態・規約の状態・前周回 head)
- 手順 2 の
kind 分類規則の転記
- 再指摘禁止リスト(2 周目以降): 前周回の
record / keep 出力の suppress
(file:line / 要旨 / 理由)をそのまま転記する。空配列なら「再指摘禁止リスト: なし」と書く
- 統合報告ファイルの出力先:
<STATE> と同じディレクトリの
review-converge-round-<周回番号>.md(絶対パス)
- 修正時に指摘の詳細文脈が必要なら、統合報告ファイルから必要な指摘だけ Read する
(全文を無差別に読み込まない)
- フォールバック: 集約エージェントの完了通知が届いたのに返却 6 項目が揃わないとき
(完了通知がまだ届いていない間は実行中であり、発動条件に当たらない)、その周回の統合報告ファイル
(
review-converge-round-<周回番号>.md)が存在し、冒頭の 対象: に現周回の HEAD の sha
(短縮 sha なら前方一致)が、レンズ欄に受領/起動の内訳が読み取れるなら、
再起動せず本体が統合報告から record-ready JSON を構成する(手順 2 の kind 分類・yagni 指摘の
優先判別は本体が行う。受領突合はレンズ欄の内訳で判定し、--lenses / --received もそこから作る)。
ファイルが無い・sha が一致しない・どちらかの欄が読み取れなければ従来どおり
1 回だけ再起動する。それでも揃わなければ、この周回は本体から diff-review スキルを
直接起動して従来どおり回す(引き継ぎ規定は同じ。手順 2 の kind 分類・yagni 指摘の
優先判別(レンズタグで判別できる)も自分で行う)
- 本体へ直接届いたレンズ報告は、集約エージェントを失敗と確定してフォールバックに入った後だけ
record の根拠にしてよい。集約エージェントの完了通知を待っている間に届いた reviewer の
報告を先取りして受領に数えると、集約側の突合結果と食い違ったまま記録することになる
- 停止済み周回のエージェントから届く通知は、周回番号または HEAD が現周回と一致しなければ
無視する。再起動やフォールバックで打ち切った前周回のエージェントが後から返すことがあり、
それを現周回の受領に数えると、実施していないレビューの結果で収束判定が動く
diff-review への引き継ぎ規定(集約経由・直接起動のどちらでも適用する):
- 起動方式は diff-review の規定に従う(
Agent ツールで直接並列起動・エージェントチームを構成しない)。
name を付けて teammate 化すると、最終回答が完了通知ではなく idle 通知になってターン境界まで届かず、
取りこぼしで周回が空転して収束しない。レンズの結果は完了通知として後のターンに届くので、全レンズの
完了通知を待ってから突合する。完了通知が届いたのに報告本文が無いレンズの扱い(1 回再起動 → 「結果なし」の
明記)は diff-review の受領突合に従う
- 2 周目以降(差分レビュー最適化): 先に
python3 <SKILL_DIR>/scripts/converge_state.py prev-head --state <STATE> で前周回の head sha を取得し、
diff-review へ「前周回 head は <sha>。そこからの差分が今回の修正であり、レビューの重点はそこに置く」
と伝える。全体の manifest 範囲は変えない(退行を見落とさないため)が、reviewer の精読対象を
前周回差分に寄せることでトークン消費を抑える
- 再指摘禁止リスト(2 周目以降): 前周回の出力
suppress を diff-review へ「次の箇所は本体が
保持を決定した、または閾値未満で見送った箇所。同じ file:line・同趣旨の指摘を出さない。
severity を上げる新事実があるときだけ、その事実を添えて出す」と伝える。各周回の reviewer は
前周回の経緯を知らないため、これを渡さないと他レンズが要求して入れた記述を別レンズが
「過剰」と削らせる打ち消し合いが周回を跨いで起きる(README のみの diff で 5 周回した実例)
- レンズ指定はユーザーの依頼をそのまま引き継ぐ。無指定なら diff-review の既定に任せる
(グラウンドトゥルース検出時は
spec レンズが既定に昇格する)
- 起動引数
--improvement を付けない(既定モード = fix のみ、のまま呼ぶ)。このループの
修正対象は fix のみ(手順 2 の kind)で、改善提案を集めてもループ内では消化しない
- 事前準備 4 で確定したグラウンドトゥルースの状態を毎周回そのまま diff-review へ渡す
(採用パスがあれば
DIFF_REVIEW_GROUND_TRUTH に載せるパス、候補を使わないと決めたなら
その旨、無ければ「なし」)。周回ごとに候補の再確認はしない。「候補は使わない」も明示して渡す
(渡さないと集約エージェントが候補を未確定のまま報告し、次項の突合で周回が止まる)
- 事前準備 4 で確定した規約の状態(固定した明示注入パス / なし)も毎周回そのまま渡す。diff-review は
これを受け取ると Explore を起動せず渡された状態を使う(省略規則)。渡さないと集約エージェントが毎周回
Explore を起動し、確認できない候補を抱える
- レンズ段階戦略(2 周目以降): 前周回の
record 出力にある next_lenses に従う。
配列が入っていればそのレンズだけを diff-review に指定して起動する。null になるのは
前周回の指摘にレンズ情報が付いていない場合のみで、そのときは絞り込みをせず通常どおり
起動する。自分でレンズを足し引きしない
2. 指摘を JSON へ落として記録する
先に受領突合を確認する: 集約エージェント(または直接起動時は diff-review の統合報告)が
「レンズ欠落」を報告している場合、その周回の指摘は不完全なので指摘ゼロを収束と解釈してはいけない。
欠落したまま [] を record に渡すと、レビューできていない観点を「指摘なし」として
収束判定に通してしまう。欠落が残る周回は record に進まず、ユーザーへエスカレーションして
判断を仰ぐ(欠落レンズを外して続行するか、レビュー自体をやり直すか)。
この突合は record の --lenses(起動したレンズ)と --received(報告を受領したレンズ)で
機械的に検証される。渡す値は次で作る: --lenses はその周回で起動したレンズ集合
(1 周目は事前準備で確定したレンズ指定、無指定なら集約エージェントの返却 1 項目目
「受領突合の結果」が挙げる起動レンズ、2 周目以降は前周回の next_lenses)。--received は
そこから欠落として報告されたレンズを差し引いた集合。集約エージェントが起動レンズを
報告していない周回は、受領の有無を確かめられないので record に進まずエスカレーションする。受領が起動レンズに満たない周回は exit 2 で拒否されるので、
申告を偽って通さない。ユーザーが「欠落レンズを外して続行」と裁定したときに限り、欠落レンズ
ごとに --accept-missing <lens> --reason <裁定の内容> を付けて記録する。この引数を
自分の判断で使わない(裁定を得ていない欠落は必ずエスカレーションする)。
グラウンドトゥルースの突合: 集約エージェントの返却 5 項目目「GROUND_TRUTH の状態」が
事前準備 4 の確定内容と食い違う(未確定の候補が残っている・確定パスが判断基準に使われていない)
場合も、その周回は record に進まない。事前準備 4 に戻って確定し直し、同じ周回をやり直す
(確定を欠いたまま record すると、以降の周回で [PLAUSIBLE] が量産され振動判定を汚染する)。
規約の状態: 返却 6 項目目「規約の状態」に「prompt で受けた一覧に無い規約が CONVENTIONS に出た」と
あっても、周回は止めない(決定論探索が触ったファイルに応じて増えるのは想定どおり)。パスを記録するだけで
record に進む(グラウンドトゥルースの食い違いとは扱いが異なる)。
受領が揃っていることを確認したら、指摘の JSON 配列を record へ渡す。集約エージェント経由なら
返却された record-ready JSON をそのまま使う(kind / scope が下記の規則に沿っているかだけ点検する。
kind_reason が常時 improvement パターン名や spills-out なのに kind が fix の指摘は
improvement へ直す)。
直接起動時は統合報告から自分で構成する。
変更行数を record に渡す: git diff --shortstat <base-ref>...HEAD の挿入 + 削除の合計を
--changed-lines <N> で渡す(base-ref は事前準備で確定した対象範囲)。周回間の差分推移を
最終報告に出すための計測で、verdict には影響しない。取れないときは省略してよい
(省略時は推移を出さない)。
python3 <SKILL_DIR>/scripts/converge_state.py record \
--state <STATE> --head "$(git rev-parse HEAD)" \
--lenses <この周回で起動したレンズ。カンマ区切り> \
--received <報告を受領したレンズ。カンマ区切り> \
--changed-lines <git diff --shortstat の挿入 + 削除> \
--threshold <--until で指定された閾値。既定 want> --max-rounds 5 <<'JSON'
[
{"file": "src/a.py", "line": 42, "summary": "境界値が未処理", "severity": "must", "scope": "in", "kind": "fix", "kind_reason": "in-diff", "lens": "design"},
{"file": "src/a.py", "line": 30, "summary": "bool を enum に型化すべき", "severity": "want+", "scope": "in", "kind": "improvement", "kind_reason": "typing", "lens": "design"},
{"file": "other/x.py", "line": 7, "summary": "別タスクの問題", "severity": "want", "scope": "out", "kind": "fix", "kind_reason": "in-diff", "lens": "test"}
]
JSON
summary は指摘の要旨を短く。周回間の同一性はこれと file:line の正規化ハッシュで判定されるため、
同じ指摘は同じ趣旨の要旨で書く(言い回しの揺れ・句読点・空白は正規化で吸収される)
scope: diff-review が付けたスコープ分類をそのまま写す。「境界外」なら "out"、それ以外は "in"。
diff-review が分類を付けていない(タスク境界ファイルが無い)場合は全件 "in"
kind: 語彙と意味論(fix / improvement・「修正の実施が diff 外の行へ波及するか」の判定軸)は
severity と同様に diff-review 側の定義(diff-reviewer.md の kind 体系)が正。こちらで再定義しない。写し方:
- improvement モードの統合報告(全指摘に kind タグ付き)なら、タグをそのまま写す
- 既定モードのタグ無し報告は「全指摘 fix」の宣言なので、基本
"fix" と写す。ただし
常時 improvement のパターン(既存の型化・enum 化 / 既存関数からの関数抽出 /
既存テストハーネスの再設計 / 既存識別子の命名変更 / 対称性・一貫性を理由とする既存構造の変更)に
該当する指摘が漏れて混ざっていたら、record 時に "improvement" へ分類し直す。
「既存」は base 時点で存在するコードを指す。この PR が導入したハーネス・関数・抽象を
削る・縮める・インライン化する指摘はパターンに当たらず fix(yagni レンズの削れ指摘は
ここで improvement へ倒さない)。迷ったら improvement に倒す(修正の強制は安全側ではない)が、
「迷い」の根拠に PR 導入コードを「既存」と読み替えることを含めない
lens: 統合報告のレンズタグ([design] 等)をそのまま写す。複数レンズが 1 件に統合されていたら
最も重い severity を出したレンズを 1 つ選ぶ。タグが無ければ省略してよい(その場合はレンズ絞り込みが働かず、
次周回は全レンズでの起動になる)
[PLAUSIBLE](反証も確証もできなかった)/ [STRUCTURAL](構造追加を伴う)付きの指摘は、summary の
先頭にマークを残して写す(両方なら [PLAUSIBLE][STRUCTURAL] の順)。マークを剥がすと手順 3 の
機械修正の例外が働かない。周回間の同一性判定は summary を含むため、毎周回同じ付け方で写すこと
- 指摘ゼロの周回は
[] を渡す
3. verdict に従う
record の出力 JSON の verdict で分岐する。自分で判断を上書きしない。
| verdict | 対応 |
|---|
continue | remaining の指摘を修正し、次の周回へ戻る(手順 1 へ) |
converged | ループ終了。最終報告へ進む |
limit-reached | 周回上限に到達。remaining を修正しない。ユーザーへエスカレーションして停止する |
oscillation | 振動を検出。remaining を修正しない。ユーザーへエスカレーションして停止する |
diverging | 自己増殖(修正が新指摘を再生産)を検出。remaining を修正しない。ユーザーへエスカレーションして停止する |
停止系 verdict(limit-reached / oscillation / diverging)では、残指摘が「小さい」「本物」に
見えても修正せずに手順 4 へ進む。修正はユーザー(または親)の裁定後に、裁定された範囲だけ行う。
上限到達後に残指摘を全量修正してから報告した実例があり、上限が修正バーストになった。
呼び出し側の規約(ワーカー規約の反復境界など)に「実質的な指摘が出ている間は続ける」とあっても、
verdict の停止が優先する。
continue のときの修正対象は remaining(閾値以上・境界内・kind=fix)のみ。
deferred(境界外)と improvements(改善提案。周回横断で蓄積される)は修正しない
(どちらも最終報告の見送り一覧に載せる。情報は落とさない)。
保持(keep): remaining の指摘を修正しないと決めるときは、黙って残さず keep で記録する:
python3 <SKILL_DIR>/scripts/converge_state.py keep --state <STATE> \
--file <file> --line <line> --reason "<根拠>" [--user-confirmed]
- 保持してよいのは次の 2 つだけ。「同意しない」「小さい」は根拠にならない:
- 他レンズの指摘(前周回を含む)がその記述・コードを要求している(要求した指摘を名指しする)
- レビュアーの事実前提が誤りで、それを自分で検証した(何を確認したかを書く)
must は保持できない(スクリプトが拒否。手順 4 のエスカレーションで裁定する)。want+ は
AskUserQuestion で承認を取ってから --user-confirmed を付ける(質問の要点と選択肢は本文にも書く)。
want / nit は本体の判断でよい
keep は判定を再計算して出力する。保持した箇所は以降の全周回で remaining・振動・発散の
判定から外れ、suppress(次周回の再指摘禁止リスト)と最終報告の「保持した指摘」に載る。
突合は同じファイル内で line または要旨(正規化)のどちらかが一致すれば保持済みと見なす
(次周回の修正で行がずれても同じ要旨なら外れる。行も要旨も変わった指摘は新規として扱う)
- 保持は「修正の代わり」であって「見送り」ではない。境界外・改善提案の見送りとは別に扱う
- 停止系 verdict 中は keep も修正と同じく裁定前に行わない。
remaining を keep で消して収束扱いに
する迂回を防ぐため、スクリプトは直近 verdict が停止系のとき --user-confirmed 無しの keep を拒否する。
手順 4 でユーザーが「保持する」と裁定した指摘だけ、承認付きで記録する
修正の順序は yagni レンズ由来の指摘(過剰実装の削除・簡素化)を先に実施する。
集約エージェントの yagni 重点分析が「削除で消える」と名指しした他の指摘は、削除後に
解消を確認してから残りを修正する(削られるコードの上に修正を積む手戻りを避ける)。
機械修正の例外: [PLAUSIBLE] 付きの削除・縮小指摘(仕様根拠を確認できないまま出された
提案)は、修正前に自分で根拠(仕様・計画・参照実態)を検証する。整合を確認できたものだけ
修正し、確認できなければ修正せずユーザーへ採否を確認する。レビュアーが人の判断へ回す
ために付けたマークを、収束ループが強制修正へ昇格させてはいけない(仕様解釈の変更が
機械ゲートで通過して人間レビューに覆された実事故への対策)。
[STRUCTURAL] 付きの指摘(新規ファイル・型・層・単一使用の一般化など構造追加を伴う修正方針。
規約を根拠にするものを含む)も同様に自動修正せず、AskUserQuestion で採否を確認してから
修正する(質問の要点と選択肢は本文にも書く)。規約に書いてあることを理由に構造を足す指摘を
機械的に全量実装すると、PR が計画外に膨張する。採否待ちの間は keep せず remaining に残す
(裁定後に修正するか、裁定に基づいて --user-confirmed 付きで keep する)。
修正の順序は yagni 先(上記)で、規約由来の指摘は yagni 指摘の解消後に再評価してから修正する。
次周回のレンズは同じ出力の next_lenses に従う(手順 1 のレンズ段階戦略)。初回のみ全レンズ、
2 周目以降は前周回で指摘を出したレンズだけを回す判定をスクリプトが行うので(最終周回も
全レンズへ戻さない。上限周回でレンズを広げると新規指摘が上限到達と同時に出て修正バーストになる)、
周回ごとのレンズ数を自分で決めない。
4. エスカレーション(limit-reached / oscillation / diverging)
自動で回し続けない。次を提示してユーザーの判断を仰ぐ:
oscillation: oscillating 配列の各件について、どの指摘が何周目と何周目で問題になったか
(kind が stuck なら 2 周連続で未解消、reappeared なら消えた後に再出現)を示し、
打ち消し合いの構図(前周回の修正を次の指摘が戻させている等)を 1〜2 文で説明する
diverging: diverging.windows(周回ごとの新規/解消数)と diverging.new_findings
(直近周回の新規指摘)を示し、再生産の構図(前周回の修正が導入したコードへ新指摘が
付き続けている等)を 1〜2 文で説明する。新規指摘の kind 分類が適切だったか
(実は improvement を fix に分類していないか)も点検して報告する
limit-reached: 残っている指摘一覧と、収束しない理由の見立てを示す
- 選択肢: 閾値を緩めて再開 / 特定の指摘を見送りに回す / 手で方針を決める / 打ち切って現状で PR に進む
親配下(AskUserQuestion が使えない文脈)で回すときの規則
このループを親エージェント配下のワーカーとして回し、AskUserQuestion が使えない場合:
- 事前準備 4 の Explore 候補は採用せず、最終報告に「未確定の候補」として列挙する(決定論分の規約だけで回す)
[STRUCTURAL] 付きの指摘は修正せず、親へ報告して裁定を待つ([PLAUSIBLE] の採否確認・want+ の
keep 承認も同様に親へ回す)。裁定が来るまで remaining に残し、勝手に keep しない
最終報告
収束・上限・振動・発散のいずれで止まっても、必ず次を報告する:
- 結果: verdict・周回数・適用閾値
- 残指摘(収束以外のとき):
remaining を severity 順で
- 差分の推移:
changed_lines の系列(1 周目 → 最終周回)と changed_lines_delta。増分が正なら
「レビュー中に差分が N 行増えた」と明記する(修正が新規コードを積み増しているシグナル。
良否の判定はしない)。--changed-lines を渡していない周回しか無ければこの節を「計測なし」とする
- 保持した指摘:
kept を「ファイル:行 / 要旨 / severity / 保持理由 / 何周目」の形で列挙する。
1 件も落とさない(PR レビュアーが判断を追えるようにする)。ゼロ件ならこの節を「なし」とする
- 見送り improvement:
improvements(改善提案。周回横断で蓄積済み)を「ファイル:行 / 要旨 /
見送り理由(改善提案のため収束ループでは修正しない)」の形で列挙する。1 件も落とさない。
ゼロ件ならこの節を「なし」とする
- 見送り一覧:
deferred(境界外指摘)を「ファイル:行 / 要旨 / 見送り理由(タスク境界外のため
別タスク・別 PR で対応)」の形で列挙する。1 件も落とさない。境界ファイルが無かった場合は
この節を「なし」とする
- 完成の定義の残項目:
docs/dev/definition-of-done.md があれば Read し、人判定節の
チェックリストを未チェックのまま転記する(機械判定節は転記しない)。ファイルが無ければ節ごと省略する
見送り(improvements + deferred)または保持(kept)が 1 件でもあれば、報告と同じ内容を
見送りファイルとして書き出す:
- 出力先は
<STATE> と同じディレクトリ
($(git rev-parse --show-toplevel)/tmp-agents/review-converge/<ブランチ名の / を - に置換>/)。
ファイル名は YYYYMMDD_deferred.md(同名があれば _2 等の連番を付ける)。セッションの scratchpad は使わない
(セッション終了で消え、後続の転記素材にならない)
- ファイル冒頭に「PR 本文の見送り節、または別 issue へ転記して出口を作ること」を明記する
(PR 本文への反映自体は PR 作成時の作業で、このスキルの範囲外)
状態ファイルの永続化: 見送りの有無に関わらず、ループが止まったら <STATE> を見送りファイルと
同じディレクトリ(<STATE> 自身のディレクトリ)へ YYYYMMDD_state.json として複写する(cp -n <STATE> <ディレクトリ>/YYYYMMDD_state.json。
複写先はファイル名まで指定する。同名があれば _2 等の連番を付けた名前を指定する)。<STATE> は次に新規で回したときの reset(事前準備 3)で
消えるため、複写しないと周回ごとの
指摘(lens / kind / severity / scope)・保持・差分推移が後から追えなくなる。スキルの改善効果を
測る唯一の一次資料であり、複写しないと次の分析ができない(state が偶然残っていたから
分析できた実例)。
見送りファイル・状態ファイルの複写は最終的な名前へ 1 回で書く。ブランチ別のディレクトリへ
置くのは、tmp-agents/ が worktree 間で symlink 共有されうるため(並列レーンで同じ日に回すと
共有ディレクトリ直下の固定名では衝突する)。ブランチでディレクトリを分ければファイル名に
ブランチを含めずに済み、<STATE>・統合報告と同じ場所に 1 ブランチ分の記録がまとまる。連番などで
名前を変えるときも、その名前を先に決めてから直接書く。固定名で書いてから改名・rm で片付ける手順は取らない(rm は確認ダイアログになり、
並列レーンではそこで止まる)。
制約
- diff-review の設計・出力形式を変更しない(呼ぶだけ)。レンズ段階戦略も
diff-review の read-only 単発設計には触れず、こちらの呼び出し方だけで実現する
- コミット・push はこのスキルの範囲外。修正のコミット粒度は commit-flow に従う
- このループが検出するのは diff が導入した問題に限る。タスク指示・計画自体に含まれる過剰な実装
(依頼の目的に不要なリファクタ・一般化)は diff レビューでは検出できないので、計画レビューの
段階で除く。ループが収束したことを「計画が適切だった」根拠にしない
- 状態ファイル以外への書き込みは、指摘に対するコードの修正・最終報告時の見送りファイルと
状態ファイルの複写・集約エージェントが書く周回統合報告ファイルのみ