mcpField
P
pre-merge

pre-merge

github.com/chrislacey89テスト・品質472 回インストール今日更新
リポジトリ

pre-merge について

マージ前に GitHub PR を作成し、プロジェクトのアーキテクチャ原則に照らして差分をレビューするパイプライン用スキルです。作成者、レビュアー、ループの各モードに対応し、指摘は助言として提示します。コード修正やマージ阻止は行いません。

主な機能

  1. 01PRD とスライス課題に紐づく PR 作成
  2. 02アーキテクチャ原則に沿った差分レビュー
  3. 03作成者・レビュアー・ループモード
  4. 04ループモードで根拠付きの指摘を記録
  5. 05助言のみでコード修正は行わない

活用シーン

  1. 01検証済みブランチのプルリクエスト準備
  2. 02他のコントリビューターのプルリクエスト確認
  3. 03複数セッションにわたる指摘の追跡

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/chrislacey89/skills --skill pre-merge

インストール後、Claude Code で/pre-mergeを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

review-checklist.md
references/
comment-craft.md
next-step-menu.md
restated-claims.md
sidecar.sh
state-backend.md
SYSTEM-OVERVIEW.md
writing-for-humans.md

詳細

翻訳後に原文が更新されています。最新の内容は原文をご確認ください。

マージ前

PRD とスライス課題へのリンクを含む GitHub PR を作成し、プロジェクトのアーキテクチャ原則に照らして差分全体をレビューします。助言として指摘事項を提示します。マージをブロックしたり、コードを自動修正したり、課題を登録したりすることはありません。

呼び出すタイミング

実装の検証が完了し、main へのマージ前に使用する主要なパイプラインスキルです。または、他の人の PR をレビューする際にも使用します。

ブランチで PR 作成、アーキテクチャレビュー、計画とコードの最終的な照合を行う準備ができたら、/pre-merge を使用してください。自分が作成していない PR をレビューする場合は、/pre-merge --pr <number> を使用してください。

実装検証、QA の受付、リファクタリング計画の代わりとして使用しないでください。作業がすでに完了し、レビューの準備ができていることを前提としています。

モード

/pre-merge は 3 つのモードのいずれかで実行されます。3 つのモードすべてで review-checklist.md に定義されたアーキテクチャレビューの観点を再利用しますが、読み取る内容と生成する内容が異なります。

  • 作成者モード(デフォルト) — 自分のブランチで --pr 引数なしに呼び出します。このスキルは PR を作成し(Phase 2)、指摘事項を助言としてターミナルに出力します(Phase 4)。その後、処理を引き渡します。修正コミットは作成せず、2 回目のパスも開始しません。 これは、HITL パスで /execute の Step 6 から自動的に呼び出されるモードです。読み取る内容はフラグではなくブランチの状態によって決まります。 初回のレビューではブランチ全体を読み取ります。すでにレビュー通貨スタンプが付与された PR に対して再実行し、その後に head が更新されている場合は、スタンプ付き SHA 以降のコミット、つまりポストスタンプ差分をレビューの対象とし、以前のレビューでカバーされた内容は再度読み取りません。Phase 1 のステップ 4 でこの判断を行い、その内容を出力します。差分は対象であって、レビュー担当者が読み取れる範囲を制限するものではありません。レビュー担当者が読み取る内容は review-checklist.md に従い、差分の周辺ツリーも含まれます。
  • レビュアーモード — 自分が作成していない PR に対して、/pre-merge --pr <number> として呼び出します。PR はすでに存在するため、PR の作成をスキップし、確認して投稿するためのコメント文のドラフトを生成します(Phase 4)。構成は references/comment-craft.md(5P ゲート、Triple-R、Comment Signals、MMG Exchange)に従います。
  • ループモード — /pre-merge --loop として呼び出すか、AFK 実行で /execute から引き渡された際に自動的に移行します。Phase 1 のステップ 4 における対象範囲の判断を除き、作成者モードと同様に Phase 1〜4 を実行します。ループモードではブランチ全体を読み取り、ポストスタンプ差分は対象にしません。その後、Phase 5 に進みます。PR 上の永続的な台帳にすべての指摘事項を記録し、それぞれを裏付ける、または反証する証拠を添付して、オペレーターに引き渡します。このモードでは、指摘事項はターミナル出力ではなく、担当者が割り当てられた永続的な行になります。ループモードは何も修正せず、コミットも作成しません。各指摘事項をどう扱うかはオペレーターが判断します(Phase 5 § ループが修正を行わない理由を参照)。

ループモードの終了条件は、レビューがクリーンであることではなく、すべての指摘事項に担当者がいることです。 「指摘事項ゼロ」は終了シグナルとして禁止されています。これは、実質的な差分に対する指摘事項がほとんどないレビューは、コードに欠陥がないことを意味するのではなく、レビューが途中で終わったことを意味するために設けられた、Phase 4 の既存の最小指摘件数ガードと整合しています。クリーンなレビューを終了条件とするループは、安定してクリーンなレビューだけを生み出し、それ以外は何も生み出さなくなります(Meadows、『Seeking the Wrong Goal』、Leveson:インシデント件数の少なさではなく、報告そのものを評価する)。

ユーザーの作業ブランチとは異なるブランチで実行していて、--pr が指定されていない場合は、推測せずに、特定の PR 番号に対するレビュアーモードを意図しているかどうかを一度だけユーザーに尋ねてください。自動検出でキー入力を 1 回省けても、モードを誤判定すると、本来はローカルへの助言となる内容がコメントのドラフトになったり、その逆になったりします。

使用するタイミング

  • 作成者モード: QA に合格した後、機能ブランチを main にマージする前、Ralph が AFK 実行を終え、動作を検証した後、または完全なパイプラインを実行していなくても、マージ前にレビューしたいブランチがある場合に使用します。
  • レビュアーモード: チームメイトまたは外部のコントリビューターが PR を作成し、その差分に review-checklist.md の完全なアーキテクチャレビューを適用して、建設的なコメント文を作成したい場合に使用します。
  • ループモード: 指摘事項を、それを生み出したセッションの後も引き継ぐ必要がある場合に使用します。たとえば、/execute からの AFK ハンドオフや、何度かに分けてレビューする予定で、その都度指摘事項を洗い出し直したくないブランチなどです。コストがかかっているのが 修正の実施 ではなく 指摘事項の把握を維持すること である場合に使用してください。

実行フロー

フェーズ 1:コンテキストを収集する

作成者モード:

  1. PRD の Issue 番号を尋ねます。 この変更が完全なパイプラインを通っていない場合は、「none」を受け付けます。AFK の /execute ハンドオフからループモードに入った場合は、尋ねないでください — ハンドオフから Issue 番号を取得し(/execute のステップ 6 で渡されます)、記載がなければ「none」として扱います。回答する人はいないため、ここで必ず質問すると、最初のステップで実行が停止してしまいます。

  2. PRD が指定された場合:

    gh issue view <number>
    gh issue list --search "in:body #<prd-number>" --state all --json number,title,state,body --limit 100
    

    各スライス Issue の本文から境界マップ(Produces/Consumes セクション)を解析します。

  3. ベースブランチを検出し、差分を評価します:

    BASE_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD --short 2>/dev/null | sed 's@^origin/@@')
    if [ -z "$BASE_BRANCH" ]; then
      for candidate in main master prod develop trunk; do
        if git rev-parse --verify "$candidate" >/dev/null 2>&1; then BASE_BRANCH=$candidate; break; fi
      done
    fi
    # A name is not a ref. $BASE_BRANCH names the branch (for `--base`, `git switch`);
    # $BASE_REF points at it, and is the only thing safe as a range endpoint.
    if git rev-parse --verify "origin/$BASE_BRANCH" >/dev/null 2>&1; then
      BASE_REF="origin/$BASE_BRANCH"
    else
      BASE_REF="$BASE_BRANCH"
      echo "note: origin/$BASE_BRANCH does not resolve — measuring against the local branch, which may be stale" >&2
    fi
    git diff "$BASE_REF...HEAD" --stat
    git log --oneline "$BASE_REF..HEAD"
    

    スタックされた PR のスライスの場合は、$BASE_BRANCH を兄弟スライスのブランチ名(PR のターゲットとなる上流)で上書きし、そこから $BASE_REF を再導出します。ベースとの差分がなければ、レビュー対象がないことをユーザーに伝えて終了します。main をハードコードしないでください。Skill Kit 自体のリポジトリは prod を使用しており、ほかにも develop、trunk、チーム固有の名前を使っているリポジトリが多数あります。

    残存リスク: $BASE_REF の鮮度は最後の git fetch に依存します。また、三角形フォークの場合(または origin 以外の名前のリモートの場合)、origin/$BASE_BRANCH が存在しない、あるいは上流ではなく自分のフォークを追跡していることがあります。その場合、else ブランチはローカルブランチにフォールバックします。これは、このガードで回避しようとしている古い参照の動作です。もっともらしい誤った結果が何の通知もなく出ることで、この不具合が 5 か月間残っていました。そのため、黙ってフォールバックするのではなく、stderr にその旨を出力します。カウントが正しくないようであれば、git fetch を実行して再実行するか、BASE_REF を手動で設定してください。

  4. 対象範囲を決定します — ブランチ全体か、スタンプ後の差分か。 この決定は作成者モードのみで行います。ループモードではこれを省略し、フェーズ 3 のループモードの箇条書きに従って、毎回ブランチ全体を読み込むように SCOPE_FROM="$BASE_REF" を無条件に設定します。初回レビューではブランチ全体を読み込みます。このスキルがすでにスタンプを付けた PR に対する再実行で、その後に head が動いている場合 — /fix-findings のラウンド、または意図的なロック削除後の手動修正など — は、スタンプ後の差分を対象とします。/closeout のステップ 2 と同じ式を使ってスタンプを読み取ります。scripts/test-review-currency-marker.sh は両者がバイト単位で同一であることを固定し、scripts/test-delta-review-scope.sh は名前が示す各ブランチ状態のフィクスチャに対してこのブロックを実行します。

    REVIEWED_SHA=$(gh pr list --head "$(git branch --show-current)" --json body -q '.[0].body // ""' \
      | sed -n 's/.*.*/\1/p' | tail -1)
    SCOPE_FROM="$BASE_REF"
    if [ -n "$REVIEWED_SHA" ] \
      && git merge-base --is-ancestor "$REVIEWED_SHA" HEAD 2>/dev/null \
      && [ "$REVIEWED_SHA" != "$(git rev-parse HEAD)" ] \
      && [ -z "$(git log --merges --format=%H "$REVIEWED_SHA..HEAD")" ]; then
      SCOPE_FROM="$REVIEWED_SHA"
    fi
    if [ "$SCOPE_FROM" = "$BASE_REF" ]; then
      echo "review scope: whole branch, from $BASE_REF"
    else
      echo "review scope: post-stamp delta, from $SCOPE_FROM"
    fi
    git diff "$SCOPE_FROM...HEAD" --stat
    git log --oneline "$SCOPE_FROM..HEAD"
    

    4 つの状態では、意図的にブランチ全体へフォールバックします。スタンプがない(初回レビュー、または手動で作成された PR)。スタンプが HEAD の祖先ではない(ブランチが force-push され、レビュー済みのコミットが書き換えられて失われた — /closeout ではこれを より強い 分岐シグナルと呼んでおり、レビュー対象が減るわけではありません)。スタンプが HEAD と等しい(対象となる新しいものがない)。スタンプ後にマージコミットがある(スタンプ後の差分にベースブランチ自体の変更が含まれることになり、このブランチの誰もが書いたものではない)。判断結果を出力するため、ターミナルの表示と PR で、何を読み込んだかについて同じ内容が示されます。 差分を再レビューする場合、対象は差分であり、ツリーは引き続き閲覧できます。 各 Phase 3 レビュアーには、スタンプ後のコミットが解消したと主張する指摘事項を伝えてください。具体的には、このセッションで先に得られた報告、ループモードで記録されていれば PR の台帳、またはコミットメッセージです。また、該当する場合は /fix-findings のブレーカー判定も伝えてください。各コミットについて最初に確認するのは、修正が指摘事項で挙げられたすべての箇所でその指摘を解消しているかどうかです。これは Fix Completeness の次元です。2 つ目に確認するのは、新しいテキストが周辺の何と矛盾しているかです。これは references/restated-claims.md に記載されたセンサスです。どちらの確認にも周辺ツリーが必要であり、チェックリストのコンテキスト契約ではすでにその閲覧が認められています。スコープが狭めるのはレビューの 対象 であり、レビュアーが開けるものではありません。

