Evidrift について
Evidriftは、TypeScriptやリポジトリ内のJSON契約を記録し、CIで再検証するローカル優先のCLIとMCPサーバーです。失敗したJSONリクエストを検証付き再生で縮小する機能もあります。
主な機能
- 01TypeScript呼び出しシグネチャの記録
- 02OpenAPIまたはJSON Schema値の固定
- 03CIでの契約再検証
- 04再生による失敗JSONの縮小
- 05コンテンツアドレス付きレシートと整合性検査
活用シーン
- 01マージ前の依存API変更検出
- 02CIでのOpenAPI操作値の確認
- 03HTTP障害の最小再現例の作成
MCP 対応
ローカルのSTDIO MCPサーバーは、TypeScriptやJSON Pointerのレシートを含む契約記録ツールを公開します。再生コマンドは独立しており、MCP経由では利用できません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| claim | string | はい | この証拠が重要である理由を説明する人間による主張。 |
| symbol | string | はい | エクスポートされた呼び出し可能な TypeScript シンボル。 |
| overload | integer | いいえ | オーバーロードされたシンボルの記録時にのみ使用する、任意の 1 始まりのオーバーロード選択子。 |
| parameter | string | いいえ | 存在が必須の任意パラメーター名。 |
| packageName | string | はい | インストール済み npm 依存関係の名前。 |
| projectRoot | string | いいえ | 利用側の package.json を含む、リポジトリ相対ディレクトリ。 |
| affectedCodeLine | integer | いいえ | 任意の 1 始まりの影響を受けるソース行。 |
| affectedCodePath | string | はい | 主張の影響を受ける、リポジトリ相対のソースファイル。 |
詳細
Evidrift — 再生検証済みの JSON 縮約と API ドリフトの証拠
失敗はノイズを伴って現れます。API のドリフトは静かに進行します。Evidrift はどちらも決定論的な証拠に変えます。
Evidrift には、意図的に分離された 2 つのワークフローがあります。
- ReproMin は JSON データを繰り返し削除し、候補ごとに使い捨てのローカル HTTP ターゲットに対して再生します。そして、選択した失敗の識別情報と引き続き一致する縮約だけを保持します。
- Contract drift は、正確な TypeScript の呼び出しシグネチャまたはリポジトリの JSON 値をコンテンツアドレス付き Receipt として記録し、マージ前に CI で再計算します。
ローカルファーストの CLI。コントラクトの記録専用の STDIO MCP サーバー。アカウント、クラウドバックエンド、テレメトリー、LLM による判定はありません。

