• 日本語
  • ブランチ修正を検証する

    // GUIDE · BRANCH-FIX

    候補の修正を end-to-end でテストする。

    Vivarium はレシピ(バグ)と比較サーフェス(あなたの修正)と、修正が壊れた code path を実際に回避したときに反転する verdict を組み合わせている。本ガイドはそのループを Layer 1(ブラウザ内)と Layer 2/3(Docker)の両方で end-to-end に歩く。

    // 0 · このループの目的

    AI-slop 検証 — その修正、本当に動く?

    AI エージェント(Claude Code、Cursor、Cline、Continue、…)が アップストリームのバグに対する候補の修正を提案してきた。素直な問いは 「本当にバグを直したのか、それとも修正に見えるだけか?」。Vivarium の branch-fix ループはこれに 機械的な verdict 反転 で答える: 修正をレシピのランタイムに通し、バグがまだ trigger するか を見るだけ。

    verdict のセマンティクス。 reproduced は 「バグが trigger する(修正は回避できていない)」、 unreproduced は「バグが trigger しない(修正が壊れた code path を回避できた)」。動く修正は verdict を reproduced から unreproduced に反転させる。

    2 つのパスは同じワイヤ形(Contract v1)と同じ比較サーフェス (/repro/compare)を共有する:

    01
    Path A — Layer 1(ブラウザ内ソース置換)。

    レシピページに代替版の再現スクリプトをペーストする。レシピの WASM ランタイム(php-wasm、ruby.wasm、Pyodide)が同じタブで再走させ、verdict をキャプチャする。CI 不要、Docker 不要。

    02
    Path B — Layer 2/3(Docker イメージ再ビルド)。

    branch-fix Docker イメージを自分でビルドして push する。GitHub Actions ワークフローがそのイメージを pull して走らせ、verdict をキャプチャ、/repro/compare が描画するアーティファクトバンドルを公開する。

    Layer ディスパッチは自動 — レシピのカタログエントリが既にどの Layer かを知っているし、MCP の verify_branch_fix ツールは両方に 正しい足場を返す。

    // 1 · レシピを選ぶ

    カタログでバグを探す。

    既知のレシピから入るか、エラー文から入るかで 2 通り:

    01
    レシピが既に分かっている。

    ギャラリーを眺めて該当レシピのページに入る。slug をメモする(例: cpython-137205)。

    02
    エラー文があるのでレシピを探したい。

    /repro/match(エラーをペーストして候補をスコア順に表示)を使うか、AI エージェントから match_error を呼ぶ(同じスコアリング、同じサーフェス)。

    // 2 · PATH A — LAYER 1

    レシピページに修正をペースト、verdict をキャプチャ。

    Path A に opt-in した Layer 1 レシピは、ベースライン出力の下に 「Try a fix」 パネルを描画する。現時点でこのパネルを出荷しているレシピは無い。ランタイム側の仕組みとこのガイドは、次に opt-in するレシピのために残してある。

    01
    レシピページを開く。

    ベースラインの再現が先に走り、オリジナルの verdict(典型的には reproduced)がキャプチャされたあとパネルが描画される。

    02
    修正ソースを供給する。

    3 つのモード: (a) textarea にペースト、(b) 公開取得可能 URL(raw GitHub / Gist)を指定、(c) ディスクからファイル選択。URL 取得時の CORS エラーはペーストへフォールバック。

    03
    実行をクリック。

    レシピが既にロード済みの WASM ランタイムが置換ソースを実行する。パネルは Contract v1 形の verdict バンドルをキャプチャする: branch-fix-verdict.json + original-verdict.json。

    04
    両方の verdict をダウンロード。

    パネルは side ごとに 1 つずつダウンロードリンクを描画する。両ファイルは Contract v1 に準拠 — Layer 2/3 のワークフロー実行から /repro/compare が消費するのと同じ形。

    05
    /repro/compare にドロップ。

    /repro/compare を開いて両方の JSON ファイルをドロップゾーンにドラッグする。ページは side-by-side で evidence を描画し、divergent なフィールドをハイライトする。

    エージェント駆動のショートカット。 AI エージェントから verify_branch_fix(slug, fix_url) を呼ぶと、ツールは ?fix_url= 事前読み込み済みの compare_url を返す — その URL を開けばレシピページが自動で fix を走らせる。 verify_branch_fix(slug, fix_source) も同様 (≤4 KiB inline、長い fix は fix_url 経由)。

    // 3 · PATH B — LAYER 2 / 3

    イメージをビルド、ワークフローを実行、アーティファクトをドロップ。

    Layer 2(Docker カタログ)はブラウザ タブでは走らせられない — バグは本物の OS、本物のソケット、 本物のファイルシステムを要求する。Path B はビルドをあなた自身の インフラに移し、push したイメージに対する verdict を GitHub Actions ワークフローでキャプチャする。

    01
    branch-fix イメージをビルドして push する。

    AI の候補修正を fork に当て、レシピの Dockerfile で Docker イメージをビルドし、GitHub Actions ランナーが pull できるレジストリ(公開 ghcr.io / Docker Hub repo)に push する。image-as-input の境界は contract — Vivarium はあなたのソースをビルドしない、あなたが行う。mise run branch-fix:publish タスクが build / push / logout のサイクルをラップする(下の Callout 参照)。

    02
    比較ワークフローを trigger する。

    mise run branch-fix:verdict <slug> <your-image-ref>、または直接 gh workflow run branch-fix-verdict.yml --repo aletheia-works/vivarium -f slug=<slug> -f branch_image=<your-image-ref> を実行する。ワークフローはあなたのイメージを pull、その中で再現を走らせ、Contract v1 verdict をキャプチャ、branch-fix-verdict-<slug>-<run_id> をアーティファクトとしてアップロードする。

    03
    アーティファクト zip をダウンロード。

    ワークフロー実行ページからアーティファクト zip を取得する。branch-fix-verdict.json と(デプロイ済みスナップショットがあれば)original-verdict.json が含まれる。

    04
    zip を /repro/compare にドロップ。

    ページは zip をクライアントサイドでパースし、両 verdict を Contract v1 スキーマに照らして検証、side-by-side で evidence を描画する。

    巨大 upstream build 用 PAT-push ヘルパー。 無料 GitHub Actions ランナーには重すぎる upstream プロジェクト (Node.js、Chromium 等)をラップしたレシピは、バイナリをローカルで 先にビルドする必要がある。write:packages スコープの classic PAT (ghcr.io は現状 container-registry 認証で fine-grained PAT を サポートしていない)を ~/.config/vivarium/ghcr-pat(mode 0600)に置き、 mise run branch-fix:publish <slug> <tag> <dockerfile> <context> を実行すると、build → ghcr.io/<your-user>/vivarium-<slug>-fix:<tag> に push → docker logout までやってくれる — 認証情報は docker config に残らず、gh CLI の auth state も 触らない。mise run ghcr:login 単体で初回 PAT セットアップ 手順が表示される。

    エージェント駆動のショートカット。 Layer 2/3 の slug に対する verify_branch_fix(slug) は、コピペ可能な gh_command を返す。エージェントが実際にそれを走らせるには gh 認証とレジストリアクセスが必要 — だがコマンド自体は 組み立て済み。

    // 4 · VERDICT を読む

    ここでの `reproduced` と `unreproduced` の意味。

    branch-fix の verdict が伝えるのはちょうど 1 つ: 修正が当たった状態で バグは trigger したか?

    • オリジナル = reproduced、branch-fix = unreproduced。 修正がバグを回避した。典型的な 「修正が動いた」結果。

    • オリジナル = reproduced、branch-fix = reproduced。 修正は slop — outcome を変えていない。 修正を反復して再走させる。

    • オリジナル = unreproduced、branch-fix = reproduced。 リグレッション — あなたの変更が バグを導入した。diff を巻き戻すか、何を変えたかを確認する。

    • オリジナル = unreproduced、branch-fix = unreproduced。 どちらも変化なし。レシピが 非アクティブ(アップストリームが既に修正済み)か、現在のランタイム に対してあなたの修正が no-op。

    Path A は ユーザーランド の修正が壊れた code path を回避するか をテストする — アップストリームのインタプリタにパッチを当てる わけではない。Path B は 完全に再ビルドしたイメージ がバイナリレベルでバグを直すかをテストする。重みは違う、ワイヤ形は同じ。

    // 5 · エッジケース

    ループが計画通り進まないとき。

    • ランタイムが verdict 生成前にエラーした。 Path A ではパネルのステータスラインが赤になり、ランタイムエラー テキストが出る。よくある原因: ペーストした修正の構文エラー。 構文を直して Run をもう一度クリック。

    • スキーマが verdict 形を reject した。 /repro/compare は各 verdict を verdict.schema.json (Contract v1 rev3)に照らして検証する。エラーリージョンは bad フィールドの JSON path を表示する。Path A は構造的に well-formed な verdict を生成するので、これが見えるなら 手編集ファイルをドロップしている可能性が高い。

    • CORS で URL 取得がブロックされた。 公開 raw GitHub と Gist URL は CORS 対応ヘッダを返す。セルフホスト URL はしばしば 返さない。その場合はペーストモードへフォールバック。

    • Path B のプライベートレジストリイメージ。 ランナーは認証なしで pull する。プライベートレジストリは v1 の スコープ外。public ref に push するか、pull 認証情報フォロー アップを待つ。

    • 修正が長すぎて ?fix= に入らない。 インライン URL パラメータの上限は 4 KiB。Gist や fork URL を 使った ?fix_url= を使う。

    // 6 · この先

    このループの上に組めるエージェントループ。

    01
    エージェントループを end-to-end に閉じる。

    パイプライン: match_error → slug に絞り込み → verify_branch_fix → compare_url を開く → verdict を読む。reproduced ならエージェントに別の候補を頼む。unreproduced ならマージへ。

    02
    自分のバグのレシピを足す。

    カタログにまだあなたのバグが無いなら、レシピを書く。Path A は 1 行で opt-in できる。

    03
    verdict を自分の CI と組み合わせる。

    自分のリポジトリに統合する パスは push のたびに verdict ドリフトを検出する — オンデマンドだけではない。

    どこかで詰まったら、それは本ガイドのバグです。slug、Layer、path(A か B)、 詰まったステップ番号を Issue に残してください。

    // NEXT

    用語集 →

    残りのガイドが前提にしている語彙 — Layer、manifest、contract、verdict、evidence、slug — を 1 ページにまとめてある。

    VIVARIUM は ALETHEIA-WORKS の一部 · GitHub でソースを見る →