レビュアーモード(--pr <number>):

  1. PR とその差分を取得します:

    gh pr view <pr-number> --json number,title,headRefName,baseRefName,body,author,url,state
    gh pr diff <pr-number>
    

    PR がすでにマージ済みまたはクローズ済みの場合は、その旨をユーザーに伝えて終了してください。クローズ済み PR へのレビューコメントは別途表示され、有用なことはほとんどありません。

  2. PR 本文から PRD の Issue を特定します。 Closes #<n>、Refs #<n>、または Issue を指す ## PRD セクションを探します。見つかった場合は、作成者モードのステップ 2 と同じ gh issue view とスライス Issue の検索を実行し、PRD のコンテキストと境界マップを読み込みます。PR に PRD の系譜がない場合は「PRD なし」の分岐として扱い、PRD が条件となる次元はそれぞれの **Runs in:** マーカーが割り当てるフェーズでスキップされます。

  3. PR の JSON から差分の規模とベースブランチを記録します。 ローカルブランチの計算はしません。gh pr diff はマージベースからヘッドまでの差分を直接返します。ローカルで PR をチェックアウトしないでください。レビューするのは差分であり、実行するのではありません。

フェーズ 2:PR を作成する

レビュアーモードでは、このフェーズ全体をスキップしてください。 PR はすでに存在し、あなたが作成したものではなく、他の人の PR 本文を書き換えることはスコープ外です。フェーズ 3 に進みます。

  1. 既存の PR を確認します:

    gh pr list --head $(git branch --show-current) --json number,url
    
  2. PR を作成または更新します。 gh pr create --base "$BASE_BRANCH" を使います(スタックされた PR のスライスでは、--base を兄弟スライスのブランチで上書きします)。または gh pr edit を使います。

PRD がある場合の PR 本文テンプレート:

## Summary

