# Review Learn

> PRレビューで受けた指摘をCLAUDE.mdのルールとして蓄積するスキル。`/review-learn` または `/review-learn #123` で使用。レビュアーの知見をチーム全体の資産に変換し、同じ指摘を繰り返さないコードベースを実現する。

- Skill: `xtone/review-learn` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add xtone/review-learn`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xtone/review-learn/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: xtone (https://skillmd.com/u/xtone)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/xtone/review-learn

---


# Review Feedback Learner

PRレビューで受けた指摘をCLAUDE.mdのルールとして蓄積するスキル。レビュアーの知見をチーム全体の資産に変換する。

## 目的

Boris Cherny氏のTip #3「CLAUDE.mdへの投資」の拡張版:
- PRレビューで指摘されたパターンをCLAUDE.mdに自動蓄積
- 同じ指摘を繰り返し受けることを防止
- レビュアーの暗黙知をチーム全体で共有

## lessons-md-managerとの補完関係

| スキル | 学びの源泉 | タイミング |
|--------|-----------|-----------|
| `/lessons` | 自分で気づいた失敗・修正 | セッション終了時 |
| `/review-learn` | 他者からの指摘 | PRマージ後 |

両方使うと、**個人の気づき＋チームの知見**が蓄積される。

## トリガー

- `/review-learn` - 直近のマージ済みPRから学ぶ
- `/review-learn #123` - 指定PRのレビューコメントから学ぶ
- `/review-learn --my-prs` - 自分が作成したPRのレビューから学ぶ（直近5件）
- 「PRレビューから学んで」「レビュー指摘をまとめて」等の自然言語

## System Instructions

### ステップ1: 対象PRの特定

#### 引数がある場合（PR番号指定）

```bash
# PR番号からレビューコメントを取得
gh pr view {PR番号} --json number,title,author,reviewDecision,reviews,comments
```

#### 引数がない場合（直近のマージ済みPR）

```bash
# 直近にマージされた自分のPRを取得
gh pr list --author @me --state merged --limit 5 --json number,title,mergedAt
```

ユーザーに対象PRを確認する:
```
直近のマージ済みPR:
1. #123 - Fix animation flickering (2日前)
2. #120 - Add user authentication (5日前)
3. #118 - Refactor API client (1週間前)

どのPRのレビューから学びますか？（番号 or 全て）
```

### ステップ2: レビューデータの取得（GraphQL + REST ハイブリッド）

**変更理由**: `isResolved` / `isOutdated` は REST API では取得できず、GraphQL でのみ取得可能。
対応済み判定に必須のため、GraphQL をメインのデータ取得手段として使用する。

```bash
# GraphQL でレビュースレッド・コミット・レビューを一括取得
gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
  repository(owner: $owner, name: $repo) {
    pullRequest(number: $pr) {
      author { login }
      commits(last: 100) {
        nodes {
          commit {
            committedDate
            message
            additions
            deletions
          }
        }
      }
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          path
          comments(first: 10) {
            nodes {
              author { login }
              body
              createdAt
            }
          }
        }
      }
      reviews(first: 50) {
        nodes {
          author { login }
          state
          body
        }
      }
    }
  }
}
' -f owner='{owner}' -f repo='{repo}' -F pr={pr_number}
```

取得データの用途:
- `reviewThreads`: 各スレッドの `isResolved` / `isOutdated` で対応済み判定
- `commits`: コメント後の同一ファイルへのコミット有無を確認
- `reviews`: APPROVED レビューの body から具体的指摘を抽出
- `author`: PR作者の特定（返信の判別に使用）

### ステップ2.5: 対応済みフィルタリング

**目的**: 「対応した指摘のみをナレッジ化する」ためのフィルタ。
Bot の的外れな指摘や、未対応のコメントをノイズとして除外する。

#### 2a. コメント著者の分類

| 著者種別 | 判定方法 | デフォルト扱い |
|---------|---------|--------------|
| Bot | `login` が `[bot]` で終わる or GitHub API の `is_bot` | **蓄積対象外** |
| 人間 | 上記以外 | **蓄積候補** |

