
# 機能マトリクス

機能マトリクスは生成されたレポートです。サポート対象の各フラグと動作について、ネイティブツールとGrephラッパーが同等の出力をするかを記録します。「Grephはこれをサポートしているか」という疑問に答える基準となります。

決定論的なフィクスチャワークスペースに対して実際のコマンドプローブを実行し、マトリクスを再生成します。生の証拠は[`FEATURE_MATRIX.json`](https://github.com/inline0/greph/blob/main/FEATURE_MATRIX.json)に、整形済みの表は[`FEATURE_MATRIX.md`](https://github.com/inline0/greph/blob/main/FEATURE_MATRIX.md)にあります。

## ステータスの凡例

| ステータス | 意味 |
|---|---|
| `Pass` | プローブが実行され、期待された動作と一致した |
| `Fail` | プローブは実行されたが、期待された動作を満たさなかった |
| `Unavailable` | この環境にプロバイダーのコマンドがなかった |

## セクション

マトリクスは6つのセクションで構成されています:

1. **rg互換性の範囲**: すべてのプローブを、上流の`rg`バイナリと`bin/rg`の両方に対して実行します。行をサポート済みとするには、両方が`Pass`必要です。
2. **sg互換性の範囲**: すべてのプローブを、上流の`sg`バイナリと`bin/sg`の両方に対して実行します。行をサポート済みとするには、両方が`Pass`必要です。
3. **sgラッパーのみの範囲**: `bin/sg`のみを対象とするプローブです（ast-grep自体にはない機能をラッパーが提供します）。
4. **ネイティブgrephの範囲**: `bin/greph`を直接実行するプローブです。比較対象となる上流ツールはありません。フィクスチャワークスペースで期待される動作を検証します。
5. **インデックス付きgrephの範囲**: `bin/greph-index`を実行するプローブです（ビルド、更新、ウォーム状態でのテキスト検索）。
6. **インデックス付きASTライブラリの範囲**: PHP API（`Greph::buildAstIndex()`、`Greph::searchAstIndexed()`、`Greph::buildAstCache()`、`Greph::searchAstCached()`）を呼び出し、ビルド、検索、更新を確認するプローブです。

## マトリクスの再生成

```bash
php bin/feature-matrix
```

`rg`と`sg`を`PATH`に配置したリポジトリのクローンから実行します。`bin/feature-matrix`はComposerパッケージに含まれません。フィクスチャワークスペースを構築し、上流のバイナリ（インストールされている場合）とGrephラッパーに対して各互換性プローブを実行し、構造化された結果を記録して、`FEATURE_MATRIX.json`と`FEATURE_MATRIX.md`の両方を書き込みます。`--stdout`を指定すると、どちらのファイルも書き込まずにMarkdownを表示します。

コミット済みのファイルは手作業で再生成され、CIでは再生成されません。CIで実行されるPHPUnitスイートには、上流ツールを利用不可としてマトリクスを生成し、レポートの構造を確認するテストが含まれています。そのため、単一のプローブが失敗してもCIは失敗しません。リリース前にマトリクスを再生成し、差分を確認してください。

## マトリクスとドキュメントの役割

CLIリファレンスと[互換性 / rg](https://greph.inline0.dev/ja/docs/compatibility/rg)および[互換性 / sg](https://greph.inline0.dev/ja/docs/compatibility/sg)のページでは、*意図する*機能範囲を説明しています。機能マトリクスには、各行の正確なプローブ引数とともに、*検証済み*の機能範囲を記録しています。

ドキュメントに記載されているのにマトリクスにない場合、ドキュメントは古くなっています。マトリクスにあるのにドキュメントにない場合は、ドキュメントへの追記が必要です。両者を一致させてください。

## 行の例

### rgの互換性（一部抜粋）

| 機能 | rg | bin/rg | 備考 |
|---|---|---|---|
| 固定文字列検索 | Pass | Pass | プローブ: `-F needle single.txt` |
| 大文字小文字を区別しない固定文字列検索 | Pass | Pass | プローブ: `-F -i needle single.txt` |
| 単語全体の検索 | Pass | Pass | プローブ: `-F -w needle words.txt` |
| Globフィルター | Pass | Pass | プローブ: `--glob *.php function .` |
| 隠しファイル | Pass | Pass | プローブ: `--hidden -F secret .` |
| 構造化JSON出力 | Pass | Pass | ripgrepのJSONイベント方式を使うプローブ: `--json -F needle single.txt` |

### sgの互換性（一部抜粋）

| 機能 | sg | bin/sg | 備考 |
|---|---|---|---|
| `run --pattern`を使ったパターン検索 | Pass | Pass | プローブ: `run --pattern array($$$ITEMS) src/App.php` |
| `run --rewrite`による書き換え | Pass | Pass | プローブ: `run --pattern array($$$ITEMS) --rewrite [$$$ITEMS] src/App.php` |
| 構造化JSONストリーム出力 | Pass | Pass | プローブ: `run --json=stream --pattern dispatch($EVENT) src/App.php` |
| 全件更新による書き換え | Pass | Pass | プローブ: `run --pattern array($$$ITEMS) --rewrite [$$$ITEMS] --update-all src/App.php` |

全表は[`FEATURE_MATRIX.md`](https://github.com/inline0/greph/blob/main/FEATURE_MATRIX.md)を参照してください。

## プローブ駆動にする理由

手作業で管理する互換性表は、実装とのずれが生じます。ラッパーの狙いは「以前`rg`または`sg`を呼び出していた場所に置き換えても、そのまま動作する」ことです。この約束を守るには、上流ツールとラッパーを実際に並べて実行し、結果を比較するしかありません。プローブランナーは、マトリクスを再生成するたびにそれを行います。