[For trivial PRs — typo fixes, dep bumps, formatting-only, single-line reverts — 1–2 sentences derived from the PRD's Problem and Solution sections.

For non-trivial PRs — behavior changes, new surface area, bug fixes with non-obvious root causes, refactors crossing module boundaries — write a plain-language walkthrough: one paragraph of domain setup, what changed and why each piece was the right move, and why it matters. Aim for a reader who doesn't have the codebase in their head. See `references/writing-for-humans.md` for the shape and revision bar.]

## PRD

Closes #<prd-issue-number>

## Slices

- [x] #N — Title (for closed slices)
- [ ] #N — Title (for still-open slices)

## Key Decisions

[Bullet list of notable implementation decisions that refined or diverged from the PRD. Derived from commit messages and slice issue comments. Omit this section if nothing diverged.]

PRD がない場合の PR 本文テンプレート:

## Summary

[For trivial PRs — typo fixes, dep bumps, formatting-only, single-line reverts — 1–2 sentences derived from the diff and commit messages.

For non-trivial PRs, write a plain-language walkthrough: one paragraph of domain setup, what changed and why each piece was the right move, and why it matters. See `references/writing-for-humans.md`.]
  1. /execute から引き継いだ場合は、## Review Notes ブロックを記載します。 作成者モードとループモードのどちらの引き継ぎでも、再実行可能な検証内容のブロックが渡されます。実行したコマンドと終了ステータス、スキップしたティアとその理由、Consumes ゲートの下で取り込まれたスコープ、変化した前提、既知の弱点が含まれます。## Summary の後に、そのまま記載してください。要約したり、言い換えたりしないでください。このブロックの価値は、レビュアーがその内容を再実行できる点にあります。また、要約のたびに、レビュー対象であるエージェントが作成した情報が失われます。このブロックの形式については、/execute のステップ 6 を参照してください。

  2. PR の URL を表示します。

  3. 後で本文にセクションが 1 つ追加されることを記録します。 フェーズ 4 では ## Review Currency ブロックを追加し、レビューが実際に対象としたヘッド SHA を記録します。これはフェーズ 3 の実行後に記載します。PR 作成時にスタンプを記載すると、まだ行われていないレビューを認証することになるためです。

フェーズ 3:アーキテクチャレビュー

レビューの次元とその違反パターンについては、review-checklist.md を参照してください。このファイルが一覧の唯一の定義元です。## N. 見出しのみが次元のセットを定義しており、ここでは繰り返し記載しません。3 つのモードすべてで次元は同じように実行され、読み込む diff だけが異なります。

  • Author-mode — ローカルの git diff "$SCOPE_FROM...HEAD"。Phase 1 のステップ 4 で、$SCOPE_FROM は $BASE_REF(初回レビューの場合:ブランチ全体)またはスタンプ済み SHA(再実行時に HEAD が移動している場合:スタンプ後の差分)に設定されます。差分の再実行では、各レビュアーに、スタンプ後のコミットで解消したと主張されている指摘と、阻止判定も伝えます。また、チェックリストのコンテキスト契約で許可される範囲で、差分の周辺にあるツリーも読みます。レビュー対象は差分であり、読み取り範囲ではありません。
  • Reviewer-mode — gh pr diff <pr-number> の出力。
  • Loop-mode — ローカルの git diff "$BASE_REF...HEAD"。実行のたびにブランチ全体を対象とし、loop-mode では差分のスコープを変更しません。loop-mode ではコミットを行わないため、後の実行で差分が変わるのは オペレーター が修正をプッシュした場合だけです。解決済みの指摘が再報告されないようにするのは、絞り込まれた差分ではなく台帳です。

委任するのはレビュアーの独立性を確保するためです。大きな差分での並列化は、その一例です。 /execute のステップ 6 から /pre-merge が自動実行されると、コードを書いたばかりのセッションで実行され、実装エージェントが作業中に行ったあらゆる自己正当化を抱えています。観点は妥当でも、レビュアーは独立していません。Cohen の指摘によれば、作者の役割はレビュアーに 注釈を付ける ことであり、自らレビュアーになることではありません。したがって、以下のサブエージェント分割は、まず差分を新鮮なコンテキストでレビューするためのものであり、大きな差分での所要時間を半減させるのは二次的な目的です。

そのため、3 つすべてのモードで委任は無条件に行います。コードを書いたセッションが、自分の差分をインラインでレビューすることはありません。唯一の例外はサイズではなく 内容 によって定められます。Phase 2 の 2 つの本文テンプレートですでに挙げられている 4 つの軽微なクラス、つまり誤字修正、依存関係の更新、書式設定のみの変更、1 行のリバートは、同一セッション内でレビューします。Phase 3 で用いる軽微/非軽微の区別はこれだけです。この免除は Phase 3 のみが対象です。Phase 4 の最小指摘数ガードに抵触するほど大きな軽微クラスの差分は、そこで引き続き委任します。

サイズによって決まるのはサブエージェントの 数 であり、レビューを作成セッションの外に出すかどうかではありません。

  • 小規模な差分(変更行数 200 行未満、ファイル数 10 個未満):チェックリストでサブエージェントに割り当てられており、各自のゲート条件を満たすすべての観点を、1 つのサブエージェントが実行します。各観点のゲート条件はチェックリスト内の該当セクションに記載されています。以下の注記ではいくつかの項目を補足しますが、一覧を網羅するものではありません。
  • 大規模な差分:同じ観点群を分担する 2 つのサブエージェントを並列で起動します。

いずれの場合も、コントローラーが担当する観点はこの選択の対象外です。差分のサイズによって決まるのは実行する サブエージェント の数だけであり、チェックリストでサブエージェントへの委任対象から外されている観点まで委任するかどうかではありません。

トリガーがサイズではなく内容に基づく理由。 Cohen の Cisco データセットは、実証結果をもってこの代替指標の役目を終わらせています。1~2 行のレビュー 4 件に、それぞれ 15 分以上かかりました。物理的な変更が小さくても、アーキテクチャ規模の影響を伴っていたためです。このリポジトリにも同様の事例があります。34 行、2 ファイルの差分は従来の基準内に十分収まっていましたが、作成セッションでのレビューは構成上の欠陥を見逃しました。その一方、クリーンなコンテキストでのレビューでは、1 回の実行で 8 件の指摘があり、最も重要な Concern として報告されました(docs/solutions/architecture-decisions/self-review-blind-to-composition-2026-08-13.md)。基準を削除して代替指標の役目を終わらせつつ、基準が実際に保護していたものは、より対象を絞った 4 クラスの免除で維持します。

サブエージェントを利用できない場合は、各観点を同一セッション内で実行し、指摘の出力で実行モードを degraded mode と明記します。レビュアーは作成セッションのコンテキストを引き継ぐため、独立性が失われ、指摘はその前提を踏まえて読む必要があります。これは、弁証法的な検討を起動できない場合に /improve-pipeline の Phase 4 が行う宣言と同じです。degraded mode は開示であり、2 つ目の免除ではありません。委任が面倒だからといって選ばないでください。

コンテキスト契約が定めるのは、許可ではなく出所です。 これは 3 つの部分から成り、限定列挙されているのは最初の部分だけです。 引き渡すもの — 3 つのモードすべてで同じです。 差分、review-checklist.md、references/writing-for-humans.md、および存在する場合は PR 本文の ## Review Notes ブロックです。それ以外は何もサブエージェントに 与えません。特に、実装セッションのコンテキストは与えません。reviewer-mode でレビューする外部作成の PR には、/execute が実行されていないため、## Review Notes ブロックはありません。これは入力が存在しないのであって、手順が抜けているのではありません。

自ら参照するもの — 永続的な状態を、ソースで読むこと。 各観点の手順では、サブエージェントに上記の一覧を超えて、マージ済みのツリー、ブランチのコミット履歴 — git log、コミットメッセージ、コミットごとの差分 — 削除されたパスに対する git show、スライスや PRD のイシュー本文、パッケージレジストリ、調査アーカイブ、インストール済みの .d.ts、docs/solutions/、一時的な tsc --noEmit などを参照させる場合があります。コミット履歴をその一覧に含めるのは、2 つの観点がこれなしでは実行できないためです。Vertical Slice Integrity はコミット構造そのものに基づいて定義されており、Surgical Scope は最後の手段として、明示されたタスクのソースにコミットメッセージとブランチ名を挙げています。これは差分の要約ではなく独立した成果物なので、読んでも以下のルールには触れません。reviewer-mode では、ローカルでチェックアウトしなくても gh pr view <n> --json commits でコミットメッセージと SHA を参照できます。 コミットごとの差分は返されないため、それを必要とするパターンはそこで確認できません。これは契約の例外ではなく、契約が機能している状態です。永続的な成果物を自ら読むことが独立性を 保ちます — それを損なうのは、レビュー対象のセッションがその成果物をあらかじめ解釈して渡すことです。適用されるルールは 1 つです。ソースで読み、引用すること。コントローラーの説明を決して受け入れないこと。 差分の要約ではなく差分そのものをレビュアーが読むのも、常に存在する 1 つの入力に同じルールを適用したものです。

絶対に与えないもの — 変更のコンテキストです。 ここでいう変更のコンテキストとは、作成セッションの作業状態、つまり推論、退けた代替案、差分の作成中にまとめた正当化の説明、およびサブエージェントが直接読めたはずのものに代わる、コントローラーが作成した説明、要約、言い換えを指します。## Review Notes は作成者が書いたものですが引き渡します。これは 検証可能な 記録であり、/execute の Step 6 で、レビュアーが再実行できるコマンドと終了ステータスが求められているためです。引き継ぐべき解釈ではありません。

これによって判定できること。 観点自体が指定する手順に従い、差分と上記の種類の永続的な状態から証拠にたどり着ける場合、サブエージェントは指摘を立証できます。単独の手順では再構成できない、複数の成果物をまたいで組み立てた 見解 が指摘に必要な場合は立証できません。これがコントローラーバケットの根拠であり、ここで一律のルールとして示すのではなく、各コントローラー所有の **Runs in:** マーカーで観点ごとに示します。

Loop-mode で追加されるのは、1 つだけです。 2 パス目以降は、台帳に記録された 状態と証拠 です。これにより、オペレーターがすでに解決した指摘をそのパスで再報告しません。前回のパスでの重大度の判断は決して追加しません。前方に渡すものと渡さないものの区分、およびその理由の全容は、Phase 5 の台帳セクションに記載されています。

どちらの参照ファイルも ルーブリック です。確認すべき事項と、最終的な文章が満たすべき基準を示します。独立性の契約で与えないのは 変更のコンテキスト です。レビューに適用する基準を伏せるという意味ではありません。

区分はチェックリストから導きます。ここで繰り返し定義するものではありません。 review-checklist.md の各観点には、見出しの直下に **Runs in:** マーカーがあり、所有者として sub-agent A、sub-agent B、the controller, in Phase 4 のいずれか 1 つだけが明記されています(各バケットのテーマはチェックリストの凡例で定義されています)。マーカーを確認し、各サブエージェントに、その担当として示された観点を渡してください。コントローラー担当の観点はサブエージェントの作業 ではなく、委任もしません。必要な GitHub の状態がすでに読み込まれているセッション内で、Phase 4 が実行します。 これは意図的にリストにはしていません。手作業で管理された担当一覧のコピーをここに置いていたところ、作成当初から誤った内容のまま出荷されていました。この経緯はヘッダーに記載されており、scripts/test-review-dimension-partition.sh は、基準が未割り当てのままにしているディメンションがあれば失敗します。

各サブエージェントは差分全体と、割り当てられたディメンションを review-checklist.md から読み込み、その後、3 段階の重大度形式で指摘を返します。各 Suggestion と Concern は、references/writing-for-humans.md にある形式と改訂基準に沿って記述します。このドキュメントは issue と PR の本文を対象としていますが、指摘文の評価基準として引き継ぎます。Phase 4 の免除規定により、Observations は対象外です。これは、成果物の種類を対象外とし、指摘には及ばないドキュメント独自の「どんな場合に省略するか」のリストとは異なります。Phase 4 には、その基準と理由が記載されています。

レビュー担当者は常に実際の差分を読み、要約を読むことはありません。 要約は、レビュー対象のコントローラーが作成した情報損失を伴う変換です。コンテキストを新たにすることで得られるのは、合理化からの独立性であり、誤報への対策ではありません(Leveson:どんな制御システムも、その測定チャネルを超える性能は発揮できません)。

ゲート、しきい値、ディメンションごとの手順は、チェックリストにのみ記載します。 ディメンションの中には、差分が個別の条件を満たした場合にのみ適用されるものがいくつかあり、数値範囲、免除規定、または指定された検証手順を持つものもあります。すべて各ディメンションの見出しの下に記載されています。各サブエージェントに担当内容を渡し、独自のゲートを読ませてください。ここにコピーすると、同じ主張を扱う運用上の場所が二つになり、一方のファイルで範囲を変更しても、もう一方には古い内容が残ったまま出荷されます。これは references/restated-claims.md が定義するクラスであり、このスキル独自の Deep Modules の箇条書きが検出するものです。scripts/test-restated-review-operatives.sh はその一部を対象としています。どの部分を対象とするかを記載しているのはそのヘッダーだけであり、ここでは再掲しません。テストが成功していても、そのクラスが解消済みだと判断する前に、ヘッダーを読んでください。

TypeScript プロジェクト: /ts-audit は、変更された .ts/.tsx ファイルの型安全性分析により、アーキテクチャレビューを補完します。実行するかどうかはモードによって異なります。

  • 著者モードとレビュー担当者モード:言及はしますが、実行しません。 .ts または .tsx に大幅な変更があるブランチでは、選択肢として言及してください。「より踏み込んだ TypeScript 分析を行うには、変更されたファイルに対して /ts-audit を実行することを検討してください」と伝え、判断はユーザーに委ねます。これは意図的な HITL の境界であり、以下のスコープによって変わることはありません。ここでは「大幅な」という柔軟な基準が適切です。判断を誤った場合のコストは、不要な一文が増えるだけだからです。
  • ループモード:自動的に実行し、その結果をディメンションごとの指摘とともに Phase 5 の台帳に記録します。この時点で、まさにこれらのファイルに対して実行することが次の推奨アクションになっています。これまで手動だった唯一の理由は、サイクルを回す仕組みがなかったことです。ただし、言及のルールには不要でも、実行のルールには判定可能なトリガーが必要なため、制約を一つ設けます。
    • トリガー — 変更された .ts/.tsx の行数が 50 行を超えるか、変更された .ts/.tsx ファイル数が 2 件を超える場合。行数とファイル数は、このパスで読み込む差分を基準に測定します。これに満たない場合は監査を省略し、黙って見過ごすのではなく、台帳の「Checks not run this pass」の行に省略したことを記録します。これは、Review-friendly Size が抑制されたサイズ指摘についてすでに採用しているのと同じルールです。「大幅な変更」は、人間がツールに言及するかどうかを判断する指示としては使えますが、ループが実行の要否を判断する基準としては評価できません。
    • 以前のパスで挙げられた指摘と重複するものは、台帳と照合し、二重に追加せず、すでに存在する行としてそのまま残します。 疑うのではなく、検証してください — ライブラリのコールバックのセマンティクス、サブパスの差し替え、プロバイダーのスキーマ制約。 調査結果が、アプリケーションから渡された値をライブラリがどう扱うか(コールバックからの戻り値、フックに渡されるオブジェクト、systemMessages/tools/middleware コレクションのセマンティクス)に左右される場合、サブエージェントは調査結果にインストール済みの型定義を引用しなければなりません — node_modules/<library>/**/*.d.ts のファイルパスと行番号を記載します。この機能について調査アーカイブの項目がある場合は、その callback_contracts_snapshot を優先してください(research/SKILL.md Phase 1.25 を参照)。パッケージのどのサブパスを経由してインポートが解決されるか、つまりマルチランタイムパッケージの兄弟サブパス間で型のみの差分を装ったランタイムに影響する差し替えが調査結果の根拠となる場合は、installed_versions_snapshot を優先してください(research/SKILL.md Phase 5b を参照)。Boundary Map Contracts の仕様と実態の照合項目 2 が、この情報を利用するゲートです。SDK がプロバイダーをラップする場合のプロバイダーのスキーマ制約が調査結果の根拠となる場合 — SDK の型シグネチャはある形式(JSON Schema、Zod、ツール定義)を受け付ける一方、基盤となるプロバイダーの実際の契約では拒否される場合(例:Gemini の response_schema は数値列挙型を拒否する、Anthropic の tool.input_schema は JSON Schema の一部しか扱わない、OpenAI Structured Outputs のスキーマサブセットは JSON Schema 2020-12 と異なる) — 引用には、インストール済み SDK バージョンに対応するプロバイダーの契約ドキュメントを含める必要があります。SDK の寛容な .d.ts だけでは不十分です。この種の調査結果で、出典の引用なしに「ライブラリが X をマージせず置き換える場合」「このフィールドが受け付けられる場合」「SDK には任意のスキーマを渡せる」といった断定を避けた表現を使うことは認められません — 根拠は grep ひとつ、またはプロバイダーのドキュメントページひとつで確認でき、障害はランタイム上で見えないためです。出典を引用し、重大度ルールに従って Observation/Suggestion/Concern に分類するか、「マージ前に検証」という明示的なアクションを付けた名前付きのフォローアップ項目に格下げしてください。
Phase 4: 調査結果の提示

まずコントローラーが担当する観点を実行し、その後、すべての観点(またはサブエージェント)の調査結果をまとめてください。

コントローラーが担当する観点は、このセッションでここで実行します。 review-checklist.md で **Runs in:** マーカーが the controller, in Phase 4 となっている観点はすべて、あなたが実行してください — Phase 3 では委任されておらず、サブエージェントが実行した可能性もありません。これらの観点にそのマーカーがあるのは、手順の実行に PRD、各スライスの課題、マージ済みスライスの集合を一度に見渡す必要があるためです。Phase 1 ではまさにその情報がこのコンテキストに集約されており、作業がここで行われる理由もそこにあります。

該当する各観点の手順を review-checklist.md から読み、今すぐ実行してください。その調査結果は通常の調査結果です。チェックリストで割り当てられた重大度を持ち、以下の 3 段階に加わり、ループモードでは他と同様に台帳の行が作成されます。特に、コントローラーが担当する観点からの Concern も、エスカレーションの明示を含め、依然として Concern です — チェックの実行場所が変わっただけで、判定の重みは変わっていません。Concern より上の段階はありません。判定によってマージを止めるべき観点は、Concern 内でそのアクションを明示します。未対応の Must に対して Coverage Matrix Reconciliation が行うのがこれです。

その後、ほかのすべてと同じ証拠確認の基準を適用してください。コントローラーが担当する観点も、根拠の引用を免除されません。免除されるのは、すぐ下の委任された調査結果の確認だけです。これはサブエージェントによる誤報を検出するためのものであり、ここにはサブエージェントがいないからです。

コントローラーが担当する観点自体が実行条件を満たさない場合 — Coverage Matrix Reconciliation は、この PR が複数スライスの PRD の最後のスライスを完了するときにのみ実行されます — Review-friendly Size がサイズに関する調査結果の抑制を明示するのと同じように、黙って省略せず、その旨を調査結果の出力に記載してください。何も報告しなかった観点と、一度も実行されなかった観点は、それ以外では同じように見えます。その曖昧さこそが、この観点が何か月ものあいだ抜け落ちていた原因です。 委任された指摘は、提示する前にツリーと照合してください。 委任によってひとつの失敗モードは取り除かれますが、別の失敗モードが表面化します。新しいコンテキストによって 合理化 から独立できますが、誤報 に対しては何の対策にもなりません(Leveson — Phase 3 では要約について述べられていますが、サブエージェントの出力にも同じことが当てはまります)。ループモードではすでに Phase 5 Step 2 で対応しており、ツリーが主張と矛盾する場合は refuted — <evidence> を記録します。著者モードとレビュアーモードには同等の仕組みがなかったため、サブエージェントの誤報が、読者との間に何の確認も挟まず助言として表示されていました。重要なレビューがすべて委任されるようになった今、この抜けはデフォルトの経路に存在します。

そのため、委任された指摘ごとに、このコンテキストから Phase 3 の「疑うのではなく、検証する」ルールを適用します。つまり、指摘を裏付ける、または反証する grep、ファイルパス、行を確認します。指摘がライブラリのセマンティクスに依存する場合は、インストール済みの型定義を確認します。そのうえで、次のように対応します。

  • ツリーによって裏付けられる — 指摘内で証拠を引用して提示します。
  • ツリーによって反証される — 指摘として提示しないでください。事実に関する注記として一度だけ記録し(sub-agent B reported X; path:line contradicts it)、3 つのティアの後に、以下の他の報告のみの注記と並べて表示します。これにより、黙って削除するのではなく、確認が行われたことを明示できます。Scope Notes のように PRD の有無には左右されません。PRD のないレビューで反証された指摘にも、その行を含めます。
  • ツリーから確認も反証もできない — 扱いは、その指摘が「疑うのではなく、検証する」ルールの対象となる種類かどうかによって異なります。ライブラリのコールバックのセマンティクス、サブパスの解決、またはプロバイダーのスキーマ制約に関する指摘であれば、そのルールの格下げ条項を適用します。Observation、Suggestion、Concern のいずれとしても表示せず、「マージ前に検証する」という明示的なアクションを伴う、名前付きのフォローアップとして表示します。このルールはすでに、この種類の指摘に引用がない場合はティアを付けないと定めています。また、その指摘を引用できなかったコントローラーも、引用の状態を変えてはいません。それ以外の指摘は、未検証の根拠を明記したうえで、サブエージェントが割り当てたティアで提示します。格下げ条項の対象外であり、そのティアを認めるものでもありません。

確認することは、再判定することではありません。親は主張を検証しますが、サブエージェントの重大度を再評価したり、複数のサブエージェントの指摘を相互に調整したりはしません。

このルールが適用されるのはターミナルでの提示のみであり、ループモードでは Phase 4 を実行します。 反証された指摘も、反証を添えて open の台帳行として記録されます。Phase 5 Step 1 はフィルタリングせず、Phase 3 のすべての指摘を取り込みます。また Step 2 は、指摘を削除するかどうかはオペレーターが判断することだという明確な根拠により、反証された指摘も残します。反証された指摘をターミナルで非表示にするのは提示上の処理ですが、台帳から非表示にするのは、台帳が防ぐために存在する未認識の報告になってしまいます。2 つのルールが食い違う場合は、台帳を優先します。 最小指摘数ガード。 提示する前に、指摘の合計数を数えます。3 段階すべてに加え、マージ前に確認するフォローアップへ格下げされたものも含めます。これらは指摘がなくなったのではなく、印字位置が移った指摘です。Phase 3 の差分を読んだ時点で合計が 4 件未満で、差分がある程度の規模(変更行数が約 50 行を超える、またはファイル数が 2 つを超える)の場合は、見落としがないかを明示的に探すため、もう一度、対象を絞って確認します。最初のレビューではブランチ全体を、再実行ではスタンプ後の差分を対象にします。そのため、2 コミットの修正でこの条件に引っかかることはありません。この 2 回目の確認は、新しいサブエージェントで、Phase 3 が指定するものと同じコンテキストを使って実行します。このコンテキストで読み直してはいけません。 Phase 4 から起動するため、そのことを明示し、ここに列挙したものではなく Phase 3 の記述に基づいてコンテキストを読み取ります。ループモードで追加される 1 項目、つまり台帳に記録された状態と証拠も含めます。契約から離れたところで列挙すると、この文から以前台帳が抜け落ち、オペレーターがすでに解決した指摘を 2 回目の確認で再報告することになりました。その指摘も、ほかの指摘と同じ読み手の基準を満たす必要があります。コントローラーが担当する観点はスキップするよう指示してください。 チェックリスト全体を渡しますが、その観点は上で処理済みです。実行済みか、対象外として明示されています。Phase 3 のサブエージェントには、担当する観点を明記したチェックリストが渡されるため、コントローラーが担当する観点が提示されることはありません。Phase 4 の 2 回目の確認では、担当の指定がないファイルを渡すため、スキップする観点を伝える必要があります。そうしなければ、確認でその観点が暗黙に抜け落ちるか、判断を下せないコンテキストから再確認されます。このガードは、1 回目の確認で指摘が少なかった場合にのみ発動します。バイアスによる盲点は、自分自身で衛生管理を行えないことを意味します(Kahneman、Sibony、Sunstein、『Noise』)。1 回目と同じコンテキストで読み直しても、指摘が少なかったレビューが再現され、それが独立した 2 回目の確認として取り繕われるだけです。その指摘は、ほかの委譲された指摘と同様に、上記の証拠確認を経ます。重要な差分で指摘が 0 件または 1 件なら、レビューが早々に終わった兆候であり、コードに問題がないという意味ではありません。2 回目の確認後も件数が少ない場合は、得られたものを提示してください。ノルマを満たすために指摘をでっち上げてはいけません。

各指摘に、PR 本文と同じ読み手の基準を適用してください。 Phase 2 ではすでに、重要な PR の本文を書く際に、平易な言葉で説明することが求められています。指摘には同等の基準がありませんでしたが、指摘こそこのスキルの主な成果物であり、本文はその周りを支えるものです。読み手が理解できない指摘は、指摘がまったくなかった場合と同じように失敗します。そして、その失敗は気づかれないままです。段階は印字され、台帳の行には担当者が記録されているのに、シグナルが伝わらなかったことは何も示されません。そこで、各 Suggestion と Concern は references/writing-for-humans.md の構成と推敲の基準に従って書きます。システムの該当箇所をドメイン用語で示し、条件を付ける前に主張を先に述べ、何を防止するか、または何を可能にするかで締めくくったうえで、余計な部分を取り除きます。

制限が 2 つあります。Observations は対象外であり、ドメイン上の意味が自明な指摘も対象外です。 命名パターンについての 1 行の注記に、ドメインの説明は必要ありません。この例外は、このスキル独自の規則としてここに記しています。文書の「省略するケース」の一覧をそのまま借りたものではありません。その一覧が対象とするのは成果物の種類(誤字修正、依存関係の更新、フォーマットのみの PR、1 行のリバート、再現が容易なバグ)であり、指摘には適用されないためです。この 5 つのうち 4 つは、Phase 3 がそもそも委譲しない差分です。そのため、レビュー用サブエージェントに渡される一覧は、構造上そのサブエージェントには当てはまりません。引き継がれるのは、その下にある締めくくりの規則です。迷ったら、冗長な説明より 1 文を選んでください。 次に、基準となるのは長さではなく明確さです。長くなっても明確にならなかった指摘は、この基準を満たしていません。これについては、先述の最小指摘数のガードと合わせて確認してください。あちらのガードは、件数を満たすために指摘を捏造することを禁じ、こちらは、すでにある指摘を水増しすることを禁じています。

この基準は指摘文そのものに適用されるため、3つのモードすべてに引き継がれます。author-mode のターミナルでの注意事項、同じ指摘を基に作成される reviewer-mode の下書き、そして作成したセッションが終了した後も残る loop-mode の台帳行が対象です。最後のものは、読む人が最も文脈を知らない状態で目にします。

指摘は基準を満たす形で書かれて届くものとし、このフェーズでは言い換えません。 Phase 3 では、委任する場合もセッション内で作成する場合も、作成者の依頼内容にこの義務を含めます。これにより、ここで後から整えるのではなく、作成時点で基準を満たします。この禁止事項の範囲は狭く、対象となる行為は1つだけです。返された指摘の文章を整えるために書き換えることです。author-mode では、親はコードを作成したセッションです。そのため、独立したレビュアーの指摘を受け取り、親が言い換えると、委任によって確保した独立性が損なわれます。指摘が基準を満たさない場合は、ここでの仕上げではなく、Phase 3 の依頼内容を修正してください。

指摘を基に親が作成した文章はこの禁止事項の対象外であり、直接この基準が適用されます。reviewer-mode の Triple-R Rationale と loop-mode の台帳の Finding セルはいずれも親が作成するため、どちらにもこの基準が適用されます。

Author-mode では、以下の3段階でターミナルに注意事項を表示します。Reviewer-mode では、同じ指摘を PR コメントの下書きに変換します(下記「Reviewer-mode のコメント下書き」を参照)。適用される観点と重大度の分類は同じですが、出力形式は異なります。

ターミナルでは、以下の3段階で表示します(author-mode)。

## Architectural Review

### Observations (for awareness — no action needed)

[Patterns noticed that aren't violations. Example: "The presence module
exports 6 functions — reasonable, but worth watching if it grows."]

### Suggestions (action optional — would improve quality)

[Grouped by dimension. Things that aren't violations but would make
the code better. Written to the reader bar above.]

### Concerns (action recommended — potential principle violation)

[Grouped by dimension. Each concern cites the principle, shows the
specific code, and explains why it matters — and reads cold to someone
who did not write the diff, per the reader bar above
(`references/writing-for-humans.md`).]

### Verify before merge (findings that hold no tier)

[Findings the "Verify, don't suspect" downgrade clause removed from the
tiers — library callback semantics, subpath resolution, or provider schema
constraints that nothing could cite. Each names the check that would settle
it. Omit the section when there are none.]

---
No action is required. These are advisory.
When ready, merge the PR at <PR-URL>.

このブロックをもって、author-mode でのレビューは終了です。 以下の Phase 4 の残りを完了してから、## Handoff の次のステップメニュー(references/next-step-menu.md)に進んでください。指摘への対応をどうするかはこのメニューで決定します。選ぶのはユーザーであり、このセッションではありません。

スコープに関する注記(スライスの課題を含む PRD が提供された場合のみ):

3段階の指摘の後に、計画された分割と実際の差分との間に大きなスコープのずれがあれば注記します。

  • 差分には含まれているものの、どのスライスの Boundary Map にも含まれていない作業(実装中に判明した、漏れていたスコープ)
  • 宣言された Produces が差分に含まれていない場合(計画されていたものの、削除または延期された作業)
  • 実際の差分の範囲が、Boundary Map で宣言されたスコープと大きく異なるスライス

これらは事実に関する注記であり、レビュー指摘ではありません。Observations、Suggestions、Concerns は生成せず、計画と実際の差異を記録します。これにより、そのパターンを記録する価値があるかどうかをユーザーと /compound が判断できます。差分と計画された Boundary Map がほぼ一致している場合は、このセクション全体を省略してください。

受け入れ基準のチェックボックスの照合(報告のみ)。 スライスの課題を読み込んでいる間に、各スライスの ## Acceptance Criteria のチェックボックスの状態と、マージ後の差分および検証結果で実際に確認できる内容を照合します。不一致があれば事実に関する注記として報告します。たとえば、達成済みと読める基準のチェックボックスが未選択のままの場合や、チェック済みでも差分による裏付けがない場合です。EARS 形式(When/While/If … then で始まり、動作を示す shall 節を含む)で書かれた基準には、検索用の手がかりがあります。差分内のテスト名とアサーションでその節を探し、同じ種類の事実に関する注記として、該当する節がどこにも見つからない場合は報告します。節が一致すればテストが存在することは分かりますが、そのテストが正しいとは限りません。これは上記の照合を補助するものであり、照合に代わるものではありません。報告してください。課題は編集しないでください。これらのチェックボックスを書き込むのは /execute のみです(Step 5/6 の書き戻しを参照)。/pre-merge は助言のみを行い、書き込みはしません。したがって、これは2つ目の編集者を設けずに差異を明らかにする、マージゲートの最終確認です。 クローズ対象 issue のコメントスレッドとの照合(報告のみ)。 フェーズ 1 ではコメントスレッドを取得せずにスライスの issue を読み込むため、コメントにしか記載されていない要件は、ここまでのどのチェックでも見えません。PR 本文の Closes #N 行に記載された issue のみ(フェーズ 1 で読み込んだすべてのスライスではありません)についてスレッドを取得し、本文と照合してください。

gh issue view <closing-issue-number> --comments

本文の受け入れ条件でカバーされておらず、かつ利用者を特定できる具体的な機能に言及したコメントがあれば、事実として報告してください(利用する issue、スライス、PRD、またはリリース済みコードを特定できるもの)。/execute のステップ 1 と同じ判別基準を適用してください。利用者が特定されていない探索的なコメントは対象になりません。マージによって issue がクローズされるため、スレッドが未完了の作業にまだ紐づいているのはこの時点が最後です。報告してください。issue を編集したり、自分でフォローアップを起票したりしてはいけません。書き込みを行うのは /execute のみです。これにより、そもそも /execute が issue に対して実行されなかったケース(手作業で作成した PR、外部からのコントリビューション)を補完します。

レビューから主な教訓が Skill Kit 自体に関するものだと分かった場合(たとえば、chrislacey89/skills におけるステージ境界が不明瞭、ハンドオフのガイダンスが不足、レビュー用チェックリストに漏れがある場合など。下流のコードベースの問題ではない場合)は、次のように記してください。「そのスキルが存在する場合は、/improve-pipeline の実行を検討してください。」実行してはいけません。

懸念事項についてさらに深掘りした作業が必要な場合は、次のように記してください。「この領域について、/request-refactor-plan の実行を検討してください。」実行してはいけません。

指摘事項が動作上のバグと思われる場合は、次のように記してください。「検証のために /qa の実行を検討してください。」issue を起票してはいけません。

マージしようとしている人が差分を作成した本人ではない場合、またはコミットごとに内容を十分に理解していない場合は、次のように記してください。「マージ前に、コミットごとの内容を対話形式で理解するため、/walk-commits の実行を検討してください。」実行してはいけません。これは理解と承認のための確認であり、上記の不具合レビューとは別のものです。これらの指摘事項に代わるものではありません。

該当事項がない段階は省略してください。

1 つの指摘事項について、対応方法が 3 つ以上に分岐する場合は、選択肢を比較形式で提示してください。 ほとんどの指摘事項は対応方法が明らかで、特別な説明は不要です。しかし、そうでない場合もあります。同じ懸念事項に対して、このブランチで修正する、issue を起票する、理由を添えて受け入れる、または誤りとして却下する、という選択肢があり得ます。これらはフェーズ 5 の台帳ですでに定義されている 4 つの状態です。それぞれ、結果として生じる状態、コスト、「どのような場合に選ぶか」が異なります。この分岐が references/next-step-menu.md の「選択する前に比較を提示する」のしきい値を満たす場合(相互排他的な選択肢が 3 つ以上あり、それぞれに 3 つ以上の属性があり、単一の軸では順序付けできない場合)は、属性を行、対応方法を列とする表で提示してください。各セルには file:line を引用するか、「断定」と記してください。しきい値に満たない場合は、通常どおり文章で記述してください。

このフェーズで行うのは提示であり、選択はしません。また、この段落によってその点が変わることもありません。比較は指摘事項を分かりやすく提示するための手段であり、周囲の三段階形式と同じです。対応方法を決めるのはオペレーターです。author-mode では以下のハンドオフメニューで、loop-mode では台帳に状態を書き込むことで対応を決めます。比較は、その前にオペレーターが読むものです。ここで提示した比較を理由に、そのメニューへ選択肢を追加してはいけません。

レビュー済みの HEAD SHA を PR に記録します(author-mode と loop-mode)。 上記のレビュー対象は特定のコミットです。PR 本文にそのコミットを記録し、後日、別のセッションで実行される可能性もある /closeout が、マージしようとしている差分がレビュー済みの差分のままかどうかを判断できるようにしてください。将来の記憶はひそかに失われるため(Norman)、マーカーはオペレーターの記憶ではなく、永続的な GitHub の状態に記録します。これを参照するのは /closeout ステップ 2 のレビュー有効性の事前条件だけです。

記録するのは、上記の指摘事項を提示した後に限ってください。このマーカーは「この SHA でレビューを完了した」ことを示すため、それより前に記録すると、まだ実施していないレビューを完了済みとして証明することになります。

REVIEWED_SHA=$(git rev-parse HEAD)
SHORT_SHA=${REVIEWED_SHA:0:7}   # pinned, not `git rev-parse --short` — see the width note below
BODY_FILE=$(mktemp)   # unique per run — parallel worktrees must not share a temp path

# Guard the read half. Check the fetch's exit status, not just the file's size:
# a 5xx makes `gh` fail, and the edit below would then replace the whole PR body
# with a stamp. `--json` parses the response, so a success exit means the body is
# whole; the emptiness check below is for a PR whose body is genuinely blank.
if ! gh pr view <pr-number> --json body -q .body > "$BODY_FILE"; then
  echo "stamp aborted: PR body fetch failed" >&2; rm -f "$BODY_FILE"; exit 1
fi
[ -s "$BODY_FILE" ] || { echo "stamp aborted: PR body came back empty" >&2; rm -f "$BODY_FILE"; exit 1; }
ORIG_BYTES=$(wc -c < "$BODY_FILE")

# In "$BODY_FILE": replace the existing "## Review Currency" section if one is
# present; otherwise append this block, substituting the real SHAs:
#
#   ## Review Currency
#
#   
#   Reviewed by `/pre-merge` at `<short-sha>`. Commits pushed after this SHA have
#   not been through the review dimensions — `/closeout` surfaces the delta before merge.
#

# Guard the write half. With $SHORT_SHA pinned above, stamping only ever appends
# one block or swaps one fixed-width block for another, so the edited body is
# never shorter than what was read. Shorter means the edit dropped content.
[ "$(wc -c < "$BODY_FILE")" -ge "$ORIG_BYTES" ] || { echo "stamp aborted: edited body is shorter than the body read" >&2; rm -f "$BODY_FILE"; exit 1; }

# Guard the write half too. Everything below this line — including the local
# flag that locks the branch — runs only if the stamp actually landed in the PR.
# An unchecked `gh pr edit` would leave the PR body unstamped and the flag on
# disk, which locks the branch on the strength of a review nothing recorded.
if ! gh pr edit <pr-number> --body-file "$BODY_FILE"; then
  echo "stamp aborted: PR body write failed" >&2; rm -f "$BODY_FILE"; exit 1
fi
rm -f "$BODY_FILE"

# The stamp's local twin. `.claude/.review-stamped` is read by
# .claude/hooks/enforce-classification.sh, which refuses implementation writes
# while it exists and .claude/.fix-findings-active does not — so a post-review
# fix has to go through /fix-findings or through a visible hand deletion.
# /closeout removes it at merge. The guard on the `gh pr edit` above is what
# makes this line reachable only after the stamp write succeeded; without it the
# touch would run on an aborted stamp too.
# $CLAUDE_PROJECT_DIR is unset outside a Claude Code session, and an unguarded
# expansion would resolve to "/.claude" — a silent no-write that leaves the
# lock disengaged while everything above reports success.
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel)}"
mkdir -p "$PROJECT_DIR/.claude" && touch "$PROJECT_DIR/.claude/.review-stamped"
  • 3 つのガードはいずれも修復せずに拒否します。また、中断はレビューの失敗ではありません。 フェッチは1 回だけ、失敗した書き込みも1 回だけ再試行してください。書き込みは追記ではなく、ファイルの内容で本文を置き換えるため、再試行してもスタンプが二重に付くことはありません。2 回目も中断した場合は、その旨を報告し、すでに提示した所見を有効なまま引き継いでください。この上限は重要です。このガードのきっかけとなったインシデントでは、不安定な API に対する無制限の再試行ループが、時間計測されていない要因の一つでした。スタンプが失われても、レビューの最新性について /closeout プロンプトが 1 つ増えるだけです。PR 本文を上書きすると、系譜、Closes #N の行、そして /execute が書き込んだ ## Review Notes が失われます。他にはコピーが存在しないものです。
  • $SHORT_SHA は、git rev-parse --short の結果を使わず、7 文字に固定されています。 --short が選ぶ略記の長さは可変で、リポジトリの成長に伴って長くなるため、スタンプを付け直すと 8 文字の短縮形が 7 文字のものに置き換わり、読み込んだ本文より 1 バイト短くなることがあります。その場合、正しい書き込みであっても書き込みガードは正しく拒否します。幅を固定することで、ガードの「決して短くならない」という前提が、ほぼ正しいのではなく、確実に正しくなります。
  • HTML コメントには 40 文字の完全な SHA を記載します。短縮形は使いません。 2 つのプレースホルダーは隣接する行にあり、相互に置き換えられません。<full-sha> は切り詰めていない git rev-parse HEAD の出力で、<short-sha> は短縮形であり、表示される文章の行でのみ使用します。/closeout は抽出したマーカーを headRefOid と比較しますが、これは常に 40 文字です。そのため、コメント内の短い SHA が一致することはありません。一致しない場合、head が動いていない PR でもゲートが差分を報告し、誤報するゲートはクリックして通過されてしまいます。/closeout のパーサーは 40 桁の 16 進数文字を厳密に要求するため、プレースホルダーを取り違えても、静かにプレフィックス一致へ劣化することはなく、解析に失敗します。Skill Kit リポジトリでは、scripts/test-review-currency-marker.sh がこのテンプレートを /closeout 自身の抽出処理に通して往復させ、この契約を固定しています。そのため、2 つのスキルが気付かないうちに食い違うことはありません。
  • PR ごとにスタンプは 1 つだけです。 /pre-merge を再実行すると、既存のブロックを置き換え、2 つ目を追加しません。/closeout はスタンプを単一の値として読み取るため、2 つあると「どの SHA がレビューされたのか」が曖昧になります。古い方が答えとして使われることが、より危険です。
  • スタンプが示すのはコミットの網羅状況であり、ツリー全体を 1 回確認したということではありません。 スタンプの表示行には、その意味が明記されています。その SHA 以降のコミットはレビューの観点から確認されていない、ということです。差分スコープで再実行する場合(Phase 1 の手順 4)、新しい head までのすべてのコミットについてその主張が成り立ちます。前回のレビューで古いスタンプまでのコミットを確認し、今回のレビューで残りを確認するため、同じテンプレートを使って HEAD で再スタンプします。意図的に、ブロックにはスコープを記録しません。上記の短縮禁止ガードによってブロックの幅が固定されており、次回ブランチ全体を再スタンプしたときにスコープ欄が短くなると、処理が中断されるためです。代わりに、スコープは Phase 1 でターミナルに表示します。
  • 両方を残してください。 /closeout が検索するのは HTML コメントです。表示行は、PR をざっと確認する人に、なじみのない SHA が本文にある理由を伝えます。
  • レビュアーモードではスタンプを付けず、.claude/.review-stamped にも触れません。 PR 本文の作成や書き換えは行わず(同じ理由で Phase 2 もスキップします)、その指摘事項はユーザーがまだ投稿していない草稿です。認定対象となるレビューが PR に反映されていません。誰も投稿していないコメントを根拠にローカルのチェックアウトをロックすると、レビュアーが所有していないブランチでの編集まで拒否してしまいます。
  • これらの指摘への対応で修正を行うと、head はスタンプ以降に進みます。 これは想定どおりの仕組みであり、誤報ではありません。そのコミットは実際にまだレビューされていないからです。/closeout の手順 2 では、その差分をマージ時に見えるようにします。上で書き込む .claude/.review-stamped フラグは、修正を /fix-findings(そのコードを書いていないサブエージェント)に回すか、意図的に手動削除するよう求めることで、編集時にコストが発生するようにします。フラグはローカルで一時的なものです。PR 本文のスタンプが永続的な記録として残り、このスキルだけがそれを書き込みます。
  • ループモードでも、オーサーモードと同じようにスタンプを付けます。 ループモード自体はコミットを作成しないため、その実行中に head が動くことはなく、上記のルールにループモード用の例外を設ける必要はありません。台帳を受けて担当者が行う修正によって head がスタンプ以降に進みます。これはすぐ上の箇条書きで述べたとおりで、実際に未レビューです。