#### 2b. 「対応済み」判定ロジック（信頼度順）

以下の順で判定し、最初にマッチした条件を採用する:

```
対応済み判定(thread):
  1. thread.isResolved == true → 対応済み（確定）
  2. thread.isOutdated == true かつ
     thread.comments[0].createdAt 以降に同一ファイル（thread.path）へのコミットあり
     → 対応済み（高確度）
  3. PR作者からの返信に対応キーワードあり
     （"対応しました", "修正しました", "fixed", "done", "updated"）
     → 対応済み（中確度）
  4. いずれにも該当しない → 未対応
```

#### 2c. 著者種別 × 対応状況のマトリクス

| | 対応済み | 未対応 |
|---|---------|--------|
| **Bot** | 蓄積候補に昇格 | **除外**（デフォルト） |
| **人間** | **蓄積候補**（高優先） | 除外 |

- Bot でも対応した指摘は有用なため蓄積候補に含める
- 人間でも未対応（放置）の指摘は的外れだった可能性があるため除外

#### 2d. APPROVED レビュー body の特別処理

レビュー `state: APPROVED` の body に具体的な指摘（番号付きリスト等）が含まれる場合:
- APPROVED = レビュアーが対応を確認済みという強いシグナル
- body 内の各ポイントを個別の蓄積候補として扱う
- これらは「対応済み（確定）」として扱う

例: APPROVED レビューの body が以下の場合
```
LGTMです。以下の修正ありがとうございました:
1. LifecycleResumeEffectの追加
2. トリガーイベントの送信タイミング修正
```
→ 2つの個別の蓄積候補として抽出

### ステップ3: コメントの分類

レビューコメントを以下のカテゴリに分類:

| カテゴリ | 判定基準 | 例 |
|---------|---------|-----|
| 命名規則 | 変数名、関数名、クラス名への指摘 | 「fetchではなくgetを使う」 |
| アーキテクチャ | レイヤー構造、依存方向への指摘 | 「ViewModelからRepositoryを直接呼ばない」 |
| エラーハンドリング | 例外処理、Resultパターンへの指摘 | 「Resultでラップして呼び出し元で処理」 |
| テスト | テストコード、カバレッジへの指摘 | 「エッジケースのテストを追加」 |
| パフォーマンス | 効率、最適化への指摘 | 「N+1クエリに注意」 |
| セキュリティ | 脆弱性、認証への指摘 | 「入力値のサニタイズ」 |
| コードスタイル | フォーマット、可読性への指摘 | 「早期リターンを使う」 |
| ドキュメント | コメント、READMEへの指摘 | 「公開APIにはdocstringを」 |

### ステップ4: ルール化可能な指摘の抽出

以下の基準で「ルール化すべき指摘」を抽出:

**抽出対象**:
- 繰り返し適用できる一般的なパターン
- プロジェクト固有の規約・慣習
- 「〜すべき」「〜しないこと」という形式化できる指摘

**除外対象**:
- タイポの指摘（1回限り）
- 特定のバグ修正（再現性なし）
- 好みの問題（「私なら〜する」）
- 曖昧なコメント（「ここ気になる」）
- 未対応のコメント（ステップ2.5のフィルタで除外済みだが、明示的に除外）
- Bot コメントで対応していないもの
- resolve せずに放置されたスレッドで対応コミットもないもの

### ステップ5: 既存ルールとの重複チェック

1. CLAUDE.mdを読み込む
2. 既存の Lessons Learned / Review Learnings セクションを確認
3. 意味的に重複する指摘は除外
4. 既存ルールを補強・具体化する指摘は更新案として提示

### ステップ6: ルール案の生成

以下のフォーマットでルール案を生成:

```markdown
### {カテゴリ名}
- {具体的なルール}。{理由や背景}
  - 📝 PR #{PR番号} で @{レビュアー} さんが指摘
```

**記述の品質基準**:
- 肯定形で記述（「〜しないこと」より「〜を使うこと」）
- 具体的なコード例やパターンを含める
- なぜそうすべきかの理由を添える
- 元の指摘者をクレジット

