# レビューポリシー

全レビュアーが共有する判断基準と行動原則を定義する。

## 原則

| 原則 | 基準 |
|------|------|
| 即座修正 | 軽微でも「次のタスク」にしない。今修正できる問題は今修正させる |
| 曖昧さ排除 | 「もう少し整理して」等の曖昧な指摘は禁止。ファイル・行・修正案を具体的に示す |
| ファクトチェック | 推測ではなく実コードを確認してから指摘する |
| 実践的修正案 | 理想論ではなく実装可能な対策を提示する |
| ボーイスカウト | 変更箇所と、その正しさ・契約・配線に直接関係する箇所の問題をタスクスコープ内で改善させる |

## スコープ判定

| 状況 | 判定 | 対応 |
|------|------|------|
| 今回の変更で導入された問題 | ブロッキング | REJECT |
| 今回の変更により未使用になったコード（引数、import、変数、関数） | ブロッキング | REJECT（変更起因の問題） |
| 変更箇所・関係箇所の既存問題 | ブロッキング | REJECT（ボーイスカウトルール） |
| 変更の正しさに直接影響する構造的問題 | ブロッキング | スコープ内なら REJECT |
| 変更外ファイルの問題 | 非ブロッキング | 記録のみ（参考情報） |
| 同じ変更ファイル内にあるだけで変更の正しさに直接関係しない既存問題 | 非ブロッキング | 記録のみ（参考情報） |
| タスクスコープを大きく逸脱するリファクタリング | 非ブロッキング | 提案として記載 |

## 判定基準

### REJECT（差し戻し）

以下のいずれかに該当する場合、例外なく REJECT する。

- テストがない新しい振る舞い
- バグ修正にリグレッションテストがない
- `any` 型の使用
- フォールバック値の乱用（`?? 'unknown'`）
- 説明コメント（What/How のコメント）
- 未使用コード（「念のため」のコード）
- オブジェクト/配列の直接変更
- エラーの握りつぶし（空の catch）
- Issue番号・外部制約・除去条件のない TODO/FIXME
- 本質的に同じロジックの重複（DRY違反）
- 同じことをするメソッドの増殖（構成の違いで吸収すべき）
- 特定実装の汎用層への漏洩（汎用層に特定実装のインポート・分岐がある）
- 内部実装のパブリック API エクスポート（インフラ層の関数・内部クラスが公開されている）
- リファクタリングで置き換えられた旧コード・旧エクスポートの残存
- 関連フィールドのクロスバリデーション欠如（意味的に結合した設定値の不変条件が未検証）
- 契約変更後の呼び出し元・生成元・テストデータの更新漏れ
- ログ、エラーレスポンス、テスト出力への機密情報露出

DRY違反の修正案は、単に共通化を求めるだけでは不十分とする。以下を満たさない共通化案は不適切であり、別案を検討する。

- 共通化先が既存の責務境界・依存方向と整合している
- 新規公開API・wrapper・helperの追加が、既存契約を不自然に広げていない
- 指示書や plan にない追加抽象化を要求する場合、その必要性が根拠付きで説明されている

### Warning（警告）

ブロッキングではないが改善を推奨する。

- エッジケース・境界値のテスト不足
- テストが実装の詳細に依存
- 関数/ファイルが複雑すぎる
- 命名が不明確
- Issue番号・外部制約・除去条件がある TODO/FIXME
- 理由なしの `@ts-ignore`、`eslint-disable`

### APPROVE（承認）

全ての REJECT 基準をクリアし、品質基準を満たしている場合に承認する。「条件付き承認」はしない。問題があれば差し戻す。

## ファクトチェック

指摘する前に必ず事実を確認する。

| やるべきこと | やってはいけないこと |
|-------------|-------------------|
| ファイルを開いて実コードを確認 | 「修正済みのはず」と思い込む |
| 呼び出し元・使用箇所を検索 | 記憶に基づいて指摘する |
| 型定義・スキーマを突合 | 推測でデッドコードと判断する |
| 生成ファイル（レポート等）とソースを区別 | 生成ファイルをソースコードとしてレビュー |
| ツール出力が正常に読めることを確認 | 文字化け・異常文字を含む出力に基づいて指摘する |
| 「存在しない」主張は対象行を直接読んで検証 | 検索結果だけで「コードにない」と断定する |

### ツール出力の信頼性

ツール出力が正常に読めない場合、読める方法で読み直してから判断する。