Phase 4 の出力の最後に限り、今回の作業から今後の /research や /write-a-prd に役立つ永続的な教訓が得られた場合は、マージ前にこの PR に記録するよう勧めてください。 /compound は、docs/solutions/ のエントリを、まだオープンしているこの PR ブランチにコミットし、ここに戻って再実行することで、そのコミットを読み込んで再スタンプするのを既定の動作とします。これにより、その教訓は同じマージ前にレビューされ、コードと一緒にまとめてマージされます。そのため、別のマージ後セッションで記録するのではなく、/closeout の前に記録してください。ランタイムの引き継ぎ行を出力します。

**Next session:** /compound
**Input:** PR #<pr-number>  (capture the lesson onto this PR branch, before /closeout merges)

再実行された /compound 自体に引き渡してはいけません。 その実行は差分の対象範囲(Phase 1 のステップ 4)に含まれており、対象は docs/solutions/ のエントリーです。そこで記録するよう勧められる教訓は、レビュー中のコミットそのものです。それを再び推奨すると /compound に引き渡され、そこからこちらに引き渡されますが、どちらのステップにも停止するためのカウンターはありません。「永続的な教訓が生まれた場合に限り」という条件がこれを防ぎます。記録済みの教訓は、まだ記録されていない状態では生まれていないからです。判別基準はセッションの記憶ではなく差分です。スタンプ後の差分が docs/solutions/ のパスだけで構成されている場合、この推奨への対応はすでに済んでおり、終了先は /closeout です。スコープの判断で出力された差分からそれを読み取ってください。

