Vivarium Contract v1
すべての Vivarium 互換再現ページが出力する再現 verdict サーフェス。 現在 リビジョン 3——ページ末尾のリビジョン履歴を参照。
概要
Vivarium Contract v1 に準拠するページは以下を公開する:
- 定数バージョン宣言:
<head>内の<meta name="vivarium-contract" content="v1">。- 出力する JSON エンベロープ(ページ内
__VIVARIUM_RESULT__グローバル、またはverdict.jsonファイル)内の"contract": "v1"。
- verdict —
"reproduced"(アップストリームバグが再現された)、"unreproduced"(再現されなかった)、"pending"(実行未完了)のいずれか。 - バグ、ランタイム、ページ固有の出力を記述する result エンベロープ。
公開方法はレイヤーによって異なる:
DOM/グローバルサーフェスは三つのレイヤー全体で同じだ。ファイルスナップショットは Layer 2 と Layer 3 にのみ存在する。
Verdict セマンティクス
reproduced はこの実行でアップストリームバグが再現されたことを意味する。ページは
アップストリームレポートが記述した失敗を実証している。再現が機能している。
unreproduced はバグが再現されないことを意味する。ランタイムがページが取り込んだ修正を
出荷したか(例: Pyodide がバンドルする pandas をバグのあるリリース以降に更新した)、
または verdict を出力する前にランタイムが別の方法でリグレッションしたかのいずれかだ。
どちらの読み方も調査する価値がある——ページはもはや README が主張することを実証していない。
pending は再現コード(Layer 1)または verdict スナップショットのフェッチ
(Layer 2 / 3)が確定するまでのデフォルト状態だ。
ページ内サーフェス(全レイヤー)
HTML meta タグ
すべての再現ページの <head> に必須。
DOM verdict 要素
id="verdict" を持つ要素は以下を持つ:
再現コードはページロードごとに要素を "pending" から "reproduced" または "unreproduced" に
一度だけ遷移させる。
JavaScript グローバル
__VIVARIUM_VERDICT__ は #verdict[data-verdict] をミラーする——両者は
src/layer1_wasm/_shared/verdict.ts
のヘルパーによって一緒に書き込まれる。
両者の間に乖離があればページが壊れているサイン。テストは両方をクロスチェックする。
__VIVARIUM_RESULT__ は構造化エンベロープ(次のセクション)。
ページが(Layer 1 の場合)verdict を生成するか、(Layer 2 / 3 の場合)フェッチしたときに設定される。
DOM evidence 要素(オプション、リビジョン 2+)
#evidence コンテナはオプションだ。リビジョン 2 以前のページはこれを省略する。
v1 コンシューマーは不在を無視する。存在する場合、再現比較 UI がサイドバイサイドパネルを
レンダリングするようなツールが使う機械可読な実行エビデンスを持つ。
ページはこれらの子要素の一部のみを出力してよい。コンシューマーは欠損した
[data-evidence="<key>"] を null / 不在として扱わなければならない(エラーではない)。
hidden 属性でデフォルトレンダリングでは非表示になる。
stdout / stderr テキストはページサイズを制限するために切り詰める場合がある。
規約では Layer 1 ヘルパーは各々を 4 KiB に制限し、既存の Layer 2 / 3
verdict.json#stderr_tail の切り詰めルールに合わせている。
Result エンベロープ (VivariumResultV1)
TypeScript で表現した型:
runtime.name は自由形式だが、ギャラリー全体で現在使用されている値は:
外部再現は新しい値を自由に追加できる。ダウンストリームツールは runtime.name を
opaque として扱う。
result は意図的に Record<string, unknown> だ——その形はページごとに異なる
(例: pandas 再現は { wrong_value, expected_value } を置くかもしれないし、
regex 再現は { matched, expected_match } を置くかもしれない)。
ページは自身の result の形を README に文書化する。コントラクトはフィールドが
存在することのみを保証する。
evidence はオプションで、リビジョン 2 で追加された。コンシューマーは
フィーチャーデテクション(if (result.evidence) …)しなければならない——
リビジョン 2 以前のページはフィールドを完全に省略する。
Verdict スナップショットファイル (verdict.json)
Layer 2 と Layer 3 では、ギャラリーページは再現をライブ実行しない——
CI(Layer 2)またはメンテナー(Layer 3)が最後の再現試行時に書いたスナップショットを
消費する。ファイルはページ読み込み時にフェッチされ、
src/layer2_docker/_layer2-shared/layer2.js
によってページ内サーフェス(__VIVARIUM_RESULT__ など)にリフトされる。
スキーマ: verdict.schema.json(JSON Schema draft 2020-12)。
フィールド概要:
スキーマは v1 の不変条件を強制する: contract === "v1" かつ verdict ∈ {"reproduced", "unreproduced"}。
Layer 1 は verdict.json を出荷しない。その verdict はページ内でライブに生成される。
ページ内 evidence サーフェスへのリフト(リビジョン 2+)
Layer 2 / Layer 3 ページは書き込み時にスナップショットの evidence フィールドを 自身の DOM に複製しない——スナップショットがソースだ。 ギャラリーローダーがページ読み込み時に DOM evidence 要素 にリフトする:
stderr_tail → evidence.stderr のリネームは、ページ内コントラクトサーフェスを
Layer 1(再現コードがキャプチャしたいテキストを直接出力し、「tail」フレームがない)と
均一に保つためのものだ。4 KiB 切り詰めルールはソースフィールドのプロパティであり、
ページ内サーフェスはソースが適用した制限を継承する。
スキーマはリビジョン 2 で変更されない——ソースフィールドは スナップショットのトップレベルにすでに存在していたものをそのまま再利用している。
ファイルに "pending" がない理由
スナップショットは記録されたプログラム / replay が完了した後に書き込まれる。
キャプチャされた "pending" スナップショットは存在しない——CI またはメンテナーが
ファイルを書き込む時点ですでに実行は完了している。"pending" 値はライターのバグを意味する。
バージョニング
バージョンは二つの場所に記載される:
<meta name="vivarium-contract" content="v1">— ページ内。verdict.json#contract— ファイルスナップショット。
両方を出荷するすべてのページで両者は一致しなければならない。
v1 を宣言するページはこの仕様に準拠しなければならない。
コントラクトは二層のポリシーで進化する:
- メジャーバンプ(v2) — 既存の v1 フィールドへの変更(リネーム、削除、型変更、 セマンティクス変更、オプション → 必須)に必要。v2 は新しい仕様ページと 新しい JSON Schema の兄弟ファイルとして出荷される。 コンシューマーはバージョンリテラルによるディスパッチで v1 と v2 を同時サポートできる。
- マイナーリビジョン(v1 内) — v1 コンシューマーが無視できるオプションの追加的
サーフェスに使用する。バージョンリテラルは
"v1"のまま(meta変更なし、verdict.json#contract変更なし)。同じ仕様ページが更新され、以下の リビジョン履歴が日付とともに追加を記録する。 コンシューマーは新しいサーフェスをフィーチャーデテクトする(例:if (result.evidence) …)。
現在 v2 は存在しない。
コンフォーマンス
再現ページが Vivarium Contract v1 に準拠するのは:
<head>に<meta name="vivarium-contract" content="v1">を含む。#verdict[data-verdict]と__VIVARIUM_VERDICT__を通じて verdict を公開する(値は一致)。VivariumResultV1型に準拠した構造化エンベロープを__VIVARIUM_RESULT__経由で公開する。verdict.jsonを出荷する場合、ファイルがverdict.schema.jsonを検証パスする。
CI はこれらの条項を機械的に強制する——現在は
src/layer1_wasm/tests/repro.spec.ts
(条項 1〜3 に対する Playwright アサーション)と
.github/workflows/repro-regression.yml
内の jq -e '.contract == "v1" and …' 述語(条項 4)による。
リビジョン履歴
<meta name="vivarium-contract"> と verdict.json#contract が持つバージョンリテラルは
"v1" だ。以下のリビジョンは v1 サーフェスの非破壊的・追加的な進化だ。
リビジョン 2 以前のページは変更なしでコンフォーマンスを維持する。
参照
src/layer1_wasm/_shared/verdict.ts— ページ内サーフェス用 TypeScript ヘルパー。src/layer1_wasm/tests/repro.spec.ts— サーフェスに対する Playwright アサーション。src/layer2_docker/_layer2-shared/layer2.js— ギャラリー側のverdict.json→ ページ内サーフェスリフト。.github/workflows/repro-regression.yml— 現在のjq -eバリデーター。.github/workflows/deploy-docs.yml— Layer 2 ビルド/実行/スナップショットワークフロー。