**良い例**:
```markdown
### 命名規則
- Repository層のメソッドは `fetchXxx` ではなく `getXxx` を使う。fetchは非同期を暗示するが、Repositoryは同期/非同期を抽象化するため
  - 📝 PR #123 で @tanaka さんが指摘

### エラーハンドリング
- API呼び出しでは `Result<T, E>` でラップし、呼び出し元で処理する。例外を投げると呼び出し側でtry-catchが必要になり、漏れやすい
  - 📝 PR #120 で @suzuki さんが指摘
```

### ステップ7: ユーザー確認と追記

蓄積候補を対応確度別にグループ化して表示する:

```markdown
## 蓄積候補（対応済み指摘から抽出）

### 確実に対応した指摘（resolved / APPROVED body）
1. {指摘の要約} → {対応内容}
   - 📝 PR #{PR番号} で @{レビュアー} さんが指摘
   → ルール案: 「{具体的なルール文}」

### おそらく対応した指摘（outdated + コミットあり）
2. ...（該当があれば表示）

---
除外した指摘: Bot未対応 {N}件 / 人間未対応 {N}件
（詳細を見たい場合は「除外した指摘を見せて」と伝えてください）
```

1. 上記の形式で蓄積候補を提示
2. ユーザーに追記するか確認（個別に選択可能）
3. 承認されたらCLAUDE.mdに追記
4. 「除外した指摘を見せて」と言われた場合は除外理由付きで一覧表示

**追記先セクション**:
- `## Review Learnings` セクションがあればそこに追記
- なければ `## Lessons Learned` の後に作成
- どちらもなければCLAUDE.md末尾に新規作成

### ステップ8: CLAUDE.mdへの書き込み

```markdown
## Review Learnings

このセクションはPRレビューで受けた指摘から自動生成されました。
`/review-learn` コマンドで更新できます。

### 命名規則
- Repository層のメソッドは `fetchXxx` ではなく `getXxx` を使う
  - 📝 PR #123 で @tanaka さんが指摘

### エラーハンドリング
- API呼び出しでは `Result<T, E>` でラップする
  - 📝 PR #120 で @suzuki さんが指摘
```

## エラーハンドリング

**エラー1: GitHubリポジトリではない**
- gitルートを確認し、GitHub remoteがあるかチェック
- ない場合はエラーメッセージを表示

**エラー2: gh CLIが未認証**
```
GitHub CLIが認証されていません。
以下のコマンドで認証してください:
$ gh auth login
```

**エラー3: PRにレビューコメントがない**
- 「このPRにはレビューコメントがありませんでした」と表示
- 別のPRを選択するよう促す

**エラー4: 自分のPRがない**
- 「マージ済みのPRが見つかりませんでした」と表示
- PR番号を直接指定するよう促す

## 複数人リポジトリでの価値

| シナリオ | 効果 |
|----------|------|
| 新メンバー参加 | 過去のレビュー指摘が蓄積済み。同じミスをしない |
| レビュアー | 同じ指摘を繰り返す手間が減る |
| チーム全体 | 暗黙知が形式知化され、コード品質が均一に |
| オンボーディング | 「なぜこのルール？」の背景（PR番号）が追跡可能 |

## 重要事項

- CLAUDE.mdはプロジェクト全体で共有されるファイル。慎重に編集すること
- 既存の内容は変更しない（追記のみ）
- レビュアーへのクレジットを必ず残す（敬意＋追跡可能性）
- 追記・変更は必ずユーザーの承認を得てから実行する
- プラットフォーム非依存: あらゆるGitHubリポジトリで使用可能

## バージョン

### v1.1 - 対応済みフィルタリング (2026-02-16)
- Bot vs 人間のコメント自動分類
- GraphQL API で isResolved / isOutdated を取得
- 「対応した指摘のみ蓄積」フィルタ導入
- APPROVED レビュー body の解析対応
- 確度別グループ表示

### v1.0 - 初回リリース (2026-02-07)
- PRレビューコメントからルールを抽出
- カテゴリ自動分類
- 重複チェック
- レビュアークレジット付きでCLAUDE.mdに追記
- lessons-md-managerとの補完設計

