Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,28 @@
## コード規約
- Python: PEP 8, pytest, 型ヒント推奨
- 依存関係: pydantic == 2.13.4(最小依存)

## 検出ルールを追加・変更するときの必須手順(proof)

このリポジトリ固有の最重要ルール。**自作の合成フィクスチャだけで「動く」と判断しない。**

1. **単体テスト** — `python -m pytest tests/ -q`
- 各ルールに「**発火する例**」と「**発火しない例**」の両方を書く。片方だけではトートロジーになる
- 内部関数ではなく公開経路(`scan_file` / `check_file`)を通す。過去に「パターンは定義したが呼んでいない」配線漏れが2件あり、内部関数テストでは検出できない
2. **実コーパス計測** — 実在するリポジトリ群に対して走らせ、**誤検知率を数値で出す**
- 合成フィクスチャは「自分が想定した書き方」しか含まないので、通って当然。ミューテーションテストに合格しても、ルールが実世界で妥当かは**一切示さない**
- 実測例: 合成フィクスチャで誤検知ゼロだったルール群が、実コード 10 リポ 1,015 ファイルでは **121 件中の真の指摘が約 2 件(誤検知率 98%)** だった
- **NET-NEW(既存ゲートが見ていない指摘)を全件目視する。** 件数だけを見ない
- 出力ディレクトリの作成漏れ等で全件 0 になる事故に注意。**「0 件」は「見ていない」を疑う**
3. **既存ゲートとの重複確認** — 導入先に CodeQL / Dependabot / シークレットスキャナが既にある場合、
それらが出していない指摘が実際に出るかを先に測る。出ないなら、そのルールを足す価値はない

### 誤検知を生みやすい既知の型(新ルールを書く前に読む)
- SQL キーワードは英単語(`delete` / `update` / `insert`)としてごく普通に現れる → 「SQL 実行文脈」か「文字列が SQL 文で始まる」を必須条件に
- 危険な関数名は同名メソッドを持つ(`model.eval()` / `regex.exec()`)→ 直前が `.`/英数字/引用符なら除外
- 定数実行は注入経路ではない(`os.system("clear")`)→ 動的構築を伴う場合のみ
- 語の出現はその技術の使用を意味しない(バッジ文字列の "FastAPI")→ インスタンス化を条件に
- **モジュール横断の事実は行単位スキャナでは判定できない。** 絞り込みで解決しない種類は、ルールごと削除する(SEC007 削除の経緯を参照)

### 意図的に脆弱なコードを含むテスト
`# code-validator: ignore-file` を先頭に置く。これが無いと `--git-diff` の CI が自分のテストで落ちる。