DCP-AI 適合性キット¶
英語版の参考訳です(02/11/2026 更新)。内容が異なる場合は英語版が優先されます。識別子、コマンド、コードブロックは翻訳せずにそのまま掲載しています。
tools/conformance.js は、catalog.json で宣言されたスイートを、リポジトリにコミット済みの
フィクスチャとベクターに対して実行します。カタログはバージョン管理され(kit_version)、スイートごとに
生成すべきケース ID を正確に固定しています。キットはフィクスチャを読むだけです。チェックアウト内に鍵や
フィクスチャを生成せず、正規化、署名、プロファイル、スキーマ、ベクターも変更しません。
コマンド¶
npm run conformance # every suite (same as node tools/conformance.js)
node tools/conformance.js --list # suites, pinned case counts and inventory
node tools/conformance.js --suite v1.integrity --suite v2.hashes
node tools/conformance.js --report /tmp/conformance.json
node --test tools/conformance/conformance.test.mjs # runner self-tests (temporary copies only)
フィクスチャ、スキーマ、カタログのパスは、現在のディレクトリではなくスクリプトの位置から解決されます。
上記のコマンドはリポジトリのルートから実行してください。別のディレクトリからは、スクリプトを絶対パスで
呼び出します(node /path/to/dcp-ai/tools/conformance.js)。--root <dir> はキットをフィクスチャの別の
コピーに向けます(セルフテストは一時コピーに対してこれを使います)。
契約¶
| 終了コード | 意味 |
|---|---|
| 0 | 選択したすべてのケースが合格 |
| 1 | 少なくとも 1 件の不一致(値または判定が期待値と異なる) |
| 2 | 使用法エラー:不明な引数、不明・重複・空のスイート ID、--report と組み合わせた --list |
| 3 | インフラストラクチャエラー:フィクスチャの欠落または不正な形式、不正な形式の期待値、不明な設定 kind、カタログの欠落または不正な形式、例外、固定されたケースが生成されない、または固定されていないケースが生成された、あるいはチェックが 1 件も実行されなかった |
- ケースの欠落や余剰はエラーになります。そのため、他のベクターが残っているコレクションから 1 つを削除 しても、カバレッジが黙って減ることはありません。例外を投げたスイートは、固定されたケースをすべて生成 した後であっても失敗になります。
--reportを指定すると、実行前にincompleteのプレースホルダーが書き込まれ、最終レポートで置き換え られます。使用法エラーやカタログのエラーでもファイルは置き換えられます。これはキットが処理するエラーで、 レポートのパスに書き込める場合に限ります。Node が起動できない場合やファイルに書き込めない場合は以前の ファイルが残ることがあるため、利用側は既存のファイルを信用せず、終了コードとレポートのrun.idとstatusを確認してください。- レポートには、
kit(名前、バージョン、カタログの SHA-256)、run(uuid、タイムスタンプ、ルート、 Node のバージョン)、selection、status、totals(cases、executed、pass、fail、error)、 主張・制限・ケース(statusと、discrepancy、fixture、expectation、exception、catalogの いずれかのkind)を含む各スイート、インベントリ、全体の制限が含まれます。
スイート¶
| スイート | ケース数 | 仕様 | スキーマ / ベクター | 合格が証明するもの |
|---|---|---|---|---|
v1.schema |
7 | DCP-01、DCP-02、DCP-03、BUNDLE.md |
schemas/v1、tests/conformance/examples/*.json |
スキーマの妥当性のみ |
v1.integrity |
9 | VERIFICATION.md(V1)、DCP-03 |
citizenship_bundle.signed.json、keys/public_key.txt、golden_vectors.json#v1_bundle_verification |
1 つのフィクスチャの Ed25519 署名、バンドルハッシュ、Merkle ルート、インテントハッシュ、エントリハッシュ、prev_hash チェーンを golden 値と比較。鍵メタデータの整合性 |
v2.canonicalization |
11 | CANONICALIZATION_PROFILE.md |
golden_vectors.json#canonicalization、#v2_canonicalization、interop_vectors.json#canonicalization |
リファレンス正規化器の dcp-jcs-v1 バイト列 |
v2.hashes |
9 | DCP-AI-v2.0 §2.3、§10.3 | golden_vectors.json#hash_vectors、#dual_hash_vectors |
SHA-256 / SHA3-256 の値、デュアルハッシュ、デュアル Merkle ルート |
v2.signed_bundle |
10 | VERIFICATION.md(V2) |
lib/verify.js、メモリ内で構築したバンドル |
正当なバンドルと改ざんされたバンドルに対するリファレンス検証器の判定。検証済みは受け入れではない |
v2.secondary_sha3 |
51 | VERIFICATION.md の V2-11 とその正誤 |
secondary_sha3_vectors.json、lib/verify.js |
存在する二次の SHA3-256 フィールドに対するリファレンス検証器の判定。拒否される各ケースに対照あり。完全な二次チェーンではない |
v2.schema |
4 | DCP-AI-v2.0 | schemas/v2、*_v2.json の例 |
スキーマの妥当性のみ |
ext.dcp05_09.schema |
18 | DCP-05〜DCP-09 | schemas/v2、<record>_v2.json の例 |
スキーマの妥当性のみ |
ext.dcp05_09.wire |
28 | DCP-05、DCP-08、DCP-09、V2-WIRE-COMPATIBILITY.md |
schemas/v2、メモリ内で署名した記録、interop_vectors.json#domain_separation_all_contexts |
これらの記録の表現、スキーマの妥当性、署名を別々の層として確認。機能的な適合ではない |
admission.strict_v1 |
117 | spec/profiles/admission |
admission_vectors.json |
期待される受け入れ結果とエラーコード。action_authorized は常に false |
制限¶
- 一部のスイートに合格しても、これらのフィクスチャに対するそのチェックが認定されるだけです。DCP の完全な 実装、他の SDK、デプロイメントを認定するものではありません。スキーマのスイートはスキーマの妥当性のみを 証明します。V2 スキーマのスイートだけでは、正規化・ハッシュ・署名のスイートなしに V2 実装にはなりません。
verifiedとadmittedがアクションを認可することはありません。- アダプター(Express、FastAPI、OpenClaw、検証サーバー)はキットに含まれません。
- プロトコル上の論点(
spec/V2-WIRE-COMPATIBILITY.mdによる):DCP-09 の期限のフィールド(valid_until)と、 DCP-05、DCP-08、DCP-09 の署名コンテキストは正誤で訂正され、ext.dcp05_09.wireでテストされます。明示的で バージョン管理された設計を待っており、キットが判断しないもの:DCP-05 のvitality_reportの小数のメトリクス (dcp-jcs-v1では 0 と 1 しか表現できない)、DCP-08 §4.3 の逆ドメイン表記の権利(right_typeの enum で 拒否される)、2 人目の署名者や確認応答(DCP-05 §4.4、DCP-09 §3.3 と §6.3)。DCP-04、DCP-06、DCP-07 の例は これらの正誤の対象外です。
インベントリ¶
--list とレポートに、合計の外で表示されます。キットはこれらを実行せず、存在することは合格したテスト
ではありません。interop_vectors.json の攻撃ベクター、正規化のエッジケースとその他のカテゴリ、バンドル
とマンデートのベクターは SDK のテストスイートで実行されます。tests/nist-kat/ には既知解ベクターと
プロパティテストがあり、それぞれ独自の範囲を持ちます(その README
を参照)。これらも SDK のテストスイートで実行されます。dcp-jcs-v2 候補は実験的で、
dcp-jcs-v1 の外にあり、独自のスイート(tests/interop/candidate/)を持ちます。
外部実装¶
tools/conformance-external.js は、別のカタログ external-catalog.json(契約
dcp-ai-conformance-external/1)を、-- の後に argv として指定した実装に対して実行します。実装はどの言語で書いても
かまいません。stdin から JSON のリクエストを 1 つ読み、stdout に JSON のレスポンスを 1 つ書きます。ランナーには
Node 20 以降が必要で、組み込みモジュールだけを使います。上記のコマンド、カタログ、レポートは変わりません。
node tools/conformance-external.js --list
node tools/conformance-external.js --report /tmp/external.json -- node tools/conformance/wrappers/ts-sdk.mjs
node tools/conformance-external.js -- /path/to/python -I tools/conformance/wrappers/python_sdk.py
node tools/conformance-external.js --suite external.digest -- ./my-implementation --its-own-flag
node --test tools/conformance/external.test.mjs
DCP_EXTERNAL_PYTHON=/path/to/python DCP_EXTERNAL_REQUIRE_PYTHON=1 node --test tools/conformance/external.test.mjs
DCP_EXTERNAL_PYTHON がないと、node --test は Python のラッパーをスキップし、その旨を表示します。
DCP_EXTERNAL_REQUIRE_PYTHON=1 を指定すると、インタープリターがないことは失敗になります。最後のコマンドは
すべてのテストを実行します。
| スイート | ケース | ベクター |
|---|---|---|
external.dcp-jcs-v1.canonicalize |
30 | golden_vectors.json#canonicalization、#v2_canonicalization、interop_vectors.json#canonicalization とその 19 の edge_cases(うち 3 つは拒否されなければならない) |
external.digest |
8 | golden_vectors.json#hash_vectors、#dual_hash_vectors の raw と intent(SHA-256 と SHA3-256) |
最小のやり取りとして、0 バイトの SHA-256 を TypeScript のラッパーに対して実行できます。
printf '%s' '{"contract":"dcp-ai-conformance-external/1","run_id":"00000000-0000-4000-8000-000000000000","nonce":"00000000000000000000000000000000","cases":[{"id":"c1","op":"digest","alg":"sha256","input_b64":""}]}' | node tools/conformance/wrappers/ts-sdk.mjs
このリクエストに対する有効なレスポンスです(ラッパーはさらに resolved_from と runtime を加えます)。
{"contract":"dcp-ai-conformance-external/1","run_id":"00000000-0000-4000-8000-000000000000","nonce":"00000000000000000000000000000000","implementation":{"name":"example","version":"0.0.1"},"results":[{"id":"c1","status":"ok","hex":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}]}
- 封筒: リクエストとレスポンスは UTF-8 の JSON です。レスポンスは stdout 上のちょうど 1 つの JSON 文書で、 プロセスは終了コード 0 で終了します。
- リクエスト:
contract、run_id、nonce、cases。各ケースはid、op(profileがdcp-jcs-v1のcanonicalize、またはalgがsha256かsha3-256のdigest)、input_b64を持ちます。ID は実行ごとに ランダムで、期待値は送りません。canonicalize の入力は JSON テキストです。input_jsonのベクターはコミットされた とおりに、inputの値はJSON.stringifyが書くとおりに送ります。 - レスポンス: 同じ
contract、run_id、nonce、implementation(name、version、任意のresolved_fromとruntime。いずれも実装の自己申告)、そしてresultsです。resultsはケースごとにちょうど 1 つのオブジェクト を持つ配列で、各オブジェクトはそのケースのidとstatusを持ちます。statusは、output_b64(正規化された バイト列)またはhexを持つok、codeがparseかprofileのrejected、messageを持つerror、 またはunsupportedです。それ以外のフィールドは受け付けません。 - エンコーディング:
input_b64とoutput_b64は、標準のアルファベット、パディングあり、改行なしの RFC 4648 base64 の正規形です。hexはちょうど 64 文字の小文字の 16 進数です。 - 判定: バイト列は完全に比較し、拒否されなければならないベクターは拒否されたときだけ合格です。
errorやunsupportedの結果、不正な形式・欠落・重複・余分な結果、古いrun_idやnonce、不正な出力、0 以外の終了 コードやシグナル、タイムアウト、4 MiB を超える stdout はエラーであり、合格にはなりません。終了コードは 契約のとおりです。 - プロセス: シェルを使わずに起動し、POSIX では独自のプロセスグループに入れます。期限は 1 つ
(
--timeout-ms、既定 30 000)で、単調時計で測ります。その後 SIGTERM、2 秒後に SIGKILL を送り、パイプが閉じる のを最大 2 秒待ちます(閉じなければcleanup_incomplete)。stderr は 64 KiB まで保持し、解釈はしません。 - カタログとフィクスチャ は事前に検証します。ID が一意であること、ポインターが存在すること、期待値がベクターと 整合していること、各コレクションのすべてのメンバーが操作とアルゴリズムごとに 1 回ずつ固定されていることです。 欠陥があれば exit 3 です。レポートには、カタログ、フィクスチャ、リクエストのハッシュと、実装が自己申告した 識別情報をランナーが観測した内容と分けて記録します。
- レポート:
--reportの値がない、オプションのように見える、または繰り返されている場合は使い方のエラー (exit 2)で、パスがあいまいなためレポートは書きません。上記のコマンドと同様に、Node が起動しない場合、レポートを 書けない場合、ランナーが強制終了された場合にも古いレポートが残ることがあります。必ず終了コードを確認し、その後で レポートのrun.idとstatusを確認してください。 - ラッパー:
wrappers/ts-sdk.mjs(@dcp-ai/sdk。--sdk <path>は任意)とwrappers/python_sdk.py(インストール済みのdcp_ai。-Iで実行)。どちらも実際の正規化関数を 1 回だけ呼び、SDK が文書化している 非整数の拒否に対してだけrejected/profileを返します。SDK には安定したエラーコードがないため、型とメッセージ で判別します。これらが変わると、正しい拒否はエラーとして表示され、合格にはなりません。CI は両方のラッパーを 実行します。 - 制限: 合格が示すのは、実行した argv が、それが使うパーサーを通してこれら 38 ケースに合格したことです。完全な
dcp-jcs-v1の実装や DCP への適合を示すものではなく、識別情報は自己申告です。サンドボックスではありません。実装は あなたの権限と環境で実行され、プロセスグループから離れた子孫(setsid)は見えず、Windows では直接の子だけを終了 させます。
Go、Rust、WASM のラッパー¶
さらに 3 つのラッパーが、同じ 38 ケースと同じ契約を、このチェックアウトの Go SDK、Rust SDK、Rust SDK の
WASM ビルドに対して実行します。build.mjs はそれらを tools/conformance/wrappers/.build/(Git の対象外)に
コンパイルします。Go 1.25 以降、Cargo、wasm32-unknown-unknown ターゲット付きの wasm-pack が必要です。
DCP のパッケージをインストールや公開することはなく、SDK のマニフェストやロックファイルも変更しません。--offline
なしでは、Cargo と wasm-pack がビルドツールや固定された依存関係をキャッシュにダウンロードすることがあります。
--offline は GOPROXY=off、Cargo の --offline、wasm-pack --mode no-install を使い、それらのキャッシュが
すでに埋まっている必要があります。
node tools/conformance/wrappers/build.mjs all
node tools/conformance/wrappers/build.mjs --offline go rust wasm
node tools/conformance-external.js -- tools/conformance/wrappers/.build/go-wrapper
node tools/conformance-external.js -- tools/conformance/wrappers/.build/rust-target/debug/dcp-ai-conformance-wrapper
node tools/conformance-external.js -- node tools/conformance/wrappers/wasm.mjs
DCP_EXTERNAL_REQUIRE_NATIVE=1 node --test tools/conformance/external-native.test.mjs
- ビルド: Go はラッパーの
go.modとgo.sumに対して-mod=readonlyでビルドします。そのバージョンは SDK 自身のものの部分集合です。Cargo は--lockedでビルドします。ネイティブのラッパーはそのCargo.lock(SDK の ロックのコピーをオフラインで解決したもので、固定されたバージョンは同じ)を、WASM の成果物は SDK のCargo.lockを使います。--offlineはローカルのキャッシュだけを使います。SDK のマニフェストやロックファイルは 変わりません。 - Go(
wrappers/go):入力は UTF-8 でなければなりません(encoding/jsonは不正なバイトを置き換えるため、 先に確認します)。その後、SDK 自身の interop テストと同じくinterface{}にjson.Unmarshalし、v2.CanonicalizeV2を 1 回だけ呼びます。rejected/profileになるのは文書化された拒否(non-integer float at、non-finite float at)だけです。ダイジェストはv2.SHA256Hex、v2.SHA3256Hex。バージョンはローカルの チェックアウトとして報告します。 - Rust(
wrappers/rust):致命的な UTF-8 デコード、serde_json::from_str、そしてdcp_ai::v2::canonicalize::canonicalize_v2を 1 回だけ呼びます。rejected/profileになるのは文書化された 拒否(パスの接頭辞の後に続くNon-integer number in V2 canonical form:、Non-finite number in V2 canonical form:)だけです。ダイジェストはsha256_hex、sha3_256_hex。バージョンはDCP_SDK_VERSIONです。 - WASM(
wrappers/wasm.mjs):wasm-packがsdks/rustからwasmフィーチャー(--target web)で コンパイルした実際の.wasmを読み込み、その SHA-256 を報告します。生の JSON テキストをwasm_canonicalize_v2に 1 回だけ渡し、呼び出し前に JavaScript でJSON.parseやJSON.stringifyは使いません。呼び出し後は、曖昧さを示すためだけに入力と出力を調べ、バイト列を計算し直すことは ありません。この エクスポートはエラーを結果の中で{"error": "…"}として返しますが、有効な入力も同じものを生成し得ます。その ため、単一キーの{"error": string}の結果は、入力自体が唯一のキーがerrorであるルートオブジェクト(値の型は問わない)であれば曖昧なerrorとし、それ以外では文書化されたメッセージの場合にだけ拒否とします。ダイジェストのエクスポートはテキストを 受け取ります。8 つのダイジェスト入力はテキストで、UTF-8 でないバイト列はerrorとなり、置き換えはしません。 - エラー: 3 つとも、型が誤っているリクエスト(たとえば数値や
nullのinput_b64、配列でないcases)は 不正で、ラッパーは 2 で終了します。文書化された拒否以外のエラーはerrorです。Rust と WASM では、文書化された数値の拒否は、 バックトラックする正規表現を使わず 1 回の線形な走査で判別します。UTF-8 で 1 MiB を超えるメッセージは拒否ではなくerrorになります(この上限はその判別にだけ適用され、構文解析のエラーには適用されません)。DCP_EXTERNAL_REQUIRE_NATIVE=1がないと、node --testはビルドされていないものをスキップし、その旨を表示します。指定すると、ツールや成果物が ないことは失敗になります。CI はチェックアウトから 3 つのラッパーをビルドし、それぞれで 38 ケースを実行するため、 そこでは 5 つのラッパーすべてが必須です。 - 制限: WASM のラッパーは、Node 上で wasm-bindgen の生のエクスポートを呼びます。
@dcp-ai/wasmパッケージの JavaScript API(DcpClientなど)やブラウザーは対象外です。SDK に安定したエラーコードがないため、拒否の判別は メッセージの文字列に依存します。また、WASM では、ルートが単一キーの{"error": …}の入力は、 エクスポートが{"error": string}の封筒を返した場合にだけ曖昧なエラーになります({"error":5}はokの ままです)。 合格が示すのは、これら 38 ケースが各ラッパーで合格することだけです。
証拠カタログ:マークルと署名の検証¶
--catalog evidence は任意で選ぶカタログ external-evidence-catalog.json
(契約 dcp-ai-conformance-external/2、241 ケース)を選択し、同じ種類の argv に対して実行します。
既定のカタログ、契約 /1 とその 38 ケースは変わりません。カタログの contract が読み込みと判定の方法を決めます。
5 つのラッパーはどちらの契約も受け付け、リクエストの契約で応答します。
使うのはコミット済みの公開フィクスチャだけで、鍵を生成することも何かに署名することもありません。
node tools/conformance-external.js --catalog evidence --list
node tools/conformance-external.js --catalog evidence --assessment verdict --report /tmp/evidence-ts.json -- node tools/conformance/wrappers/ts-sdk.mjs --sdk sdks/typescript/dist/index.js
node tools/conformance-external.js --catalog evidence --assessment verdict -- /path/to/python -I tools/conformance/wrappers/python_sdk.py
node tools/conformance-external.js --catalog evidence --assessment verdict -- tools/conformance/wrappers/.build/go-wrapper
node tools/conformance-external.js --catalog evidence --assessment verdict -- tools/conformance/wrappers/.build/rust-target/debug/dcp-ai-conformance-wrapper
node tools/conformance-external.js --catalog evidence --assessment verdict -- node tools/conformance/wrappers/wasm.mjs
DCP_EXTERNAL_PYTHON=/path/to/python DCP_EXTERNAL_REQUIRE_PYTHON=1 DCP_EXTERNAL_REQUIRE_NATIVE=1 node --test tools/conformance/external-evidence.test.mjs
| スイート | ケース数 | ベクター |
|---|---|---|
external.merkle.dual_root |
6 | tests/conformance/v2/merkle_vectors.json:葉が 1、2、3、5 枚の場合と並べ替えた葉(spec/VERIFICATION.md V2-11)。Python の標準ライブラリでオフラインに生成 |
external.signature.composite |
24 | interop_vectors.json:複合署名と古典署名のみの署名、コミット済みの攻撃、各陽性ケースの決定的な改変 |
external.v2.bundle_vectors |
131 | bundle_vectors.json:署名済みバンドル、コミット済みの 38 の変異、受理される 9 のバンドルと別途構築された拒否される 79 のバンドル、4 つのモードでの古典署名のみのルーチンバンドル |
external.v2.secondary_sha3 |
80 | secondary_sha3_vectors.json:受理されるケースと拒否されるケース、拒否される各ケースのコミット済みの対照 |
- 操作:
dual_merkle_rootはleaves(小文字の 64 桁の 16 進文字列からなる{sha256, sha3_256}の空でない配列)を受け取り、sha256とsha3_256(小文字の 64 桁の 16 進数)を持つokで応答します。composite_verifyはcontext、payload_b64(ペイロードの正規バイト列)、コミットされたままのcomposite_sig、classical_public_key_b64、pq_public_key_b64(またはnull)を受け取り、validとclassical_valid(ブール値)、pq_valid(ブール値またはnull)を持つokで応答します。verify_signed_bundle_v2はbundle_b64(署名済みバンドルの JSON)、policy(検証器のポリシーのオブジェクト)、verification_time(Zまたはオフセット付きの RFC 3339)を受け取り、verified(ブール値)とerrors(文字列の配列)を持つokで応答します。 形の正しくないリクエスト(空または大文字の葉、文字列でない葉、タイムゾーンのない時刻、未知のフィールド)では、ラッパーは 2 で終了します。 - 判定: 複合署名のケースはフィクスチャがコミットしたフィールドだけを比較します。バンドルの判定は一致しなければならず、
拒否はコミット済みの
error_containsを含まなければなりません(大文字と小文字を区別せず、連結したエラーに対して)。 エラーを伴うverified: trueはcontradictory_resultのエラーです。 コミット済みの入力はすべて解析できるため、codeがparseのrejectedは不合格です。errorとunsupportedは決して合格になりません。 - 対照: 陰性ケースは対照が合格した場合にだけ数えられ、そうでなければエラーの
control_failedになります。 基準の署名済みバンドルはその 38 の変異の対照です。同じペイロードの陽性ケースはその改変とコミット済みの攻撃の対照です。 古典署名のみのバンドルの有効なモードは、拒否するモードの対照です。拒否される二次ケースにはそれぞれコミット済みの対照があります。 79 のmust_reject_bundlesにはケースごとの対照がありません。基準と受理される 9 のバンドルが合格した場合にだけ数えられ (スイート単位の対照で、より弱い保証)、コミット済みのerror_containsで判定されます。 レポートには各ケースのsource、input_sha256、controlsが記録されます。 - PQ 署名の欠落: PQ 部分のない
pq_over_classical署名に対して、Rust のcomposite_verifyはエラーを返し、 WASM のエクスポートはインバンドのエラーSignature error: pq_over_classical binding requires PQ signatureを返します。 この 2 つのラッパーは、その正確なエラーで、かつ入力がそのバインディングとpq: nullを持つ場合にだけ、codeがmissing_pq_signatureのrejectedとして報告します。 ランナーがそれを受け入れるのは、フィクスチャがvalid: falseだけをコミットしている場所(stripping_pq_removal)で、 その陽性の対照が合格した場合だけです。有効な署名や他の陰性ケースに対する同じコードは不合格です。 TypeScript、Python、Go はそのケースにブール値で応答します。 - ペイロードの改変は正規ペイロードの最初の文字列値の最後の文字を変えるため、ペイロードは有効な正規 JSON のままであり (WASM のエクスポートはペイロードの JSON を受け取ります)、パーサーのエラーが暗号上の失敗として数えられることはありません。
- 時刻: バンドルの各ケースは
verification_timeを送ります。基準のバンドルと検証に成功すべき各バンドルの有効期間内にある 2026-10-22T00:00:00Z(一部の陰性ケースは、その時点で意図的に期限切れまたはまだ有効でない状態です)、または二次ベクターのコミット済みの時刻です。TypeScript は{ now }、Python はnow_ms、 Go はVerifySignedBundleV2At、Rust はverify_signed_bundle_v2_atを使います。 WASM のエクスポートはDate.nowを読むため、WASM ラッパーは同期呼び出しの間だけDate.nowをその時刻に置き換え、 呼び出しが例外を投げた場合も含めてfinallyで元に戻します。その旨はruntimeに記載されます。 セルフテストは、各ラッパーが基準のバンドルを 2020-01-01 では拒否し、2026-10-22 では受理し、2100-01-01 では拒否すること、 そして例外の後に元に戻ることを示します。 - WASM 経由のマークル: ラッパーはこのチェックアウトからビルドした
wasm_dual_merkle_rootを使い、これは Rust のコアに委譲します。@dcp-ai/wasm2.1.1 以前で公開されたヘルパーは、複数の葉のケースで不合格になります(CHANGELOG を参照)。 - V2-2 とコミット済みの文言:
mainの SDK 検証器は最初に V2-2 を実行するため、error_containsを持つ 146 の拒否のうち 16(署名エンコーディングのmust_reject7 行とmust_reject_bundles9 件)は、より深い検査の文言ではなくスキーマの診断を 受け取るようになりました。そのためlegacyでは、各 SDK ラッパーは 225 ケースに合格し、その 16 件を判定は正しいまま文言の 不一致として不合格にします。これは合格ではありません。verdictでは 241 ケースすべてが合格し、130 件は文言がmatched、 その 16 件はdiffersです。CI は五つの SDK ラッパーをverdictで評価します。フィクスチャ、そのerror_containsの文字列、 既定の評価は変わりません。 - セルフテスト:
external-evidence.test.mjsは 241 ケースを 5 つのラッパーで実行し、時刻の証明、不正な形のリクエスト、 そして TypeScript ラッパーの実際の応答から作った偽の実装を実行します。偽の実装は、すべてを検証する、すべてを拒否する、 矛盾した結果、誤ったエラーテキスト、順序を無視するか 16 進テキストをハッシュするマークル縮約、不合格になる基準、 正しい場所と誤った場所でのmissing_pq_signature、陰性ケースでのエラーやunsupportedを試します。 改ざんしたフィクスチャとカタログはインフラのエラー(終了コード 3)です。このカタログの既定のタイムアウトは 300 000 ms です(--timeout-ms)。 2 つのREQUIRE変数を設定すると、ラッパーがない場合はスキップではなく不合格になります。CI では 5 つすべてを実行します。ラッパーを使う各実行では両方の評価を確認します。legacyは上記の 16 行だけを 文言の不一致として不合格にし、verdictは 241 ケースすべてに合格しなければなりません。 - 制限: 合格が示すのは、実行した argv がこれら 241 ケースに合格することだけです。ポリシーは、各ケースのコミット済みの
verifier_policy_overridesを適用したdefault_verifier_policyと、古典署名のみのバンドルの 4 つのモードであり、それ以外のポリシーは試しません。composite_verifyはバインディングと鍵を与えられたプリミティブであり、 バンドルの判定は受け入れ、プリンシパルへの信頼、行為の認可のいずれでもありません。stripping_pq_with_downgradeはclassical_validとpq_validで判定され、それを拒否するのはhybrid_requiredのポリシーの役割です。 二次フィールドは存在する場合にだけ確認されるため、合格は完全な二次チェーンを示しません。WASM 経由では、時刻は置き換えたホストの時計です。error_containsの文字列は SDK の診断用の文言であり、規範ではありません。spec/VERIFICATION.mdはエラーコードを定めていません。 これら 146 ケースの合格はその文言との一致を示すだけです。同じ判定で別のメッセージを返す検証器はそれらに失敗しますが、その失敗だけでは判定の誤りを示しません。判定による評価では、これらのケースを判定だけで評価します。
判定による評価¶
spec/VERIFICATION.md が定めるのは bundle が検証に通らない条件であり、エラーの文言ではありません。--assessment verdict は、独自のメッセージを返す実装のために、このカタログを判定だけで評価します。
オプションを指定しない場合、または --assessment legacy の場合、判定、レポート、終了コードは上記のとおりで変わりません。
このオプションは /2 のカタログ(コミット済みのもの、または独自のファイル)にだけ適用されます。/1 や /3 のカタログでは legacy も含めて使用法エラーになります。それらのコードは契約の一部であるか、規範だからです。
node tools/conformance-external.js --catalog evidence --assessment verdict --list
node tools/conformance-external.js --catalog evidence --assessment verdict --report /tmp/evidence-verdict.json -- ./my-implementation
DCP_EXTERNAL_PYTHON=/path/to/python DCP_EXTERNAL_REQUIRE_PYTHON=1 DCP_EXTERNAL_REQUIRE_NATIVE=1 node --test tools/conformance/external-evidence-assessment.test.mjs
- 変わる点:
error_containsを持つ 146 件の拒否(38 件の変更、別途構築された 79 件の bundle、29 件の二次ケース)だけです。 結果がokで、形式が正しく、矛盾がなく、verified: falseを返し、同じ実行で制御が合格していれば、それぞれ合格します。メッセージは判定しません。 それ以外の規則は制御も含めて従来どおりです。同じ回答に対して、legacyで合格するケースはverdictでも合格し、146 件以外のケースはすべて同じ状態と種別になります。 - アンカーと前提: これらの各ケースは
spec/VERIFICATION.mdの手順(anchor)を示します。bundle ベクトルではspec_step(V2-1 から V2-14)、二次グループでは V2-11 とエラッタのフィールド(audit_merkle_root_secondary、prev_hash_secondary、intent_hash_secondary)です。 すべての制御は単純な肯定ケースでなければなりません。検証に通る(または有効である)ことが期待され、error_containsも独自の制御も持ちません。そのため、評価方法によって制御の結果が変わることはありません。 どちらも実行前に確認され、満たさない計画はverdictでは終了コード 3 になります(legacyでは、たとえば独自の--rootで合格することがあります)。上記の性質は、両方の評価で有効な計画にだけ成り立ちます。 - 診断: 合格した拒否の文言は、
matched(コミット済みのerror_containsを含む)、differs、no_message(errors: [])として報告されます。 それ以外の結果はnot_evaluatedで、そのreasonはrun_error、missing、duplicate、malformed_result、implementation、unsupported、rejected、contradictory_result、wrong_verdict、control_failedのいずれかです。 誤った判定は、メッセージがどうであれ合格せず、文言が状態、合計、終了コードを変えることはありません。 - レポート:
kit.contractは/2のままです。レポートにはassessment(そのschemaは wire の契約とは別のdcp-ai-conformance-assessment/1)とdiagnostic_totalsが加わります。claimとlimitsは、この評価が実際に確認する内容を示し、カタログの文章に関係なくランナーがスイートごとに定めます。その文章はcatalog_claimとcatalog_limitsにそのまま残り、確認済みの結果ではありません。 146 件の各ケースはexpect: {"verified": false}、anchor、diagnosticを示します。legacy のレポートには新しいフィールド(assessment、diagnostic_totals、catalog_claim、catalog_limits、anchor、diagnostic)はなく、claim、limits、expect(error_containsを含む)は従来どおりです。--assessmentを付けた--listはモードを示し、付けない場合の出力は変わりません。 - 終了コードと鮮度: 契約のとおりです。実行が合格したことを意味するのは状態
pass(終了コード 0)だけです。状態がfailやerrorの実行(たとえば余分な結果がある場合)の診断は部分的な情報であり、適合を意味しません。--assessmentのエラー(不明、重複、欠落した値、/1や/3のカタログ、欠けたアンカー)はすべてプレースホルダーの後に起こるため、古いレポートを新しいrun.idを持つ新しいエラーで置き換えます。レポートが残らないのは、コマンドで説明した例外だけです。 - セルフテスト:
external-evidence-assessment.test.mjsは、TypeScript ラッパーの実際の回答から作った fake を両方の評価で実行します。期待どおりのメッセージ、中立的なメッセージ、メッセージなしの正しい判定、期待どおりのメッセージを伴う誤った判定、すべてを検証またはすべてを拒否する回答、エラー、unsupported、欠落、重複、形式不正、拒否、余分な結果、制御の失敗、実行の失敗とタイムアウト、各スイートの単独選択、全モードでの上記の性質(順序を無視する Merkle、奇数ノードの旧来の昇格、正しい場所とそれ以外でのmissing_pq_signatureを含む)、アンカーと前提、古い合格の上に書かれる新しいレポート、レポートの形と--listを扱います。 さらに、5 つのラッパーで 241 ケースをverdictで実行します。CI はすべてのラッパーを必須にして実行します。 - 制限:
verdictでの合格が示すのは、実行した argv と同じポリシーでのこれらのケースの判定が正しいことです。メッセージが正確か有用かは評価しません。/2の wire の契約、カタログ、フィクスチャ、ラッパーは変わりません。
スキーマ境界の診断(明示的選択)¶
別の external-schema-catalog.json は、新しいスキーマ閉鎖コーパスの 15 ケースを契約 /2 で実行します。V2-2 の規範上の期待値を維持し、閉じたオブジェクトの未知のメンバーは、ハッシュと署名が有効でも拒否を要求します。基準データと許可された拡張が肯定対照です。署名を更新していない拡張は、別の整合性に関する否定ケースです。この診断はデフォルトの証拠カタログの 241 ケースを変更しません。
node tools/conformance-external.js --catalog tools/conformance/external-schema-catalog.json --assessment verdict --list
node tools/conformance-external.js --catalog tools/conformance/external-schema-catalog.json --assessment verdict --report /tmp/schema-diagnostic.json -- ./my-implementation
node --test tools/conformance/external-schema.test.mjs
main の SDK 検証器は V2-2 を実行し、五つの SDK ラッパーはこれら 15 ケースに合格します。不合格になる実装は失敗のままで、許容された例外にはなりません。schema-boundary.js は、参照スキーマ検証、この有限コーパスに限定した整合性検査、コーパスの時刻でのスキーマと TypeScript SDK の組み合わせを別々に報告します。組み合わせの合格は SDK 単体が V2-2 を実施する証明ではなく、時刻を注入して参照 API を実行したものでもありません。整合性ヘルパーは汎用の規範検証器ではありません。自己テストは診断、その対照、期待値を確認します。その合格は SDK の適合性を認証しません。カバレッジマップと実装者ガイドを参照してください。
スキーマ検証カタログ(V2-2、明示的選択)¶
external-schema-validation-catalog.json は、wiring_cases.json の署名済み 57 ケースに契約 /2 を使います。各ケースは ID で固定され、肯定 13 件、否定 44 件です。各否定ケースは同じ実行で基準ケースが検証に成功した場合にだけ数えられ、各ケースは spec/VERIFICATION.md の手順(V2-1 から V2-14)を示します。テキストとして保存されたケースは、そのバイト列のまま送られます。判定だけを評価します。どのケースも error_contains を持たないため、legacy と verdict の評価は同じです。既定のカタログは変わりません。
node tools/conformance-external.js --catalog tools/conformance/external-schema-validation-catalog.json --assessment verdict --list
node tools/conformance-external.js --catalog tools/conformance/external-schema-validation-catalog.json --assessment verdict --report /tmp/schema-validation.json -- ./my-implementation
node --test tools/conformance/external-schema-validation.test.mjs
セルフテストは、キットが tools/schema-ir/ のコーパス読み取りと同じ計画を作ること、カタログとコーパスの整合性(ID の欠落・余剰・重複、両方の形式で与えられたケース、肯定でない基準)、ランナーの対照を確認します。すべてを受理すると 44 の否定ケースだけが不合格になり、すべてを拒否するとどれも数えられず、一つの制約を無視する検証器はそのケースだけが不合格になり、欠落・重複・不正な形の結果はエラーになります。CI はセルフテストとカタログを五つの SDK ラッパーで実行し、すべてを必須とします。合格が示すのは、これら 57 ケースをそのポリシーと検証時刻で通ることだけで、V2 の完全な適合ではありません。
検証器ポリシーカタログ(明示的選択)¶
external-policy-catalog.json は /2 契約で固定時刻の 74 ケースを扱います。肯定対照 10、4 要求モードにわたる存在する無効な PQ 署名 24、アルゴリズムリストとアドバイザリ 14、ティアケース 26 です。既定の証拠カタログは変更しません。各否定ケースには肯定対照の成功が必要で、診断文言は評価しません。
node tools/conformance-external.js --catalog tools/conformance/external-policy-catalog.json --assessment verdict --list
node tools/conformance-external.js --catalog tools/conformance/external-policy-catalog.json --assessment verdict --report /tmp/policy-conformance.json -- ./my-implementation
node --test tools/conformance/external-policy.test.mjs
routine のハイブリッド肯定例は実効 classical_only に到達しますが、standard の肯定例はその要求を hybrid_preferred に引き上げます。記録されたティア・モードの導出は説明であり、結果フィールドの評価ではありません。ティアケースは別々に署名された既存 bundle を使い、単一変更の対ではありません。pq_only での古典アルゴリズム除外は、解釈の明確化まで期待判定なしで除外します。残る範囲はコーパスの質問とカバレッジマップを参照してください。CI はコーパスとランナーの自己テスト、および 5 SDK ラッパーを通じたカタログ検査を実行します。合格が示すのはこれらのケースだけです。
構造カタログ(オプトイン)¶
external-structural-catalog.jsonは、/2 と実効モード hybrid_preferred で時刻を固定した16ケースを実行します。陽性対照2件と構造上の陰性ケース14件です。各陰性ケースには基本対照が必要であり、時刻順序が逆のセッションには対応する陽性対照も必要です。既定のカタログは変わりません。
node tools/conformance-external.js --catalog tools/conformance/external-structural-catalog.json --assessment verdict --list
node tools/conformance-external.js --catalog tools/conformance/external-structural-catalog.json --assessment verdict --report /tmp/structural-conformance.json -- ./my-implementation
node --test tools/conformance/external-structural.test.mjs
評価対象は判定結果のみです。コーパスには署名の出所と分離の限界を記録しています。特に、小数を含むペイロードの古い証拠と、逆向きの範囲に有効なルートが存在しない点を明示しています。CIはコーパスとランナーの自己テスト、および5つのSDKラッパーを実行します。合格はこれらのケースとポリシーに限られ、V2の完全な適合性を示しません。
アドミッションのカタログ:strict-v1 のアドミッション¶
--catalog admission は 2 つ目のオプトインのカタログ external-admission-catalog.json
(契約 dcp-ai-conformance-external/3、140 ケース)を選び、同じ種類の argv に対して実行します。これは
spec/profiles/admission のアドミッションの判断を、コミット済みの
admission_vectors.json で判定します。カタログはこのファイルを
bundle_vectors.json とともに SHA-256 で固定します。契約 /1 と /2 とそのカタログは変わりません。TypeScript、
Python、Go、Rust のラッパーは SDK を通じて /3 に答えます。WASM のビルドにはアドミッションの API がないため、その
ラッパーは /3 を拒否し(exit 2)、何もそれをエミュレートしません。
node tools/conformance-external.js --catalog admission --list
node tools/conformance-external.js --catalog admission --report /tmp/admission-ts.json -- node tools/conformance/wrappers/ts-sdk.mjs --sdk sdks/typescript/dist/index.js
node tools/conformance-external.js --catalog admission -- /path/to/python -I tools/conformance/wrappers/python_sdk.py
node tools/conformance-external.js --catalog admission -- tools/conformance/wrappers/.build/go-wrapper
node tools/conformance-external.js --catalog admission -- tools/conformance/wrappers/.build/rust-target/debug/dcp-ai-conformance-wrapper
node --test tools/conformance/external-admission.test.mjs
DCP_EXTERNAL_PYTHON=/path/to/python DCP_EXTERNAL_REQUIRE_PYTHON=1 DCP_EXTERNAL_REQUIRE_NATIVE=1 node --test tools/conformance/external-admission-wrappers.test.mjs
| スイート | ケース | 出典 |
|---|---|---|
external.admission.outcomes |
65 | admission_vectors.json の結果のベクトル |
external.admission.config |
71 | その 49 の拒否される設定、最大値つきの 2 つの受け入れられるプロファイル、ベクトルが使う 14 の信頼セットと 6 つのプロファイルの読み込み |
external.admission.composed |
4 | ベクトルの入力からカタログに書いたもの:信頼セットのないプロファイル、呼び出し元の検証器のポリシーを伴うプロファイル、そしてアルファベット順ではコードの位置がずれる 2 つの組み合わせ |
- 操作:
admit_signed_bundle_v2はbundle_b64、now、profile、trust_set、verifier_policy、revocationを常に 6 つすべて受け取り、load_admission_configはkind(trust_setまたはprofile)とconfigを受け取ります。 nowは正確にYYYY-MM-DDTHH:mm:ss.sssZで、0001 年から 9999 年の実在する日付です。これはこのトランスポートの 範囲にすぎず、プロトコルのタイムスタンプは何も変えません。revocationは、プロファイルがなければnull、{"state": "unavailable"}(スナップショットなし、R1)、または{"state": "snapshot", "snapshot": {…}}(完全かどうかにかかわらず SDK が判定するオブジェクト)です。プロファイルが あるときに限って与えられます。profile、trust_set、verifier_policyはオブジェクトかnullです。信頼セットとプロファイルは運用者の設定で あり、リクエストの中で帯域外から与えられ、バンドルから取られることは決してありません。プロファイルがなければ、 リクエストは完全な検証器のポリシーを持ちます:default_verifier_policyの 14 のフィールドに、require_session_expiry: false、require_audience_binding: false、max_session_duration_seconds: 0を加えた もの。プロファイルがあるときはポリシーを持ちません。ただし、その拒否を確かめるケースは例外です。- それ以外の形のリクエストでは、ラッパーは SDK を呼ぶ前に 2 で終了します。
- 答え:
okは、正確にverified、principal_trust、profile、profile_compliance、admitted、action_authorized、recorded_decision、trust_set_version、codes(errorsのコードを出た順に、繰り返しも 含めて)、verification_verifiedを持ちます。設定ではaccepted: true、プロファイルではさらに 2 つの最大値を 持ちます。rejectedは、SDK が型付きの設定エラーを投げたときに限ってCONFIG_*のコードを持ちます。errorとunsupportedは決して合格になりません。 - 判定(この順):
- フィールドの型(
malformed_result)。 - spec/profiles/admission から導かれる規則(
contradictory_result):action_authorizedはfalse。admittedは コードが 1 つも加えられなかったときに限って成り立つ。プリンシパルへの信頼は、信頼セットがあり、バンドルが検証を 通ったときだけ評価される。 - 正確なフィールドとコードの集合。
- 生の並びの順序。§5.1 と §5.2 の段階に従い、P1、T1、R1、R2 の停止を含む(
order)。 - 繰り返し(
cardinality):複数の構成要素や対象に当てはまる P4、T2、R4、R5 だけが、そのコードを繰り返して かまいません。
拒否される設定は、その allowed_codes のどれかで合格します。それは自身のコードか、2 つの問題を持つ 3 つの信頼
セットでは当てはまる 2 つのコードのどちらかです(§2.2)。プロファイルは実効の最大値で判定されます(§4.1)。
- 対照: 否定のケースは、その対照が推移的に合格した場合にだけ数えられます。そうでなければ control_failed
というエラーです。
- 結果の否定のケースのうち 29 は、同じバンドルの肯定のケースを対照とします。
- 19 は同じバンドルに肯定のケースがなく、スイートの単位で対照されます。これはより弱い保証です。
- 設定の拒否は、有効な信頼セットかプロファイルの読み込みを対照とします。
- 組み合わせたケースは、組み合わせたベクトルを対照とします。
--suite は、選んだケースが必要とする対照も実行し、それを報告します(controls_included、
included_for_controls)。
- プロセスとエラー: /1 と /2 と同じです(run id、nonce、ランダムなケース id、プロセスグループ、制限)。
このカタログの既定のタイムアウトは 300 000 ms です。起動の失敗、0 以外の exit、シグナル、タイムアウト、古い id、
あるいは不正な形の、欠けた、重複した、余分な結果はエラーであり、拒否や「アドミッションされない」になることは
決してありません。カタログとそのフィクスチャーは読み込むときに検証されます(固定したハッシュ、正確なキーと型、
本文と整合する各期待値)。欠陥は exit 3 です。
- ラッパー: ケースごとに 1 回、SDK の組み合わせた関数または読み込み関数を、システムの時計ではなくリクエストの
now で呼びます:admitSignedBundleV2、createPrincipalTrustStore、resolveStrictV1Profile(TypeScript)、
admit_signed_bundle_v2、create_principal_trust_store、resolve_strict_v1_profile(Python)、
AdmitSignedBundleV2、NewPrincipalTrustStore、ResolveStrictV1Profile(Go)、admit_signed_bundle_v2、
PrincipalTrustStore::from_json、resolve_strict_v1_profile(Rust)。プロバイダーは Ed25519 と ML-DSA-65 です。
拒否になるのは型付きのエラーだけです:AdmissionConfigError(TypeScript、Python、Rust)、または errors.As を
通した *AdmissionConfigError(Go)。DCP_CONFORMANCE_WRAPPER_FAULT はセルフテスト専用で、答えをエラーに変える
ことしかできません。
- セルフテスト:
- external-admission.test.mjs は、カタログ自身の期待値から作った合成の答えを、SDK なしで判定します:誤った判断、
順序、カーディナリティ、設定のコード、インフラの失敗、改ざんしたカタログとフィクスチャー。
- external-admission-wrappers.test.mjs は 4 つのラッパーを SDK を通じて実行します:それぞれ 140 ケース、
リクエストの時計(1 つのケースを 3 つの時刻で)、不正な形のリクエスト、注入した失敗、読み込めない実装、WASM の
拒否、そしてバンドルから信頼を取る SDK(TypeScript を通じて)。
CI は 4 つのラッパーを必須として両方を実行します。
- 制限:
- 合格が示すこと。 実行した argv がこれら 140 ケースに合格すること、それだけです。アドミッションは決して認可では
ありません:action_authorized は常に false です。
- 射影。 答えはアドミッションの結果の射影です。内包する検証(そのエラー、警告、詳細、signer_keys、モード、
階層)は判定しません。verification_verified は実装自身が報告するものです。
- 型付きのエラー。 拒否はそのコードで判定されます。それが SDK の型付きのエラーから来たかどうかを見るのは
ラッパーであり、ランナーではありません。
- より弱い保証。 スイートの単位の 19 の対照と、ベクトルではなくカタログに書いた 4 つの組み合わせの期待値です。
- このカタログの外。 アダプター、信頼と失効の情報源、TLS、テナント、キャッシュ、一度限りの使用。コーパスは
コミット済みのベクトルとこの 4 つの組み合わせであり、あらゆる入力ではありません。
性能ベースライン¶
tools/conformance-perf.js は、このチェックアウトの 5 つの SDK の規範的な V2 検証器を、同じ入力バイト列、同じポリシー、同じ検証時刻で測定します(契約 dcp-ai-perf/1)。
小さく再現可能なローカルのベースラインであり、このハーネスのベンチマーク、セキュリティのランキング、速度の要件ではありません。CI は速度を一切確認しません。
node tools/conformance-perf.js --list
node tools/conformance-perf.js --offline --warmup 5 --samples 20 --rounds 1 --python /path/to/python --report /tmp/perf-sanity.json
node tools/conformance-perf.js --no-build --warmup 20 --samples 100 --rounds 3 --python /path/to/python --report /tmp/perf.json
DCP_PERF_PYTHON=/path/to/python DCP_EXTERNAL_REQUIRE_PYTHON=1 DCP_EXTERNAL_REQUIRE_NATIVE=1 node --test tools/conformance/perf.test.mjs
- ワークロード: コミット済みの 6 つのバンドルを読み込むだけで、決して再署名しません。
default_verifier_policy、2026-10-22T00:00:00Z で、hybrid_ok、classical_sig_invalid(RPR の Ed25519 署名)、pq_sig_invalid(バンドルの ML-DSA-65 署名)、secondary_root_ok、secondary_root_wrong、secondary_all_okです。 二次のペアは基本の成果物とエントリーを共有し、マニフェストのaudit_merkle_root_secondaryと、それを覆うバンドル署名(manifest_hash、両方の署名値、signature.hash_alg)が異なります。1 つのフィールドのコストを切り出す実験ではありません。 - 測定する内容: 呼び出しごとに、SDK ごとに 1 つのプロセスで測り、サンプルごとにプロセスを起動しません。TypeScript は
JSON.parseとawait verifySignedBundleV2(公開パッケージではなくローカルのdist)、Python は 1 つの永続的なasyncioループの中でjson.loadsとawait verify_signed_bundle_v2(チェックアウトのdcp_ai)、Go はバイト列 API が解析を含むVerifySignedBundleV2At、Rust はserde_json::from_sliceとverify_signed_bundle_v2_at(release の example)です。 WASM はデコード、wasm_verify_signed_bundle_v2、その結果のJSON.parseで、呼び出しの間Date.nowを検証時刻に置き換えます。公開境界のコストを含め、その旨を明記します。レジストリとポリシーは一度だけ用意し、結果はキャッシュしません。 - 確認: ウォームアップと計測の呼び出しはワークロード間でラウンドロビンに実行し、各呼び出しを確認します。期待する判定、肯定ケースでエラーがないこと、否定ケースでエラーがあることです。確認に失敗すると、その子プロセスは止まり、時間を含まない
check_failedを返して終了コード 0 で終わります。ランナーはその実行を失敗として報告します(ランナーの終了コード 1)。レポートには他の子プロセスの結果が残り、その場合はベースラインではありません(baseline: false)。失敗した子プロセスの時間は決して提示しません。 子プロセスは、すべてのサンプルを持つ成功か、その失敗のどちらかを返します。ランナーは契約、実行の識別、SDK とエントリーポイント、件数、各サンプルがナノ秒の正の安全な整数であることを確認します。 - 統計: すべてのサンプルを順に保持します。SDK とワークロードごとに、
n、min、中央値(nが偶数なら中央 2 値の平均)、最近接順位による p90 と p99、max、IQR です。ランキングも割り当てた割合もありません。否定ケースは最初の失敗した確認で止まることがあり、そのerrors_firstは診断にすぎません。 - 来歴: 既定では、ツールは測定対象(TypeScript の
dist、.build配下に-oで出力する Go の子プロセス、release の Rust の example と WASM、独自のフォルダーの WASM)を、上限のある 1 つのビルド期限のもとでビルドします。 その後、選択した各 SDK について、ソースツリー、マニフェストとロック、子プロセス、成果物のハッシュ(dist全体、.wasmとその JS グルー、バイナリ)、ツールのバージョン、ビルドオプションを記録し、どれかが欠けていれば何も測定しません。--no-buildは要求された SDK についてそれらすべてを再計算し、差異や欠落を拒否します。時刻、コミット、dirty フラグは参考情報です。各子プロセスは読み込んだものを報告します(TypeScript:distから解決した各 import とそのパッケージマニフェストとハッシュ、Python:チェックアウトのdcp_aiと実際に import されたモジュール)。 この記録は成果物をこのチェックアウトに結び付けますが、サプライチェーンを保証するものではありません。 - プロセスとレポート: 各子プロセスは外部キットのランナー(期限、プロセスグループ、出力の上限)のもとで実行します。レポートにはまず
incompleteのプレースホルダーが書かれ、どの経路でも置き換えられます。曖昧な--report(欠落、オプションのような値、重複)は何も書きません。 ランナーの終了コードは 0 が合格、1 が確認の失敗、2 が使用法、3 がインフラ、ビルド、来歴です。--child-argvはハーネスのテストのためだけに子プロセスを置き換え、そのレポートは決してベースラインになりません。 - セルフテスト:
perf.test.mjsは、5 つの子プロセスの必須のスモーク実行(W=1、N=2、R=1)、偽の子プロセス(欠落、重複、未知の結果、誤った件数、不正または安全でないサンプル、誤った識別、矛盾、accept-all、ウォームアップとサンプルでの失敗、不正な失敗、有効な出力の後のゼロ以外の終了、ハング)、誤った肯定の期待を与えた実際の子プロセス、古い合格の上の新しいレポート、偽造、古い、不完全な来歴、一時ツリーでの選択、SIGTERM を無視するビルド手順を実行します。 CI はすべての子プロセスを必須にしてネイティブのジョブでこれらを実行します。 - 制限: 1 台のマシンと小さなサンプルです。周波数、熱と電源の状態、バックグラウンドの負荷は制御しません(CPU と OS は記録します)。各 SDK はそれぞれの暗号ライブラリを含めてそのまま測定し、Rust のプロファイルは既定の release です。結果はローカルにとどめ、この節は数値ではなく手法を記述します。