アニメーションは、記録された CLI トランスクリプトからレンダリングされています。PASS、変更されたシグネチャ、影響を受けるファイル、決定論的な FAIL は、実際のローカル evidrift demo の実行結果です。シーンの見出しだけは編集上追加されています。
クイックスタート — 失敗するリクエストを最小化する
Node.js 22 以降が必要です。セットアップ不要のデモでは、使い捨てのループバックサーバーを起動し、1 つの HTTP エラーを検証して、その JSON リクエストを最小化し、結果を再度検証してからサーバーをシャットダウンします。
npx --yes evidrift@latest repro-demo
結果は LLM によって選択されるのではありません。採用される縮約はすべて実際に再生され、期待される HTTP ステータスとエラーの識別情報の両方に一致する必要があります。
独自のローカルエンドポイントを使う場合:
npx evidrift minimize \
--request failing-request.json \
--status 500 \
--response-pointer /error/code \
--response-equals '"INVALID_FILTER"' \
--output minimal-repro.json \
--confirm-replay yes
次に、コンテンツアドレス付きの成果物を一度再生します。
npx evidrift reproduce --artifact minimal-repro.json --confirm-replay yes
ReproMin のフィクスチャ、保証、および再生時の安全境界をご覧ください。
クイックスタート — 1 つのコマンドでドリフトを確認する
Node.js 22 以降が必要です。グローバルへのインストールは不要です。
npx --yes evidrift@latest demo
このコマンドは使い捨てのローカルフィクスチャを作成し、parseConfig の省略可能な options パラメーターを記録して正常にチェックします。次に、options を必須にするようフィクスチャを変更し、evidrift check が不一致を検出することを実証します。ダウンロードしたパッケージのコードは実行しません。
マージ前に検出したい失敗なら、GitHub で Evidrift にスターを付けてください。
実例ラボ — React 19 の useRef
合成デモは高速ですが、このソースリポジトリを使ったラボでは、実際のドキュメントで説明されているエコシステムの変更に対して同じワークフローを検証します。React の公式アップグレードガイドには、React 19 では useRef の最初の引数が必須になると記載されています。Evidrift は @types/[email protected] の引数なしオーバーロードを記録し、その型パッケージのみを @types/[email protected] にアップグレードして、オーバーロードが見つからないことを報告します。
git clone https://github.com/bm1016bm-svg/evidrift.git
cd evidrift
npm ci --ignore-scripts
npm run demo:react-19
両方のパッケージバージョンは固定され、インストール後に検証されます。このラボでは依存関係のライフサイクルスクリプトを無効にしており、最後の evidrift check は再現性のあるコントラクトの不一致を返す必要があります。再現方法と完全な信頼境界およびReact 19 公式アップグレードガイドを参照してください。
現在の対応状況
| 対象 | 決定論的な証拠 | 状況 |
|---|---|---|
| ループバック HTTP の JSON エラー | ステータスとエラー識別情報が一致する再生済みの縮約 | CLI のみ |
| インストール済み TypeScript 依存関係 | 選択された呼び出しシグネチャ、パラメーター、パッケージバージョン、宣言 | 対応済み |
| リポジトリの OpenAPI / JSON Schema | RFC 6901 JSON Pointer で選択された正規値 | JSON に対応 |
| コントラクト CLI とローカル STDIO MCP | 同じレコードと再検証コア | 対応済み |
リモート再生、cURL インポート、YAML、リモート $ref | なし。Evidrift は推測せず、これらの入力を拒否します | 非対応 |
インストール — リポジトリに追加する
グローバルインストール、アカウント、API キー、クラウドバックエンドを使わずに、現在のリポジトリを初期化します。
npx --yes evidrift@latest init
ファイル名と行番号の注釈を付ける、冪等なプルリクエストのワークフローを追加するには、次のようにします。
npx --yes evidrift@latest init --github-actions
初期化ツールは npm、pnpm、Yarn を検出し、scripts.evidrift:check を追加して、.github/workflows/evidrift.yml を作成します。既存のスクリプトやワークフローは上書きされず、報告されて保持されます。
チームまたは CI ワークフロー向けに Evidrift のバージョンを固定するには、次のようにします。
npm install --save-dev evidrift
npx evidrift init
これがこの製品の目的です。AI の前提を今すぐレビュー可能にし、後から CI で同じコントラクトを確認できるようにします。
リポジトリで使う
依存関係は対象リポジトリ内にすでにインストールされている必要があり、影響を受けるコードパスには実在するファイルを指定する必要があります。
cd /path/to/your/repository
evidrift init
evidrift record \
--project . \
--package your-package \
--symbol exportedFunction \
--parameter options \
--claim "exportedFunction accepts the options used here." \
--code src/caller.ts:12
evidrift check
--code にオーバーロードされた呼び出しを含む行が指定されると、Evidrift は、その呼び出しで実際にどのオーバーロードが解決されるかを TypeScript に問い合わせます。--overload <number> は、呼び出し元のコードが不完全な場合やコンパイルできない場合に使える、明示的な代替手段です。
リポジトリ内の OpenAPI または JSON Schema ドキュメントから値を 1 つ固定するには、次のようにします。
evidrift record \
--json openapi.json \
--pointer /paths/~1users/get/operationId \
--claim "The generated client calls listUsers." \
--code src/client.ts:24
JSON Pointer は RFC 6901 に準拠しており、/ には ~1、~ には ~0 を使います。Evidrift が読み取るのは .json ファイルのみです。URL の取得やリモート参照の解決は行いません。
コーディングエージェントは、evidrift_record と evidrift_record_json_pointer を介して同じコアを呼び出します。最小限の Codex、Claude Code、Cursor の設定も用意されています。
仕組み
flowchart LR
Author["Developer"] --> Minimize["Minimize failing JSON"]
Minimize --> Replay["Replay loopback failure"]
Replay --> Repro["Content-addressed reproduction"]
Agent["Coding agent or developer"] --> Record["Record one assumption"]
Record --> Adapter["TypeScript or JSON adapter"]
Adapter --> Receipt["Content-addressed Receipt"]
Receipt --> Review["Git review"]
Review --> Check["evidrift check in CI"]
Check --> Result{"Contract still matches?"}
Result -->|Yes| Pass["PASS"]
Result -->|Source unavailable| Warn["WARNING"]
Result -->|No or tampered| Fail["FAIL"]
CLI と MCP サーバーは、同じコアを利用する薄いエントリーポイントです。コンポーネントの全体図、チェックポリシー、リソース上限、信頼境界については、アーキテクチャに記載されています。
ファイル
Evidrift は 1 つのロックファイルと、Receipt ごとに 1 つの不変な JSON ファイルを書き込みます。
.evidrift/
evidence.lock
receipts/
<64-character-sha256>.json
.evidrift/receipts.json はありません。evidence.lock には、コンテンツアドレス方式の Receipt ID のみが含まれます。
{
"receipts": ["sha256:9bfbb065cff372abe52e8e269123959e9f2ae84cd02230dc751f768ac5e4c274"],
"schemaVersion": 1
}
各 Receipt には、主張と影響を受けるコードに加えて、決定論的なコントラクトが 1 つ保存されます。コントラクトは、インストール済み TypeScript シンボルのシグネチャ、またはリポジトリ内の JSON パス、ポインター、正規値、ハッシュです。Receipt スキーマを参照してください。
CI に追加する
パッケージスクリプトと、読み取り専用のプルリクエストワークフローを生成します。
npx evidrift init --github-actions
生成されるパッケージスクリプトでは、現在の Evidrift リリースが固定されます。
{
"scripts": {
"evidrift:check": "npx --yes [email protected] check"
}
}
ローカルで同じ固定バージョンのチェックを実行するには、npm run evidrift:check を実行します。
生成されるワークフローは、ライフサイクルスクリプトを無効にしてロック済みのリポジトリ依存関係をインストールし、 その後 Marketplace Action を実行します。契約の不一致と整合性の失敗は、該当するファイルと行に プルリクエストのエラーとして表示されます。ソース変更と証拠を利用できない場合は、警告として表示されます。
evidrift check --annotations github
--format json を指定すると、GitHub ワークフローコマンドは標準エラーに書き込まれるため、標準出力は
有効な JSON のままです。生成されるワークフロー、権限、パッケージマネージャーの動作、手動セットアップについては、
GitHub Actions のセットアップに記載されています。
ルートの action.yml は、Marketplace ですぐに使える契約チェックを提供します。実行するのは
ネットワークを使用しない契約ワークフローのみです。この Action が ReproMin の再生を実行することはありません。
CI の動作
evidrift check は、保存された matched フラグや verified フラグを信頼しません。Receipt を検証し、ソースを再読み込みして、選択されたシグネチャまたは JSON 値を再計算します。
| 結果 | 意味 | 終了コード |
|---|---|---|
PASS | 決定論的なシグネチャまたは JSON 値が引き続き一致しています | 0 |
WARNING source_changed | ソースの識別情報または内容が変更されていますが、選択された契約は一致しています | 0 |
WARNING unverifiable | ソースが存在しない、無効である、または検査できません | 0 |
FAIL contract_mismatch | 選択された TypeScript シグネチャまたは JSON 値が変更されたか、存在しなくなりました | 1 |
FAIL evidence_integrity | Lock または Receipt の形式が不正、欠落、偽造されているか、ハッシュが無効です | 2 |
CI システム、コーディングエージェント、その他のツールでは、終了コードを変更せずに、バージョン付きの JSON レポートを要求できます。
npx evidrift check --format json
レポートには schemaVersion、Evidrift のバージョン、概要の件数、順序付けられた CheckResult オブジェクトが含まれます。タイムスタンプや絶対パスのリポジトリルートは含まれないため、同じ結果は同じようにシリアライズされます。JSON チェックレポートの仕様を参照してください。
Receipt を 1 行だけ手動で編集すると、対処方法を示す整合性レポートが生成されます。
FAIL evidence_integrity sha256:...
Message: Receipt content hash mismatch.
Receipt ID: sha256:...
Action: Do not trust or hand-edit this Receipt. Restore it from version control, or intentionally create a new Receipt with `evidrift record`.
プロジェクトのワークフローでは、Node.js 22 および 24 を使用して、Linux と Windows で完全なゲートを実行します。サードパーティの Action は、完全なコミット SHA で固定されています。
人間が操作する TTY では、check、diff、explain、demo はスピナーと、緑の ✅、黄色の ⚠、赤の ❌ によるステータス表示を使用します。リダイレクトされた出力、CI、TERM=dumb、NO_COLOR では ANSI を使用せず、エージェントやテストで使われる安定したプレーンテキスト形式を維持します。
RAG、Sonar、AI レビューとは異なる理由
| ツール | 役割 | Evidrift の役割 |
|---|---|---|
| RAG | 回答の作成中にコンテキストを取得する | ある前提を記録し、後から再度チェックする |
| Sonar/静的解析 | コードパターンや品質上の問題を見つける | 明示された外部依存関係の契約を再検証する |
| AI コードレビュー | 確率的な判断を行う | CI の判定に LLM を使わず、決定論的な結果を生成する |
役立つものはすべて併用してください。Evidrift が埋めるのは、コード自体が変わっていなくても、そのコードを書いた理由が古くなるという、ひとつのギャップです。
よくある質問
API ドリフトとは何ですか?
API ドリフトとは、コードが依存関係や契約に基づいて書かれた後に、それらが変更されることです。Evidrift は、決定論的な形式を 2 つチェックします。影響を受けるコード位置で選択された TypeScript の呼び出しシグネチャと、リポジトリ内の OpenAPI JSON または JSON Schema から選択された正規化値です。
Evidrift はコントラクトテストツールですか?
Evidrift の対象は、エンドツーエンドのコントラクトテストよりも限定的です。コントラクトテストではプロバイダーとコンシューマーの動作をテストしますが、Evidrift はコードに影響した明示的な前提を 1 つ固定し、依存コードを実行せずに CI でその前提を再検証します。
Evidrift は Codex、Claude Code、Cursor で動作しますか?
はい。これらはローカルの STDIO MCP サーバーを呼び出し、共通の検証コアを通じて Receipt を作成できます。エージェントが Receipt を直接検証済みにすることはできません。最小限の MCP 設定を参照してください。
Evidrift は OpenAPI URL を取得したり、パッケージコードを実行したりしますか?
コントラクトアダプターは、どちらも行いません。URL を取得したり、リモートの $ref を解決したり、依存パッケージの JavaScript をインポートしたり、任意のコマンドを実行したりすることなく、インストール済みの TypeScript 宣言とリポジトリ内の .json ファイルを検査します。
minimize と reproduce は、それぞれ独立した明示的なリプレイコマンドです。--confirm-replay yes の指定後に限り、リテラルなループバック HTTP アドレスに JSON のみを送信します。check の実行中や MCP ツール経由で実行されることはありません。
Evidrift は AI が生成したコードが正しいと証明しますか?
いいえ。決定論的な証拠のドリフトと Receipt の改ざんを検出します。ランタイムでの正しさを証明したり、自由記述の意味を検証したり、ハルシネーションをなくしたりするものではありません。Evidrift が証明しないことを参照してください。
CLI
evidrift init [--github-actions]
evidrift record --project <path> --package <name> --symbol <name> \
[--parameter <name>] [--overload <number>] --claim <text> --code <path[:line]>
evidrift record --json <path> --pointer <RFC6901> --claim <text> --code <path[:line]>
evidrift check [--format text|json] [--annotations none|github]
evidrift diff
evidrift explain <receipt-id>
evidrift demo
evidrift repro-demo
evidrift minimize --request <json> --status <code> \
(--response-contains <text> | --response-pointer <RFC6901> --response-equals <json>) \
--output <json> --confirm-replay yes
evidrift reproduce --artifact <json> --confirm-replay yes
evidrift mcp
リポジトリを対象とするコマンドでは、--root <repo> を指定できます。record には初期化済みの .evidrift/evidence.lock が必要です。repro-demo と mcp はリポジトリのルートを使用しません。
evidrift mcp は、evidrift-mcp bin で公開されているものと同じローカル STDIO サーバーを起動します。これは、パッケージレジストリと MCP クライアントがメインの npm パッケージから Evidrift を決定論的に起動できるようにするためのものです。
信頼境界
.evidrift/receipts/*.json は信頼できない入力です。各チェックでは、次の処理を行います。
- ロックと Receipt のスキーマを厳密に検証します。
- 完全な SHA-256 ID のみからファイルパスを導出します。
- 期待されるコントラクトハッシュと Receipt のコンテンツハッシュを再計算します。
- パッケージの JavaScript のインポート、シェルコマンドの実行、ネットワークリクエスト、LLM の呼び出しを行わずに、宣言またはリポジトリ内の JSON を解決します。
- 証拠の完全性、ソースのドリフト、意味的な裏付け、ランタイムでの正しさをそれぞれ個別に報告します。
パーサーは、Receipt ID が 1,024 個を超える場合、またはシンボルごとの呼び出しシグネチャが 64 個を超える場合に拒否します。TypeScript の証拠はリポジトリ内のファイルに限定され、ソースファイル数は 256 個、ファイルサイズは 1 ファイルあたり 2 MiB、合計 16 MiB を上限とします。JSON ソースの上限は 4 MiB、選択された正規化済みの値の上限は 1 MiB です。動的テキストは拒否またはエスケープされるため、Receipt によってターミナル制御文字や偽の CI 行が挿入されることはありません。
コンテンツハッシュは不整合な編集を検出しますが、作成者を証明するものではありません。Receipt を書き換え、ID を再計算し、evidence.lock を変更できる人であれば、内部的に有効な新しい証拠を作成できます。その置き換えを検出するには、Git のレビューとブランチ保護が必要です。アーキテクチャを参照してください。
リプレイでは副作用が発生する可能性があるため、ReproMin には独立した境界があります。リテラルなループバック HTTP ターゲットのみを受け付け、リダイレクトと一般的なシークレット形式の入力を拒否し、明示的なリプレイ確認を必須とし、リクエスト数とレスポンスの検査範囲を制限します。また、check や MCP サーバーから実行されることはありません。アーティファクトには Evidrift が観測した内容が記録されます。コンテンツハッシュは不整合な編集を検出しますが、プローブ履歴を認証するものではありません。reproduce は現在のリプレイを 1 件検証します。
Evidriftで証明できないこと
Evidriftは、コードが正しいことを証明するものではありません。コントラクトのワークフローでは、自由記述のクレームを証明したり、実行時の動作を実行したり、ハルシネーションを排除したり、依存関係の脆弱性をスキャンしたり、任意のURLを検証したりすることはできません。
ReproMinは、全体最小値を証明したり、根本原因を特定したりするものではありません。予算を使い切っていない場合、文書化されたJSONリデューサーと選択した失敗述語のもとで、1-最小性のみを確立します。弱い述語では依然として誤ったバグを表す可能性があるため、ステータスだけでの判定は却下されます。
コントラクトのワークフローは、影響を受けるpath:lineからオーバーロードされたTypeScriptの呼び出しを解決します。これは、コンシューマーコードがコンパイルでき、TypeScriptが宣言されたオーバーロードを1つ特定できる場合に限ります。無効、曖昧、または欠落している呼び出しは推測せずに拒否されます。--overloadは明示的なフォールバックです。レシートには選択された正規化済みシグネチャとハッシュが保存されるため、宣言の並べ替えによって誤ったドリフトが発生することはありません。
json.pointerアダプターは、リポジトリ内の.jsonファイルにある正規化済みの値をロックします。YAML、URL、リモートの$ref、スキーマ検証、意味的同等性には対応していません。リポジトリ内のTypeScript宣言のインポートには対応しますが、すべての名前付き型を展開して深い構造のコントラクトにするわけではありません。ソースが存在しない、または読み取れない場合は、表示されますが処理を妨げない警告が出ます。これらは意図的な制限であり、隠れた保証ではありません。
実行可能なboss-fightテストでは、複雑な複数ファイルにまたがる型エイリアスを使った実際の呼び出しから3つのオーバーロードのうち1つを解決し、宣言の並べ替え後も動作し、選択されたオーバーロードのみを変更すると決定論的に失敗します。
開発とUAT
npm run format:check
npm run lint
npm run typecheck
npm test
npm run uat
npm run check
npm run verifyはリリースゲートを実行します。テストでは一時的なフィクスチャと破棄可能なループバックサーバーを使用します。シークレット、有料API、Evidriftバックエンド、外部ネットワークへのアクセスは不要です。詳細なUATレポートでは、各受け入れケースに対応する自動テストと、残るリスクを示しています。
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。