# This block runs in its own shell — $SCOPE_FROM was assigned in Phase 1 step
# 4's fenced block and does not survive here. Unset, the range below makes git
# diff HEAD against itself and print nothing, and the guard below would
# misread that empty diff as "delta is a /compound entry" on a delta that was
# never read. Same failure BASE_REF's guard at review-checklist.md:114 exists
# to catch.
: "${SCOPE_FROM:?resolve it with the Phase 1 step 4 scope-decision block before running this}"
# Capture and test for empty rather than asking `grep -qv` for the verdict.
# Two reasons, and the second is why this shape is not optional: `grep -q` exits
# at the first match and the producer dies of SIGPIPE, which `pipefail` reports
# as "no match" from a pipeline that matched (scripts/test-pipefail-safe-matchers.sh);
# and the `grep` on PATH in a Claude Code shell is a function wrapping ugrep,
# whose `-q -v` returns 1 on input that *does* contain a non-matching line —
# the exact inversion of the verdict, in the direction that suppresses the
# recommendation on a delta carrying code. `grep -v` without `-q` is correct
# under both.
outside=$(git diff --name-only "$SCOPE_FROM...HEAD" | grep -v '^docs/solutions/' || true)
if [ -z "$outside" ]; then
  echo "delta is a /compound entry — do not re-recommend /compound; the exit is /closeout"
