fallow-review について
fallow-reviewは、変更セットを依存グラフに基づくレビュー概要に変換するスキルです。重要な構造上の判断にレビューを集中させ、エージェントの判断をグラフのシグナルとスナップショットで検証します。CIゲートを担うauditとは役割が異なります。
主な機能
- 01注意度スコアで変更箇所を順位付け
- 02決定的な検出結果を判断対象から除外
- 03構造上の決定を質問として提示
- 04グラフスナップショット付きのエージェントガイドを生成
- 05判断シグナルとスナップショットの鮮度を検証
活用シーン
- 01マージ前のブランチや差分のレビュー
- 02自動コーディング後に残る判断事項の抽出
- 03コード作成者に返すレビューコメントの作成
MCP 対応
READMEでは、CLIと同じ依存関係の判断事項を提示するMCPツールdecision_surfaceに言及しています。その他のMCP連携の詳細は抜粋に記載されていません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fallow-rs/ fallow-skills --skill fallow-reviewインストール後、Claude Code で/fallow-reviewを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/production-runtime-data.mdtradeoff-elicitation.md詳細
Fallow Review:グラフに基づくコードレビュー
fallow review は変更セットを、決定的なグラフ由来のレビュー概要とエージェント契約のループに変換します。「CI でブロックされるか?」(これはゲートとして機能する fallow audit が判定します)ではなく、「どこを見ればよいか、実際にどの呼び出しに人の判断が必要か?」に答えます。review は常に終了コード 0 を返すため、判定結果にかかわらず安全に実行できます。
次の 4 つの処理を、この順番で行います。
- subtract:変更されたファイルのデッドコード、複雑さ、重複、スタイルを報告し、判断ループから除外します。これにより、決定的なチェックですでに確認できる内容に注意を費やさずに済みます。
- focus:変更されたファイルのユニットを、複合的な注目度スコア(ファンイン/ファンアウト、リスクゾーン、変更の形状)でランク付けし、
review-here/not-prioritizedのラベルと、完全なdeprioritizedの例外リストを付けます。これにより、何も隠されません。 - structure:判断サーフェスでは、重要な STRUCTURAL 判断を少数だけ diff から取り出し、それぞれを判断を促す質問として提示します。作業記憶に収まる数に制限し、各項目を fallow が出力した
signal_idに結び付けます。 - direct:ウォークスルーガイドでは、グラフ由来のダイジェスト、レビューの方向性、グラフスナップショットのピン、および返すべき判断スキーマをエージェントに提示します。
使用する場面
- マージ前に、PR、ブランチ、または diff(AI 生成でも人間が作成したものでも)をレビューする場合。
- エージェントが作業を終え、可能な fallow の指摘を取り除いた後に、残った人間/エージェントの判断が必要な箇所を明らかにする場合。
- コードを書いたエージェントに戻せる、インラインレビュー可能な判断を作成する場合。
使用しない場面
- CI を合否判定でゲートする場合:
fallow auditを使用してください(失敗判定では 0 以外の終了コードを返します)。 - プロジェクト全体の健全性、クリーンアップ、またはデッドコードのレポートを作成する場合:
fallowスキルを使用してください。
人間向けの概要をすばやく確認
# Auto-detect the base (merge-base against the upstream / remote default):
fallow review
# Pin the base, or scope to a precise diff:
fallow review --base origin/main
git diff --find-renames origin/main...HEAD | fallow review --base origin/main --diff-stdin
人間向けの概要には、状況を把握するための事実、注目箇所マップ、判断サーフェス(「決定事項」)が出力されます。--format json を指定すると、構造化された全データ(decisions、focus、deltas、impact_closure、partition、graph_facts)が出力されます。--max-decisions N で上限を調整できます(小さな範囲内に制限されます)。--show-deprioritized を指定すると、注目箇所マップで折りたたまれた内容が展開されます。
判断サーフェス
各判断は、グラフから fallow が決定的に導出した signal_id(差分キーまたは調整ギャップキー)に結び付いた、判断を促す質問として提示されます。出荷可能なカテゴリは、次の 3 つだけです。
- coupling-boundary:新しいゾーン間の依存エッジ。
- public-api-contract:新しいエクスポート済みパブリック API サーフェス、またはこの diff の外部にあるモジュールが使用する契約の変更(確認または判断を促すシグナル)。
- dependency:サードパーティのエントリーを追加する、または宣言済みエントリーのメジャーバージョン(あるいは
0.xのマイナーバージョン)を上げるpackage.jsonの変更。マニフェストと種類ごとに判断を 1 つにまとめ、影響を受けるパッケージをリポジトリ内でインポートしている数に応じて重み付けします。blastはインポーター数、internal_consumer_countは diff の外部にあるインポーター数です。どちらの数も、まとめられたパッケージ全体の和集合です。dependencies以外のエントリーには、質問に(dev)、(optional)、または(peer)のタグが表示されます。digest.deltasには、キーがdependency_added(<manifest>::<name>)およびdependency_major_bumped(<manifest>::<name>@<from>-><to>)として格納されます。どちらのリストも常に存在し、空の場合もあります。マイナーおよびパッチバージョンの更新、ならびに数値以外の範囲(workspace、file、git、タグ)は候補になりません。dependency判断にはsuppressアクションがありません。判断の基点はコメントを記述できないpackage.jsonであるため、マニフェストに// fallow-ignoreの行を貼り付けないでください。decision_surfaceMCP ツールは、CLI と同じ依存関係の判断を提示します。質問の形式ルール:変更履歴に関する質問(「<from>から<to>へのどの変更が、この N 個のインポーターに影響しますか?」)を提示してください。動作の変更を推測しないでください。
判断の基点となるファイルが変更時に名前変更されている場合、判断には previous_signal_id が含まれることがあります。これは、旧パスで同じ判断に付与されていたはずの signal_id です。これにより、レビュービューで git mv をまたいで以前のレビュアーコメントを再添付できます。
より広範なトレードオフの引き出し(テイストの決定権)
上記の決定対象は、DETERMINISTIC な範囲、つまり fallow がグラフから証明できるトレードオフ(3つのカテゴリ)のみです。実際のアーキテクチャ上のトレードオフはさらに広範です(抽象化のレベル、エラー処理の方針、データモデルの形、先行評価と遅延評価、状態の所有権、拡張性とYAGNIのバランス、テスト容易性、信頼境界など)。これらはいずれもグラフから検出できません。これらを明らかにするには、静的な解析ではなく、差分を読み取るモデルが必要です。
references/tradeoff-elicitation.md のトレードオフ引き出しプロンプトを、差分とガイドに対して実行します。このプロンプトはテイストの決定権を適用します。モデルはそれぞれの選択を明確にし、真に未決の質問として提示し、人間が判断します。このプロンプトには、誠実性に関する契約(差分への根拠付け、observed/tradeoff/question の分離、deterministic: false による明確な区分、出典情報、誠実に回答を控えることを認めた上での最大5件の制限、決定論的な対象との重複禁止、選択を決して決めない options)が含まれます。fallow は証明できる内容を担当し、プロンプトが残りを扱い、明確な区分によって両者が混同されないようにします。
レビュー手順としての実行
決定論的な判断に加えて、トレードオフも確認する場合:
- ガイドを取得し、差分を読み取ります:
fallow review --base <ref> --walkthrough-guide --format json > guide.json git diff <ref>...HEAD # or: git diff --cached for staged work - 差分と
guide.jsonに対してreferences/tradeoff-elicitation.mdのプロンプトを実行します。 - エンベロープ(
{ graph_snapshot_hash, abstained, tradeoffs[] }の形式)を保持します。以下の統合レビューで使用します。
この手順は、以下の post-validate エージェント契約ループには意図的に含まれていません。トレードオフのエンベロープが fallow review --walkthrough-file を介して往復することはありません(このコマンドは出力された signal_id のみを検証します)。そのため、これは fallow グレードの保証を持ちません。すべての項目は deterministic: false のままで、グラフによる検証ではなく、エージェントが差分と照合して自己チェックします。fallow による検証済みとして提示しないでください。
エージェント契約ループ
このループでは、エージェントが判定を行い、fallowが稼働中のグラフに対して事後検証します。検証を行うのはグラフであり、2つ目のモデルではありません。
-
ガイドを取得します:
fallow review --base origin/main --walkthrough-guide --format json > guide.jsonガイドには、
digest(概要と判断対象)、direction(確認する場所)、graph_snapshot_hash(古さを判定するための固定値)、agent_schema(返す値の厳密な形式)、injection_noteが含まれます。digestはグラフのみから作られ、PRの説明文は一切取り込まれません。そのため、設計上、ガイドはインジェクションへの耐性があります。 -
digestの判断対象を読みます。それぞれにsignal_id、category、整理されたquestion、anchor_file/anchor_lineが含まれます。 -
agent_schemaに一致する判定を返します:{ "graph_snapshot_hash": "<echo the value from the guide>", "judgments": [ { "signal_id": "<one signal_id fallow emitted>", "framing": "<your reasoning for the human reviewer>", "action": "<block | address | consider | fyi>", "concern": "<optional: one lens from agent_schema.concern_vocabulary>" } ] }すべての
signal_idは、ガイドで出力されたもの(emitted_signal_ids)でなければなりません。アンカーのないIDは拒否されます。graph_snapshot_hashはそのまま返してください。検出事項のない変更領域については、
signal_idの代わりに、出力済みのchange_anchor(ガイドのchange_anchorsにあるchg:ID)を判定に記載できます。各アンカーにはfile、start_line、line_countが含まれます。不明なIDはunknown-change-anchorとして拒否されます。actionは、その判定が作成者に求める内容を示します。blockとaddressは必須のアクション、considerは任意、fyiは対応不要です。concernは観点を示します。ガイドのagent_schema.concern_vocabularyにある13種類のケバブケース形式の観点を使うことを推奨します:abstraction、coupling、data-model、error-handling、control-flow、performance、dependencies、api-ergonomics、compatibility、state-ownership、extensibility、testability、trust-boundary。ガイドにはagent_schema.action_vocabularyとagent_schema.concern_vocabularyの両方が記載されています。このファイルではなく、ガイドから読み取ってください。action_vocabularyは適用必須ですが、concern_vocabularyは参考情報であり、任意の文字列を受け付けます。 -
事後検証します:
fallow review --base origin/main --walkthrough-file judgment.json --format json応答では、各判定が次のように分類されます:
accepted:signal_idが出力済みで、スナップショットが一致しています。エージェントのframingは非決定的なもの(deterministic: false)として区別され、ゲートとして使われることはありません。actionもagent_framingの隣に同じように区別して記載されます。これは作成者への指示であり、fallowの事実ではありません。reason: "unanchored-signal-id"を伴うrejected:signal_idが一度も出力されていません(幻覚です)。削除するか、修正してください。reason: "invalid-action"とinvalid_value(fallowが拒否したラベル)を伴うrejected:actionが語彙の範囲外です。このエラーが報告されるのはアンカーの解決後のみです。幻覚のアンカーと不正なラベルが組み合わさっている場合は、代わりにunanchored-signal-id/unknown-change-anchorとして拒否されます。まずアンカーを修正し、その後ラベルを修正してください。reason: "stale-snapshot"とstale: trueを伴うrejected:ガイドの取得後にツリーが変更されています。ガイドを再取得し、判定をやり直してください。
本番ランタイムデータ(Fallow Cloud)
プロジェクトから本番カバレッジをFallow Cloudに送信している場合は、変更する関数をそのデータと照合してください。ランタイムコンテキストをすべて取得するのではなく、対象を絞った読み取りを使います:
- 編集前:
fallow coverage review-packet --repo <owner/repo> --base <ref>(MCP:get_cloud_review_packet)。hit_count、covered_by_test、および存在する場合は呼び出し元を確認します。covered_by_test: nullのホットな関数を編集する場合は、リスクが高くなります。 - 削除前:
tracking_stateだけでなく、対象期間のperiod_tracking_state: "never_called"を必須とし、evidence_window.observed_hoursを確認します。観測時間が少ない場合やトラフィックの少ない領域は、「訪問されていない」ことを意味し、「使われていない」ことを意味するわけではありません。 - デプロイ後:
fallow coverage deployment-changes --repo <owner/repo>(MCP:get_cloud_deployment_changes)。comparableがfalseの場合は、reasonを報告し、変更があったとは主張しないでください。 file_pathではなく、repo_pathでファイルを開きます。
このデータはコンテキストとして使います。ゲートとしてではなく、framing に記載してください。各フィールドの意味と手順の全容については、references/production-runtime-data.md を参照してください。
レビューをまとめる
検証とレビューは別物です。判断が承認されたら、読者がまず結論を左右する内容を把握し、その後で決定論的な残りを確認できるよう、以下の固定順で人間向けに表示してください。
- 承認された判断を
direction.orderの順に表示します。各判断には、ダイジェストのquestionとtradeoffをそのまま含め、続けてframing、さらに重要度を示す数値(internal_consumer_count、out_of_diffのパス、またはユニットのscoring_budget)を記載します。 - 聞き取りステップで得たトレードオフを
consequence順に、最大5件表示します。エンベロープがabstained: trueの場合は、その旨を1行で表示し、この欄には項目を追加しないでください。 - 差し引きは、ブリーフに記載された件数を使って次のように1行で表示します。「決定論的に処理済み:デッドコードN件、重複N件、複雑性N件、スタイルN件。議論の対象外」。これらの値をdiffから再計算しないでください。すでにブリーフで管理されています。
- 優先度を下げた項目は、件数と、表示するための指定方法
--show-deprioritizedを含めて1行で表示します。項目を隠さず、数を水増ししないでください。 - 判断が0件で、トレードオフのエンベロープが棄権の場合、レビューは完了です。「重大な影響なし。決定論的な指摘:N件」。失敗ではなく、項目を捏造する理由にもなりません。
3つのグラフ情報が構成に反映されます。項目を追加できるのはtest_reachの注記だけで、その基点はchange_anchorです。
- 各direction unitには
test_adjacencyが含まれます。値は、none(このユニットをインポートするテストファイルがない)、untouched(テストからインポートされているが、そのテストはdiffに含まれない)、changed(テストからインポートされており、そのテストもdiffに含まれる)のいずれかです。テストファイルの場合、およびグラフが保持されていない場合は、この値はありません。review-hereユニットの値がnoneの場合は、framingで作成者に検証方法を尋ねてください。カバレッジがあると断言してはいけません。この値が示すのは、テストがそのユニットをインポートしているかどうかであり、変更をテストしているかどうかではありません。 digest.test_reachは、変更された各値エクスポートの到達状況を示します。statusはmeasuredまたはno-testsです。countsにはすべてのクラスの件数が含まれます。exportsには、directまたはframework以外のクラスのみ、file、export_name、line、reachを含む行が記載されます。transitive:テストからエクスポートに到達しますが、エクスポートを直接指定するテストはありません。mocked-only:テストではファイルがモック(mocked_targets)に置き換えられるため、実際のコードは実行されません。none:テストからファイルには到達しますが、エクスポートに到達するテストはありません。none-file:ファイルに到達するテストはありません。test_reachには次のルールを適用します。- 存在しない場合は、事実がないことを意味します。古いバージョンの Fallow ではこのフィールドが出力されず、値のエクスポートに変更がない場合も存在しません。その場合は
test_adjacencyを使います。 review-hereユニットのファイルにmocked-only、none、またはnone-fileの行がある場合は、その行(ファイル、エクスポート、クラス)を示します。検証の経緯を作成者に尋ねます。- 行には
signal_idがありません。エクスポート宣言と範囲が重なる、同じfile内のchange_anchorに注記を紐付けます。重なるアンカーがない場合は、そのファイル内で最初のアンカーを使います。そのファイルに判定がある場合は、その枠組みの中に注記を記載します。 test_reachとtest_adjacencyが食い違う場合は、エクスポートごとに判定され、モックも検出できるtest_reachを使います。- これらの事実から「テスト済み」や「カバー済み」と記述してはいけません。
directは、テストでそのエクスポートが指定されていることを意味し、変更された行をテストが実行することを意味するものではありません。 reachセットに含まれる値は固定されていません。不明な値には注意が必要です。exports_omittedが 0 より大きい場合、一覧は不完全です。行がないファイルは、directに到達している証拠にはなりません。countsを使います。status: "no-tests"の場合は、エクスポートごとではなく、全体の概要を示す行を 1 行記述します。masking: "capped"の場合、グラフはモックを検出できません。mocked-onlyの行がないことは、何の証明にもなりません。- エンドツーエンドテストはファイルをインポートしません。エンドツーエンドランナーがあるプロジェクトでは、
none-fileの行があってもエンドツーエンドテストが存在する場合があります。決めつけず、尋ねてください。
digest.partition.independent_slicesは、ユニット間依存関係グラフの連結成分を示します。各成分はモジュールディレクトリのソート済みリストです。スライスが 2 つ以上ある場合にのみ存在し、存在しない場合は変更箇所が 1 つの連結したまとまりであることを意味します。digest.triage.risk_classがhighで、このフィールドが存在する場合は、概要を示す事実として「この変更は、グラフで確認された境界に沿って K 個の独立したスライスに分かれています」と明記します。分割を求めるものではありません。判断は作成者に委ねられます。
文章作成では、次の 2 つのルールに従います。まず、活用を重視します。構造に関する判断 1 件と小さな注記 10 件がある場合、レビューの中心となるのはその判断です。注記はその下に添えるか、省略します。形容詞ではなく、数値を示します。すべての framing には、ガイドにある数値またはパスを少なくとも 1 つ含めます(利用側の数、差分外のパス、scoring_budget など)。「遅くなる可能性があります」では根拠になりません。「14 個のモジュールからインポートされ、そのうち 9 個はこの差分の外です」と記述します。
人間が介在するウォークスルー(ターミナル)
上記のエージェント契約ループでは、エージェントが枠組みを設定します。同じループを使えば、人間の評価も同じグラフ検証済みのハルシネーション防止保証付きで伝達できるため、ターミナルでレビューする人は、fallow が検証して往復処理するアンカーにメモを残せます。契約は既存の --walkthrough-guide / --walkthrough-file による往復処理であり、新たなインターフェースではありません。
判断基準は人間が決め、あなたはメモを伝えるだけです。fallow が検証するのはアンカー(シグナルまたは変更箇所が存在すること)であり、メモの正しさではありません。伝達されるメモはすべて deterministic: false のままで、ゲートとして機能することはありません。
-
ツアーを表示し、アンカーを確認します:
fallow review --base origin/main --walkthrough # the staged human tour fallow review --base origin/main --walkthrough-guide --format json > guide.jsonguide.jsonには、判断に関するsignal_id(枠組みが示された構造的な問い)、変更箇所ごとのchange_anchorsセット(各要素は{ "change_anchor": "chg:<hex>", "file", "start_line", "line_count" })、および古さを判定するピンであるgraph_snapshot_hashが含まれます。人間にツアーを提示し、フラグを付ける項目ごとに、短い評価またはメモと、作成者に求める対応を集めます。選択肢として提示するラベルはblock、address、consider、fyiの4つのみです。不明なラベルはinvalid-actionとして拒否されます。 -
各人間のメモを判断として伝達します(ハッシュをそのまま含め、フラグを付けた判断について fallow が出力した
signal_id、または人間がメモを残すその他の変更箇所についてchange_anchorを指定し、人間の対応内容をactionとして伝えます):{ "graph_snapshot_hash": "<echo from guide.json>", "judgments": [ { "signal_id": "<an emitted decision signal>", "framing": "<the human's verdict/note>", "action": "address", "concern": "<optional>" }, { "change_anchor": "<an emitted chg: id>", "framing": "<the human's note on this region>", "action": "consider", "concern": "<optional>" } ] } -
記録を検証します:
fallow review --base origin/main --walkthrough-file judgment.json --format json応答はエージェント契約ループと同じ形式で並べ替えられますが、2つの項目が追加されます。
acceptedにはanchor_kind("signal"または"change")が含まれ、fallow が出力したことのないchange_anchorはunknown-change-anchorとして拒否されます。実在するシグナルまたは変更箇所を再度アンカーとして指定してください。アンカーを捏造してはいけません。 -
対応します: 受理された人間の評価をコーディングセッションに伝えます。受け取るエージェントが優先順位を判断できるよう、各メモの
actionも伝えてください。blockとaddressは必須の対応、considerは任意の対応、fyiは変更不要です。メモはアンカー付きで明確に区分されて届き、fallow が認定した事実として扱われることはありません。
保証:人間は、fallow が出力していないシグナルや変更箇所にメモをアンカーできません。また、変更されたツリーに対するメモは、誤った箇所に暗黙的に紐付けられるのではなく拒否されます。
このループが退ける誤った理由付け
| 誤った理由付け | 実際のところ |
|---|---|
| 「差分にデッドコードが見えるので、すぐにフラグを付けよう」 | 差し引きはすでに Subtract が担当しているため、二度目の導出はノイズになり、誤る可能性もあります。ブリーフの件数を伝えてください。 |
「この signal_id は正しそうだ」 | 存在するのは emitted_signal_ids だけです。それ以外はハルシネーションであり、fallow に unanchored-signal-id として拒否されます。 |
| 「トレードオフは5つが目標だ」 | 5つは上限です。空のリストを伴う abstained: true も、妥当で完全な回答です。 |
| 「問いは未解決だから、修正方法だけ伝えよう」 | 修正方法を名指しするのは処方です。未解決の判断として表現し直すか、実際のコストを伴う選択肢を2つ以上挙げてください。 |
| 「ツリーは少ししか変わっていないので、ガイドはまだ使えるだろう」 | これは stale-snapshot です。ガイドを再取得し、判断をやり直してください。 |
| 「テストが成功しているので、変更は良いものだ」 | 成功は検証上の事実であり、判断対象についての評価ではありません。判断には引き続き人間の決定が必要です。 |
| 「テストがこのファイルをインポートしているので、テスト済みだ」 | test_adjacency が確認するのはインポートだけです。mocked-only、none、none-file の行は、インポート経由では実際のエクスポートに到達するテストがないことを示します。検証方法について確認してください。 |
| 「本番環境で一度も呼び出されていないので、削除しよう」 | period_tracking_state と evidence_window.observed_hours を確認してください。計測期間が短い、またはまれにしか通らない経路であれば、「未訪問」であって「デッド」ではありません。 |
注記
reviewはaudit --briefのエイリアスです。--formatはブリーフとは独立しています。- プロジェクト全体の分析については
fallowスキルを、フラグの一覧についてはそのreferences/cli-reference.mdを参照してください。