| 状況 | 対応 |
|------|------|
| 出力が文字化け・エンコーディング異常を含む | 文字化けを認識し、別の手段（ファイルを直接開く、行番号指定で該当箇所を読む）で正しい内容を取得してから判断する |
| 検索コマンドで該当コードが見つからなかった | ファイルの該当行を直接読み、存在しないことを確認してから指摘する。検索失敗＝コード不在ではない |
| 前回と同じ指摘を出す際に実コードを再確認していない | persists 判定前に必ず現在のコードを読む。前回の記憶で再指摘しない |

## 具体的な指摘の書き方

全ての指摘には以下を含める。

- **どのファイルの何行目か**
- **何が問題か**
- **どう修正すべきか**
- **抽象化や共通化を求める場合は、なぜその配置先が自然か**

```
❌ 「構造を見直してください」
❌ 「もう少し整理してください」
❌ 「リファクタリングが必要です」

✅ 「src/auth/service.ts:45 — validateUser() が3箇所で重複。
     共通関数に抽出してください」
```

## 指摘ID管理（finding_id）

同じ指摘の堂々巡りを防ぐため、指摘をIDで追跡する。

- REJECT時に挙げる各問題には `finding_id` を必須で付ける
- 同じ問題を再指摘する場合は、同じ `finding_id` を再利用する
- 再指摘時は状態を `persists` とし、未解決である根拠（ファイル/行）を必ず示す
- 新規指摘は状態 `new` とする
- 解消済みは状態 `resolved` として一覧化する
- `finding_id` のない指摘は無効（判定根拠として扱わない）
- REJECTは `new` または `persists` の問題が1件以上ある場合のみ許可する
- 前回指摘を解消済みとする場合、別の構造問題や契約悪化を新たに導入していないか確認する

## 再オープン条件（resolved → open）

解消済み指摘を再オープンする場合は、再現可能な根拠を必須とする。

- 前回 `resolved` の指摘を再オープンする場合、以下3点を必須で提示する  
  1. 再現手順（コマンド/入力）  
  2. 期待結果と実結果  
  3. 失敗箇所のファイル/行
- 上記3点が欠ける再オープンは無効（REJECT根拠に使わない）
- 再現手順が変わる場合は別問題として新規 `finding_id` を発行する

## finding_id の意味固定

同じ ID に別問題を混在させない。

- 同一 `finding_id` は同一問題にのみ使用する
- 問題の意味・根拠ファイル・再現条件が変わる場合は新規 `finding_id` を発行する
- 同一 `finding_id` の説明を後から別問題に差し替えることを禁止する

## テストファイルの扱い

テストファイルの長さや重複は、原則として保守性の警告として扱う。

- テストファイルの行数超過・重複コードは原則 `Warning`
- 以下の実害が再現できる場合のみ `REJECT` 可能  
  - テスト不安定化（フレーク）  
  - 誤検知/検知漏れ  
  - 回帰検出不能
- 「長すぎる」「重複がある」だけでは `REJECT` しない

## 変更履歴ファイルの扱い

過去時点の事実を記録するファイル/セクション (例: `CHANGELOG.md`, `RELEASE_NOTES.md`, `MIGRATION.md`) は、現行コードの仕様書ではなく履歴である。これらを評価する際は履歴としての正しさを基準とする。

| 対象 | 判定 |
|------|------|
| 過去エントリの設定キー・API名・挙動が現行コードと一致しない | REJECT 禁止 |
| 過去リリース時点では正しかった記述 | 修正要求禁止 |
| 新規追加エントリの対象リリース時点での事実誤認 | REJECT 可 |
| Markdown 形式崩れ・重複・リンク切れ・明らかな表記ミス | REJECT または Warning 可 |

### 判断基準

- 履歴は「現在どう動くか」ではなく「その時点で何が変更されたか」を記録する
- 現行コードで名称変更・仕様変更されていても、過去エントリを書き換える理由にはならない
- 過去エントリを修正対象にする場合は、対象リリース時点でも誤りだった根拠を示す
- ファイル名 (`CHANGELOG.md` 等) や慣用的な見出し (`### Changed`, `### Added`, リリース日付つき見出し) で「履歴である」と判別する
- 現行スキーマや現行設定キーとの不一致だけを根拠に履歴ファイル/セクションを REJECT してはならない

## ボーイスカウトルール

来たときよりも美しく。

### 対象

- 変更箇所、および変更の正しさ・契約・配線に直接影響する関係箇所の既存問題（未使用コード、不適切な命名、壊れた抽象化）
- 変更の正しさに直接影響する構造的な問題（責務の混在、不要な依存）

### 対象外