fi

docs/solutions/ 以外のものを含む差分は、このケースには該当しません。Phase 4 の仕組みもステージした docs: compound コミットもその一例です。件名はコミットの内容を示す証拠ではありません。これも /closeout のステップ 2 と同じ判別基準です。

<pr-number> を Phase 2 で作成した PR に置き換えてください。驚きや手戻り、または自明でない判断がなく、あらかじめ形を整えた計画をそのまま実行しただけの場合は、この行を省略してください。イシューの本文と PR の説明にすでに記録があり、再利用できる教訓のない docs/solutions/ エントリーは、将来の読者に流し読みを促すだけです。迷ったら省略してください。教訓を記録する価値がある兆候としては、根本原因が自明でない厄介なバグ、実際に問題となった PRD の Rabbit Hole、大きなトレードオフを伴うアーキテクチャ上の決定、再利用すべきパターンなどがあります。省略すべきケースの全リストについては、/compound の「When NOT to Use」を参照してください。

Phase 5:ループモード — すべての指摘に担当者を割り当てる

ループモードのみ。 作成者モードとレビュアーモードは Phase 4 で終了します。これらの指摘は、設計上、助言にとどまります。

Phase 1~4 はセンサーです。センサーが報告した内容を確認し、調査し、解決するものがなければ、報告チャネルは機能上、センサーがまったくないのと同じです(Leveson、第 12 章)。さらに Phase 4 の締めくくりの文は、「対応は不要です。これらは助言です。」です。Phase 5 は、指摘を永続化することでこのループを閉じます。すべての指摘が PR 上の台帳に記録され、その台帳は指摘を生み出したセッションが終わった後も残ります。

ループモードは何も修正しません。 レビューし、記録し、証拠を集めて、引き渡します。それぞれの指摘にどう対応するかはオペレーターが決めます。この境界は設計上のものであり、後で取り除くべき制限ではありません。詳しくは、以下の「ループが修正を行わない理由」を参照してください。

ループは人間が主導します。 ループモードは自律的なパスを実行しません。コミットを作成しないため、自ら再レビューする差分もありません。オペレーターが前回のパスの指摘に対応した後、再び /pre-merge --loop を実行するとパスが行われます。制限すべき自律サイクルがないため、パス数の上限はありません。

ステップ 1 — すべての指摘を台帳に記録する

レビューの指摘はすべて行に記録します。review-checklist.md のすべての観点について、**Runs in:** マーカーで割り当てられた分類にかかわらず記録し、トリガーが発動した場合は /ts-audit も含めます。これには、Phase 3 ではなく Phase 4 が実行するコントローラー担当の観点も含まれます。そのため、この文では件数ではなくチェックリストを明記しています。台帳の行は証明であり、以前の表現は、このスキルが項目一覧と照合していない件数を証明してしまっていました。絞り込みも、重大度によるしきい値も、「これは明らかに問題ない」という判断もありません。ループが黙って落とす指摘こそ、Leveson のルールが問題にしている、確認されない報告そのものです。Phase 4 の証拠チェックで否定され、そのため出力されなかった指摘も含めます。台帳への入力は Phase 4 ではなく、Phase 3 の出力です。

指摘は未対応の状態で届きます。open は「記録済みで、オペレーターの判断待ち」を意味し、ループモードが割り当ててもよい唯一の状態です。

ステップ 2 — 結論を出さず、証拠を添付する

所見とは、コードそのものではなく、コードについての 主張 です。この設計を検証したコーパスでは、14 件中 1 件の所見が、あるブロックは「変更を加えるステップが bash のコメントなので何も実行しない」と主張し、独立した 3 つの分類器がすべて、確信度の高い対応可能な所見と評価しました。これは誤検出でした。コメントに判断ステップを担わせる形式は、このリポジトリで確立された慣例であり、/execute のステップ 5 にある受け入れ条件の書き戻しでも同じように使われています。

そのため、ループモードでは各所見をツリーと照合して、どうすべきかではなく、何が見つかったかを記録します。

  • 所見を裏付ける、または反証する grep の結果、ファイルパス、行。
  • 所見がライブラリの意味論に左右される場合は、インストール済みの型定義(フェーズ 3 の「疑うのではなく、検証する」というルール)。
  • ツリーが主張と矛盾する場合は、refuted — <evidence> という簡潔な注記。

証拠を集めることは、判断を下すことではありません。反証された所見も、反証内容を添えて open のまま台帳に残します。削除すること自体が判断であり、それを行うのはオペレーターだからです。ここでの価値は、オペレーターが主張だけでなく、その証明と並べて主張を確認できることです。

ステップ 3 — 台帳を作成して引き継ぐ

台帳ブロック(以下)を記述してから、オペレーターに引き継ぐ内容、つまり所見の件数、反証する証拠を含む件数、およびそれらを生み出したディメンションを出力します。

/pre-merge はループモードでもスタンプの形式を変えません。ループモードではコミットを行わないため、HEAD は移動せず、フェーズ 4 の通常のスタンプルールがそのまま適用されます。

処置台帳

各呼び出しは新しいコンテキストで実行されるため、永続的な成果物がなければ、前回のパスで得られた所見を再導出することになります(Cohen:相似性の高いレビュー担当者による N 回のパスは、独立した N 回のレビューではありません)。台帳がその成果物であり、同時に、Leveson のクローズドループルールが求める、確認済み/調査済み/解決済みの記録でもあります。1 つの成果物で両方の役割を果たす、GitHub ネイティブの形式です。

