# crawlers.json — AIクローラー定義ファイル

PHP(`core/`)と TypeScript(`vercel-middleware/`、将来の `webflow-app/`)の**両実装から読まれる共通定義ファイル**。
JSONにはコメントが書けないため、スキーマの説明を本ファイルに置く。

## 設計原則

- 判定ロジックは「UA文字列への大文字小文字を無視した部分一致」のみ。実装言語固有の芸(正規表現の方言等)を持ち込まない
- 新クローラーの追加・変更はこのファイルの更新だけで完結させる(コード変更不要)
- `note` は「嘘をつかない計器」原則(仕様書§1.3)の適用箇所。断定できないこと・検証手段がないことを明記する

## スキーマ

```
{
  "schema_version": 1,          // スキーマ自体の版。互換性が壊れる変更時にインクリメント
  "updated_at": "YYYY-MM-DD",   // 定義データの最終更新日
  "crawlers": [ Crawler, ... ],
  "robots_txt_tokens": [ RobotsToken, ... ]
}
```

### Crawler

| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| `id` | string | ✓ | 一意なスラッグ(小文字英数とハイフン)。DBの `crawler_id` に保存される |
| `vendor` | string | ✓ | 運営企業名(表示用) |
| `ua_pattern` | string | ✓ | UA部分一致パターン(case-insensitive)。正規表現ではない |
| `category` | string | ✓ | 3値: `training`(学習用収集)/ `search_index`(AI検索のインデックス)/ `user_fetch`(ユーザーの質問起点のリアルタイム取得) |
| `verify` | object | ✓ | なりすまし検証の方法(下記) |
| `docs_url` | string | ✓ | 公式ドキュメントURL(存在しない場合は空文字列。それ自体が情報) |
| `note` | string | - | 表示用の脚注。カテゴリの断定ができない場合等に必ず付す |

### Crawler.verify

| フィールド | 型 | 説明 |
|---|---|---|
| `method` | string | `ip_list`(公表IPレンジとの照合を優先)/ `rdns`(逆引き→正引き照合)/ `none`(検証手段なし。verified昇格不可) |
| `ip_list_url` | string | `ip_list` の場合の公表IPレンジURL |
| `domains` | string[] | `rdns` の場合の正当なホスト名サフィックス。`ip_list` でも補助として併記可 |

### RobotsToken

UAとしてはアクセスログに現れず、robots.txt の User-agent 行でのみ意味を持つ制御トークン
(Google-Extended / Applebot-Extended)。ヒット記録の対象外とし、robots.txt簡易チェック機能
(許可/拒否の表示)でのみ使用する。

| フィールド | 型 | 説明 |
|---|---|---|
| `id` / `vendor` / `docs_url` / `note` | string | Crawlerと同様 |
| `token` | string | robots.txt の User-agent 行に書かれるトークン |

## 更新時の注意

- 追加・変更時は各社**公式ドキュメントを一次情報**として確認し、`updated_at` を更新する
- `ua_pattern` 同士が部分文字列関係にならないか確認する(判定は先勝ち)
- PHP側は `DefinitionRepository` がスキーマ検証を行うため、`composer test` が通ることを確認する

## crawler-ip-ranges.json — IPレンジスナップショット(PHP専用)

なりすまし検証(CIDR照合)用の同梱スナップショット。**crawlers.json とは意図的に分離**している:
TS実装(vercel-middleware)はレンジを使わずエッジバンドルを肥大させないため、また
共通定義(クローラー追加時)とレンジ(ベンダーのレンジ変更時)は更新周期が異なるため。

| フィールド | 説明 |
|---|---|
| `schema_version` | スキーマ版(現在1) |
| `snapshot_date` | スナップショット日(UTC)。ダッシュボードに明示される |
| `fetched_at` | 取得日時(ISO 8601、UTC) |
| `sources` | crawler_id → 取得元の公式URL(出自の記録) |
| `ranges` | crawler_id → CIDR文字列配列(IPv4/IPv6混在可。素のIPは/32・/128に正規化済み) |

**更新手順**: `php tools/update-ip-ranges.php` を実行(全ソース取得成功時のみ書き換わる)。
その後 `cd core && composer test` で収載整合を確認し、`bash tools/build-plugin.sh` で配布物へ反映する。
外部フェッチは開発時のこのスクリプトのみで、プラグイン実行時には一切行わない(同梱方針)。