- 変更していないファイル（既存問題として記録のみ）
- 同じ変更ファイル内にあるだけで、変更の正しさ・契約・配線に直接影響しない既存問題
- タスクスコープを大きく逸脱するリファクタリング（提案として記載、非ブロッキング）

### 判定

| 状況 | 判定 |
|------|------|
| 変更箇所・関係箇所に明らかな問題がある | REJECT — 一緒に修正させる |
| 冗長な式（同値の短い書き方がある） | REJECT |
| 不要な分岐・条件（到達しない、または常に同じ結果） | REJECT |
| 数秒〜数分で修正可能な問題 | REJECT（「非ブロッキング」にしない） |
| 変更の結果として未使用になったコード（引数・import等） | REJECT — 変更起因であり「既存問題」ではない |
| 修正にリファクタリングが必要（スコープが大きい） | 記録のみ（技術的負債） |

既存コードの踏襲を理由にした問題の放置は認めない。既存コードが悪い場合、それに合わせるのではなく改善する。

## 判定ルール

- 変更箇所、および変更の正しさ・契約・配線に直接影響する関係箇所で検出した問題は、既存コードであってもブロッキング（REJECT対象）として扱う
- 「既存問題」「非ブロッキング」に分類してよいのは、変更と直接関係しない箇所の問題のみ
- 「コード自体は以前から存在していた」は、変更箇所・関係箇所の問題を非ブロッキングにする理由にならない
- 問題が1件でもあればREJECT。「APPROVE + 警告」「APPROVE + 提案」は禁止

## レビューの基本手順

全レビュアーが共通して踏むべき手順を定義する。各 instruction で個別に書かない。

### 差分の基準点（ベースを固定する）

レビュー対象は、タスク開始時点（ベース）からの累積差分全体とする。直前イテレーションの修正分だけを対象にしない。

- fix ↔ review のループでは、毎回ベースから差分を取り直して全体を評価する。基準点を直近の修正へ動かさない
- ベースは統合先ブランチとのマージベース、または `plan` / `order` に記録された起点とする。`Previous Response` の「変更内容」だけを差分とみなさない
- 過去イテレーションで紛れ込んだ要求外の変更（無関係なコメント削除、改名、整形、契約変更、テスト緩和）は、最新の修正レポートに現れなくても累積差分には残る。毎回これを照合する
- finding の状態追跡（new / persists / resolved）は基準点を固定した前提で行う。差分基準を狭めて「もう差分に無い」と判断しない

### 一次情報の参照

- `order.md`、`plan.md`、実コードを一次情報として参照する
- 過去ステップの判断（前段レビュー結果、計画上の決定）は補助情報として扱う
- 情報が競合する場合は、`order.md` / `plan.md` / 実コードを優先する

### 設計判断の参照

- 実装ステップが `coder-decisions.md` を出力している場合は確認し、記録された設計判断を把握する
- 記録された意図的な判断は、それだけを理由に false positive として退けない。`order.md` / `plan.md` / 実コードと照らして妥当性を評価する
- 設計判断自体に問題があれば指摘する

### 前回指摘の追跡

- Report Directory 内で、このステップが前回までに出力したレビューレポートとそのタイムスタンプ付き履歴を確認する
- 無印ファイルを最新結果、直前のタイムスタンプ付きファイル（`{レポート名}.{タイムスタンプ}`）を前回結果として扱う
- `Previous Response` がある場合は補助情報として参照してよいが、findings の状態判定はレポート履歴を優先する
- 前回レポートにある open findings を、今回のレポートへ欠落させない
- 各 finding の状態判定（`new` / `persists` / `resolved` / `reopened`）は finding_id 管理ルールに従う

### 判定の最終手順

1. 検出した問題ごとに、スコープ判定表と判定ルールに基づいてブロッキング/非ブロッキングを分類する
2. テスト・ビルド・動作確認を根拠に書く場合は、確認対象・確認内容・結果をレポート内に具体的に残す
3. ブロッキング問題（`new`、`persists`、または `reopened`）が 1 件でもあれば REJECT と判定する

## 堂々巡りの検出

同じ種類の指摘が繰り返されている場合、修正指示の繰り返しではなくアプローチ自体を見直す。

### 同じ問題が繰り返されたら

1. 同じ種類の問題が繰り返されていないか確認
2. 繰り返されている場合、細かい修正指示ではなくアプローチ自体の代替案を提示
3. REJECT する場合でも、「別のアプローチを検討すべき」という観点を含める

「もう一度修正して」と繰り返すより、立ち止まって別の道を示す。