台帳は ## Review Currency の慣例に従いますが、意図的に 1 点だけ異なります。PR 本文内のマーク付きブロックは、PR ごとに 1 つだけ設け、機械可読なマーカーと人が読める行を含めます。ただし、スタンプが書き込みのたびに前の値を置き換える単一の現行値を保持するのに対し、台帳は 累積 される記録です。

ブロックを書き換える際は、過去のすべてのパスの行を引き継がなければなりません。 「追記ではなく置換」はブロックに適用されるものであり、その内容には適用されません。パス 2 では、パス 1 の行とパス 2 自身の行を含む 1 つのブロックを出力します。パス 1 の行を削除する文字どおりの置換は、このセクションで Leveson を根拠として正当化している記録そのものを破壊します。しかも、残ったブロックは完全に見えるため、気づかれないまま失敗します。

## Review Disposition Ledger




Recorded by `/pre-merge` loop-mode. Every finding below has an owner. Rows marked `open` are waiting on a decision from you.

| Pass | Finding | Dimension | State | Evidence / outcome |
|---|---|---|---|---|
| 1 | Duplicate date formatter in pipeline | 1 — Deep Modules | fixed | `abc1234` — operator |
| 1 | Same pattern in `lib/export/` | 1 — Deep Modules | filed | #199 — operator |
| 1 | Stamp block "no-ops" | 7 — docs/solutions | open | refuted — `/execute` Step 5 uses the same shape ("Write verified status back to the issue") |
| 2 | Presence helper claimed as Effect Layer | 4 — Boundary Map | open | confirmed — `lib/presence.ts:12` exports a plain function |

**Checks not run this pass:** `/ts-audit` — delta is 12 changed `.ts` lines across 1 file, below the 50-line / 2-file trigger.

マーカー値に山括弧を含めないでください。 上記のフィールドには、モデル ID、短い SHA、プロンプト名などのリテラル値を入れ、<placeholder> 形式は使いません。HTML コメント内の > は、内容を読み取る単純な `` 抽出処理を終了させ、最初のプレースホルダーでマーカーを切り詰め、その後のフィールドをすべて気づかれないまま削除してしまいます。これは仮定の話ではありません。scripts/test-loop-ledger-markers.sh はこのバグのあるテンプレートを対象に作成され、初回の実行で問題を検出しました。実際の値に置き換えてください。値に > が含まれる可能性がある場合は、引用符で囲むかエンコードしてください。

Checks not run this pass の行には、このパスで実行されなかったチェックを記録します。スキップされたチェックは所見ではなく、状態も持たないため、表には含めません。ただし、行を完全に省くと、すべてのチェックが実行されたかのように台帳に表示されます。それこそ、台帳が防ぐために存在する、気づかれないままの切り詰めです。すべてのチェックを実行した場合は、この行を省略してください。 Finding セルは、ブランチを引き継いだ人が後日、予備知識のない状態で読みます。 Phase 4 の読者基準が適用される中で最も狭い枠であり、最も重要な枠でもあります。対象をドメインの用語で示し、主張を先頭に置くことで、行がそれを生み出したターミナル出力なしでも単独で意味を成すようにします。たとえば、Deep Modules issue ではなく Duplicate date formatter in pipeline とします。基準の対象外となるセルが2つあります。Evidence / outcome セルが記載するのは文章ではなく引用情報です。これを文章にして水増しすると、担当者が確認するための grep が埋もれてしまいます。また、Observation 行は Phase 4 と同様にここでも対象外です。台帳にはすべての Finding を記録するため、Observation にも行は作られますが、命名パターンについてのメモにドメインの前提情報まで記載させる必要はありません。

State 列の状態。 ループモードが書き込むのは open のみです。それ以外は担当者が書き込みます。fixed(コミットとともに)、filed(issue 番号とともに)、accepted(修正しない理由とともに)、または dropped(Finding が誤りだった理由とともに)です。/pre-merge は後のパスで担当者の状態を上書きしません。新しい Finding を追加し、確定済みの行はそのままにします。

Phase 4 のスタンプと同じ mktemp → フェッチの終了ステータスを確認 → 本文を読み取る → バイト数を記録 → ブロックを編集 → 結果が短くなった場合は書き込みを拒否 → gh pr edit --body-file という形でブロックを書き込みます。2つのガードを「同じ形」とだけ記さず、ここで明示しているのは、その形を4つの見える手順から再構成する読者が省いてしまう部分だからです。また、このスキルで最も頻繁に書き換えるブロックが台帳です。gh pr edit はコミットを作成しないため、台帳や review-notes への書き込みでは HEAD が移動せず、レビューの鮮度を保つ期間において無害な書き込みとして扱えます。「PR への書き込み」は分類せずに放置すると無効化要因と受け取られ、書き込みを未分類のままにしておくことが、正常系でゲートに初めて誤検知が生じる原因になるため、この点を明記しています。

次のパスに引き継ぐ情報と、引き継がない情報。 ここでは独立性と効率性が相反します。その折り合いを次のようにつけます。

  • 引き継ぐもの:状態と根拠 — 何が修正、起票、受容、または却下されたか、そしてそれぞれの根拠となる grep です。これらはコードの現在の状態に関する事実です。これがなければ、次のパスでは解決済みの Finding が再び報告されます。
  • 引き継がないもの:前のパスの重大度判断。 これがアンカリングの要因です。新しいレビュアーが、前のパスで軽微と評価された項目を独立に再度指摘したなら、それはシグナルです。前の評価を引き継ぐと、そのシグナルを抑えてしまいます。

これは意図的に /handoff とは異なります。このスキルは一時的な mktemp ドキュメントに要約を書き込みますが、ここではどちらの特性も適切ではありません。Leveson のルールが求める修正は「よりよく要約すること」ではなく「検証可能な主張を引き継ぐこと」であり、要約を経由するたびに、上流のコントローラーが作成した情報損失を伴う変換が発生するからです。/handoff 自身の Red Flags も、パイプラインスキルの境界でドキュメントを作成することをすでに禁じており、その境界はそのまま維持します。

審査役を固定しなければ、パス間の比較に意味がありません

委任先のレビュアーは AI の審査役です。そして審査役とはシステム、つまりモデル+プロンプト+サンプリングパラメーターであり、モデルだけではありません(Huyen、第3章)。パス1とパス3を比較して「これは前に見たものと同じ Finding か、それとも新しいものか」と問うとき、両方が同じ方法で測定されたことを暗黙に前提としています。そのためループモードでは、レビュアーのモデル、review-checklist.md のリビジョン、プロンプトの形式を、台帳の loop-judge マーカーに記録します。この3つのいずれかが変わった場合は、現在のループを継続せず、新しいループを開始します。審査役が変わった場合、パス間の比較は引き継がれません。

ループが修正を行わない理由

次の当然のステップは、ループが自身の調査結果に基づいて動作できるようにすることです。ローカルで解決できるものは修正し、それ以外はエスカレーションします。ここでは意図的にそのステップを採用していません。その理由を明示しておくことで、この境界が見落としのように受け取られないようにします。

  • 低コストな部分とリスクの高い部分は切り分けられ、根拠があるのは低コストな部分だけです。 サイクルを回すこと、つまりレビューを再実行し、/ts-audit を記憶し、呼び出しをまたいで状態を保持することに、誤った動作をするリスクはありません。一方、調査結果への対応を決めることには、そのリスクのすべてが伴います。実際の障害が前者だったのに、後者を自動化するのは、費用対効果を逆転させています。
  • 利用可能な証拠が測っているのは、一致度であって正確さではありません。 FEASIBILITY のスパイクでは、独立した3つの分類器の間で93%の全会一致が確認されました。しかし、全会一致は正確さを意味しません。同じコーパスには、3つすべてが高い確信度で対応可能と評価したものの、誤検出だった調査結果が含まれていました。自動修正が正しかったかどうかは、まだ何も測定されていません。
  • 複合的な誤りは不利に働きます。 1回あたり95%の判断を約40回行うと、すべてが正しい確率は約13%になります(Huyen)。一般的な緩和策は、誤りをエスカレーション側に偏らせることですが、実際の調査結果の大半には判断が必要です。そのため、適切に偏りを設定したループはほぼすべてをエスカレーションし、何も節約できません。
  • 取り消しにかかるコストは対称ではありません。 記録するループに対応の実行を加えるのは簡単です。しかし、何かをひそかに「修正」した後でそれを取り除くのは簡単ではありません。
  • パイプライン自体のルールでも、まず HITL で立証することになっています。 /setup-ralph-loop は、まさにこの理由から、ralph.sh のレビューフェーズをすでに延期しています。同じルールを1つ上のレベルで適用するのは、一貫性であって臆病さではありません。

後の判断を可能にするのが台帳です。実際の調査結果と実際の結果を蓄積し、自動判定ルーブリックが信頼を得る前に必要となるコーパスを作ります。これは却下せず、フォローアップとして記録されています。Skill Kit リポジトリの issue #190 には、着手前に必要な証拠が記載され、「未実装のままクローズ」も許容される結果として挙げられています。

健全性のシグナル

ループの健全性を示すシグナルは、調査結果が明らかになり、担当者が割り当てられることです。残っている調査結果の数ではありません。 各パスで明らかになった調査結果が実行を重ねるうちに減少するなら、ループはコードを改善するのではなく、報告を抑制しています(Leveson:インシデント件数の少なさではなく、報告そのものを評価します)。基準を再確認するか、レビューを通常の執筆者モードに戻してください。

もう1つ確認すべき点は、マージ時点で open のままの台帳行の割合です。すべてが open の台帳は、記録だけが作られ、無視されていることを意味します。これは手順が増えただけで、監査ループが閉じられていない状態です。

ループ安全性の網羅性

上記のルールは一覧にまとめるのではなく、それぞれが適用される場所に置かれているため、適用される時点で読み取れます。その分、全体の監査は難しくなるため、ここで導出を示します。STPA Step 1 では、不適切な制御アクションを 4 つに分類します。そのうち 3 つは、何も故障しなくても発生します。そのため、もっともらしいミスを列挙するだけでは見つからないハザードも、これらを列挙すれば検出できます。

不適切な制御アクション該当するルール
提供されない発見事項が台帳に記録されない → Step 1:すべての発見事項を行に記録し、フィルタリングも重大度による除外もしない
安全でない形で提供されるループが、本来なら差し戻すべき発見事項に対処する → ループは一切対処しない。書き込める状態は open のみで、オペレーターの状態を上書きしない
タイミングまたは順序が誤っている半端に適用された状態についてパスが報告する → ループはコミットしないため、そのような状態は存在しない。オペレーターが適用した修正は、実行中ではなく呼び出しと呼び出しの間に反映される
早すぎる段階で停止する/長く適用しすぎる未記録の発見事項が残っているのに、ループが問題なしと報告する → 健全性シグナルが示すのは、残っている 発見事項ではなく、表面化した 発見事項であり、パスごとの件数の減少は抑制として読み取られる

サーキットブレーカー:ループモード独自のものは導入しません。 コミットを行わず、自律的なパスも実行しないため、/execute の繰り返し失敗と停滞に関するルールが作動することはありません。これらのルールは、呼び出しと呼び出しの間に行われるオペレーターの修正作業に適用され、すでに機能しています。

レビューモードのコメント案

レビューモードでは、各観点の指摘を references/comment-craft.md に従って PR コメント文に変換します。ユーザーが確認して投稿できるよう、案をターミナルに明確にグループ分けして出力してください。このスキルから gh pr comment や gh api を使ってコメントを直接投稿してはいけません。ユーザーは最終的な編集者です。他者の PR へのコメントの自動投稿は取り消しが難しく、comment-craft が重視する人間による共感の確認も省略してしまいます。

各指摘について、以下のルールに従ってコメント案を作成してください。方法論の詳細は references/comment-craft.md に記載されています。ここではその適用方法を示します。

  1. 指摘ごとに 5P ゲートを実施します。 懸念に正当な根拠がなければ Pass(案から除外)します。有効ではあるものの、この PR の範囲外であれば Postpone(PR コメントではなく、「Suggested follow-up issue」の行として提示)します。Propose に分類された指摘のみ、PR コメントにします。

  2. 重要度をコメントシグナルに対応付けます。 review-checklist.md の重要度分類に基づいて、以下の接頭辞を選びます。

    • Concern → needs change:(小規模な修正)、needs rework:(大規模なリファクタリング)、または align:(規約違反)
    • Suggestion → levelup:(ブロックしない改善)
    • Observation → 対応を求めない場合は完全に除外するか、記載する価値がある場合は nitpick: として投稿します
  3. 対応が必要なコメントには Triple-R を使用します(すべてのブロッキングシグナル、およびほとんどの levelup: が対象)。Request(変換を示す動詞)、Rationale(客観的な根拠。review-checklist.md の原則、.d.ts の行、以前の PR を引用)、Result(測定可能な最終状態)を記載します。Rationale には Phase 4 の読者基準が適用されます。引用は説明の代わりにはなりません。Rationale では、破られたルールの名前を挙げるだけでなく、背景を再構成しようとしている作者に状況を理解してもらう必要があります。Request と Result は簡潔に保ちます。これらは指示であり、読者基準によって説明的な文章にすることは求められていません。

  4. トーンに配慮します。 文頭の「you」は「we」に置き換えます。命令するのではなく、依頼します。作者ではなく、成果物に焦点を当てます。

  5. 各コメントにファイルパスと行番号を示します。 コード上の位置が示されていない PR コメントは、ターミナルでの助言より対応しにくくなります。各観点の指摘で必須とされているファイル/行の引用を再利用してください(特に Surgical Scope の「賛否ではなく、引用された差分箇所を示す」というルール)。

ターミナルでの出力形式:

## Reviewer-Mode Draft Comments — PR #<pr-number>

### Per-line comments (paste at the cited code position)

#### `path/to/file.ts:42`
**`needs change:` Move helper into existing utility module**

**Rationale** — the new `formatBillDate` in `src/pipeline/format.ts:42` duplicates `lib/dates/format.ts`'s shape. `pre-merge/review-checklist.md`'s Deep Modules dimension flags this as information leakage between two modules holding the same protocol detail.

**Result** — `formatBillDate` lives in `lib/dates/format.ts` and `src/pipeline/format.ts:42` imports it.

---

[next per-line comment]

### Top-level review summary (paste as PR-level comment)

[2-3 sentence summary of the review posture, naming the dimensions that ran and the highest-severity finding. Frame as collaborative, not adversarial — Rigby's "shippable code, not a defect tally."]

### Suggested follow-up issues (5P-Postpone — do not post in this PR)

- [Title] — out of scope for this PR; file as `<repo>/issues/new` if the team wants to track it
- [Title] — same

### Held back at 5P-Pass (no comments posted)

- [One-line note per dropped concern with the reason — kept for the user's audit, not for the PR]

5P ゲートの結果、行ごとのコメント数が 0 件でも、レビュー全体への承認コメントを付けてもかまいません。その場合は、「LGTM」ではなく、「構造面では出荷できる状態です」のように、協力的な表現にしてください。Tacke は「LGTM」だけの承認をコードレビューにおける失敗パターンとして指摘しています。review-checklist.md のすべての観点を確認し、具体的な指摘がなかったのであれば、その結果にも意味があります。少なくとも、確認した観点を明記してください。

意見の相違が予想される場合(たとえば、作者が意図的に選択した方針を覆す指摘など)は、PR 上で反論のスレッドを立てるのではなく、「X のトレードオフについて、詳細なコメントを残す前に少し話し合えますか?」のように MMG Exchange をオフラインで始めるコメントを 1 件だけ作成してください。

このスキルでないもの

  • テストランナーではありません。 コミットごとに、プリコミットフックがテスト、型チェック、リンティングを実行します。
  • バグ発見ツールではありません。 /qa は動作上のバグを GitHub issue として登録します。
  • リファクタリング計画ツールではありません。 /request-refactor-plan は RFC 形式のリファクタリング提案を作成します。
  • CI のゲートではありません。 どのモードでも、指摘事項は助言にとどまります。ループモードでは指摘事項を拘束力のあるものにするのではなく、永続的に記録します。終了条件は「すべての指摘事項に担当者がいること」であり、「安全にマージできること」ではありません。また、/closeout は引き続き HITL による確認が必要です。
  • 自動修正ツールではありません。 ループモードでは指摘事項を記録して証拠を集めますが、コミットは行わず、何も決定しません。各行の処置はオペレーターが決めます。「フェーズ 5 § ループが修正を行わない理由」を参照してください。
  • 自動投稿ツールではありません。 レビュアーモードでは、ユーザーが確認して投稿するためのコメント文案を作成します。このスキル自体が gh pr comment や gh pr review を呼び出すことはありません。
  • 学習機能ではありません。 台帳には、何が見つかり、それがどう処理されたかを記録します。欠陥を見逃す原因となったプロセス上の問題を診断するのは /compound の役割であり、台帳はその入力となります。

引き継ぎ

  • 想定される入力: レビューと PR 作成の準備が整った、検証済みの実装作業(作成者モード)、レビュー対象の既存 PR 番号(レビュアーモード)、または /execute からの AFK 引き継ぎ — ブランチと、PR 本文に書き込まれた ## Review Notes(ループモード)
  • 生成するもの: 系譜情報が付与され、レビュー対象となったヘッド SHA が記録された PR — さらにローカルには、分類フックがレビュー後の修正を /fix-findings に振り分けるために読み取る一時的な .claude/.review-stamped フラグ — と、アーキテクチャレビューの所見(作成者モード);references/comment-craft.md に従った PR コメント文案(レビュアーモード);または同じ PR と、すべての指摘事項に行、担当者、およびその指摘を支持または否定する証拠が記載された ## Review Disposition Ledger(ループモード)
  • 別の手順に振り分ける場合があります: 指摘事項が動作上の問題に見える場合は /qa へ、より深い構造的な整理が必要な場合は /request-refactor-plan へ
  • 呼び出す場合があります: 変更された .ts/.tsx に対して /ts-audit を実行します — ループモードのみ。作成者モードとレビュアーモードでは、呼び出さずに言及します
  • デフォルトで次に行う手順: 将来に役立つ教訓が得られた場合は、まず /compound を実行します — このオープンな PR に記録し、その後ここに戻ってコミットを再レビューすることで、教訓の内容を説明するコードと一緒に、レビュー済みの状態でマージできます(事前に形が定まった計画をそのまま実行しただけの場合は省略します)。次に /closeout を実行します — 確認し、レビュー済みの PR をマージし、ワークツリーを削除する前にそこから作業の基準点を再設定し、マージ済みのブランチを削除し、ベースブランチをプルして、クリーンな最終状態を確認します。記録すべき教訓がない場合は、直接 /closeout に進みます。マージ中またはマージ後に明らかになった教訓も、フォールバックとしてマージ後に /compound に記録できます。レビュアーモードでは、ユーザーがコメント文案を確認して投稿します。次の手順は作者からの返答であり、/closeout ではありません。ループモードでは、台帳をオペレーターに引き渡します。open の行を解決し、それぞれを修正、登録、受け入れ、または削除してから、更新された差分に対して /pre-merge --loop を再実行するか、前述のとおり /compound、その結果を受けて再実行する /pre-merge、そして /closeout へ進みます。 次のステップのメニュー。 ここは実質的な分岐点なので、コマンドの再入力をユーザーに任せるのではなく、次のステップをメニューとして提示します(references/next-step-menu.md を参照)。AFK ループモードでの実行には適用されません。質問できるユーザーがいないため、終了時の案内と引き継ぎの文を表示してください。推奨ステップを先頭にして、選択肢ごとにスキル名だけでなく、その結果を示す単一の AskUserQuestion を提示します。author モードで、後に残すべき教訓が得られた場合は、→ /compound in this PR(推奨 — 教訓を記録)、/closeout(マージして整理 — 記録する価値のある教訓はない)、まずこのブランチで指摘事項を修正(/fix-findings <numbers> — 新しい修正担当を起動し、その後の /pre-merge 再実行でスタンプ後の差分を読み取って再スタンプ)、指摘事項をイシューとして引き継いでから、教訓を記録を提示します。教訓が得られなかった場合は、→ /closeout(推奨 — マージして整理)、まずこのブランチで指摘事項を修正(/fix-findings <numbers> — 新しい修正担当を起動し、その後の /pre-merge 再実行でスタンプ後の差分を読み取って再スタンプ)、指摘事項をイシューとして引き継いでから、マージを先頭から提示します。選択後、指摘事項は /qa または /request-refactor-plan に振り分けます。同じラベル内で2つのスキル名を挙げないでください。人間がまずこのブランチで指摘事項を修正を選んだ場合は、どの番号の指摘事項を修正するかを尋ねる追加質問を1つ行い、指定された番号を指定された順序のまま /fix-findings に渡します。番号を自分で補ってはいけません。どの指摘事項に対応するかは、このスキルではなく人間が決めることだからです。どちらのメニューにも、指摘事項への対応方法の選択肢を含めます。これは教訓の有無とは別の軸です。指摘事項を後回しにできるかどうかは、教訓が得られたかどうかとは関係なく、両方を抱えるレビュアーがその意向を示せる必要があるためです。**再実行された /compound から引き継がれた場合は、上記の差分テストでスタンプ後の差分が docs/solutions/ のパスだけだと判定されたとしても、ブランチから明らかな教訓が得られている場合でも、教訓なしのメニューを使用してください。教訓は、今回の実行でレビューしたコミットにすでに記録されているため、再度選択肢として /compound を提示せず、先頭には /closeout を置きます。**このペア内で区別するのは重大度ではなく、今対応するか、後で対応するかです。そのため、各ラベルの先頭では違いを生む対応(修正か引き継ぎか)を示し、末尾には両方に共通するステップではなく、その後に進むステップを記します。reviewer モードでは、次の動きは /closeout ではなく作者の対応なので、選択肢は異なります。ドラフトコメントを投稿、まずオフラインで話し合う(MMG Exchange)、ドラフトコメントを修正を提示します。プラットフォームの自由入力式「Other」オプションが代替手段になるため、追加しないでください。

コメント