Files

10 KiB
Raw Permalink Blame History

P28-02-EQ 仕様(spec_ref の候補。製品の変更なし。原本の加算は0)

  • 状態: 候補です。Root が原本の条件と照合して、docs/plans/original-completion-2026-10-02/execution/p28-02/eq/SPEC.md として main に固定し、その実 SHA を base にしてから、通常の新規登録をします。
  • 前提:
    • P28-02-DIAG は正式に完了しています(Q fdb309f3bc81529135915429d2432a6644696311、execution/p28-02/DIAG_FORMAL_COMPLETION_FDB309F.json 7d83ec0e…)。
    • OPT の契約の候補は OPT_CONTRACT_T1.md r02 です。この SPEC の §3〜§5 が、その r02 の E1 の範囲・改善の判定・順序を確定し、置き換えます。
  • 原本の条件: P28-02 の work と acceptance、横断条件6件は execution/p28-02/SPEC.md §1 のとおりで、変更しません。EQ は、OPT の前に同等性を固定するための補助の task で、原本の分母を増やしません(23/88、4/30)。

1. 目的と範囲

  • 原 work の「失敗時拒否を含む同等性を先に固定し」を、製品を変える前に、実行できる harness として凍結します。
  • allowed_paths は docs/plans/original-completion-2026-10-02/execution/p28-02/eq/** だけです。製品の source map の1407件は変更しません。
  • import の閉包:
    • RESTART の CLARIFICATION_02 D1 の6ファイル
    • DIAG の5ファイル(execution/p28-02/diag/*、読取専用)
    • 自分の allowed_paths の中のファイル

2. 成果物

ファイル 役割
eq/run_eq.py Root が実行する native の driver です。--check | --run --readonly <元の p28-01-readonly> --fixture <reference.variant> --engine <Godot> --output <新しい dir>。owned phase・guard・private profile・cleanup は、collector を読取専用で import して使います
eq/eq_probe.gd E1〜E5 の probe です。起動は DIAG の6段階(OPUS_STARTUP_LIFECYCLE_CLARIFICATION)に従います
eq/compare_versions.py 2つの版の記録を比べる比較器です(§3)
eq/check_eq.py report の checker です
eq/verify_eq.py --project-root . で、$BUILD_OUTPUT_DIR/p28-02-eq-evidence にある実際の bundle を結合します。bundle が無ければ失敗します
eq/test_eq.py engine を使わない unittest です

3. 比較の層(OPT r02 の E1 を確定する)

3.1 同じ PID の中(観測の副作用が無いこと)

  • DIAG と同じ、完全な S/K/C 層を、各観測の前後で比べます。K 層には、性能の telemetry(performance_budget の _samples・_totals・_sample_counts)を含みます。C 層には、instance ID を含みます。
  • 前後で、bytes の完全一致を要求します。

3.2 版と版の間(全状態と全イベントの意味の比較)

  • S 層: create_snapshot() の全体を比べます。var_to_bytes の完全一致を第一とします。不一致の場合に限り、RESTART の修正8の完全な typed の正規表現で比べ、dict の列挙の順序だけの差の path を全て記録します。それ以外は不一致です。latest_snapshot も同じ方法で比べます。latest_digest は、文字列の完全一致で比べます。
  • K 層(版の間で比べる欄を、次のものに限ります):
    • absolute_minute、speed、paused、snapshot_version
    • _accumulator(f64 の hex。手動の stepping では決定的)
    • _skip_next_process、_pause_request_serial、_abort_current_tick_requested、_last_tick_advanced
    • _phase_handlers の、phase ごとの handler ID の集合
    • performance_budget._sample_counts の metric ごとの件数(呼出しの回数で、決定的)
  • K 層で、版の間では比べないもの(理由: 実時間に依存し、同じ版の別の PID でも一致しないため): _samples と _totals の時間の値。各 PID の実際の値は、全て raw に保持します。
  • C 層(版の間で比べる欄):
    • _mvp_manifest_cache_generation
    • 「_mvp_manifest_cache_catalog が runtime.mvp_content_catalog と同じ object か」の真偽
    • _mvp_manifest_cache の var_to_bytes
  • C 層で、版の間では比べないもの(理由: プロセスごとに変わる値のため): instance ID の数値そのもの。実際の値は raw に保持します。
  • E2 の全イベント: 開始の時点で、両方の版の domain_event の counter と published_ids の数が一致していることを要求します。そのうえで、event ID をそのまま対応させます(付け替えの対応表は作りません)。全ての欄の完全一致を要求します。開始の時点の counter が違えば、比較は不成立とし、失敗にします。
  • 比べない欄を黙って落とすことはしません。比べない欄と、その理由と、各版の実際の値を、比較の結果に全て記録します。SimulationDigest だけでの判定は不可です。

3.3 観測と、意図的な scenario 操作の境界

  • (a) 観測の区間: 記録・比較・snapshot の取得などの観測そのものは、§3.1 のとおり、前後で完全な S/K/C が不変であることを要求します。
  • (b) scenario の区間: E3/E4/E5 のために列挙した操作だけは、観測の区間とは別の、専用の区間で行ってよいものとします。それぞれの区間には開始と終了の記録を付け、前後の S/K/C の変化、拒否の code、所有権の結果を、実際の値として記録します。列挙した操作は次のとおりです。
    • E3: 不正な入力を与えた restore_snapshot・SimulationSnapshot.validate・load_from_path
    • E4: 状態を変えるコマンド(建設のコマンドを1件、通常の command queue を通す)、tick の進行(advance_minutes(1))、restore_snapshot、load_from_path、状態を変えないコマンド
    • E5: 返された値(create_snapshot() の戻り値、latest_snapshot、snapshot_published / state_updated の引数)の、入れ子の dict と配列の変更
  • (c) 製品の既存の失敗との区別: E5 の操作によって live の状態が変わった場合(たとえば、latest_snapshot と signal の引数の aliasing。OPT r02 §3 で予想したもの)は、製品の既存の失敗として、変化した path と値を記録して保持します。これは harness による無断の変更ではありません。どの scenario の、どの操作の結果かを、記録の中で結びつけます。その scenario の後の検査は、新しい baseline から始めます。
  • (d) 禁止: 上に列挙した scenario の操作以外の、状態の変更と、hook や関数の差し替え。起動の準備(OPUS_STARTUP_LIFECYCLE_CLARIFICATION の段階①②)と手動の stepping は、従来どおりです。
  • 原本の全状態・全イベント・受入の条件は減らしません。K/C の限定の例外(§3.2)も、そのままです。

4. 改善の判定(OPT の受入で使う。新しい数値の閾値は作らない)

  • 指標(PID または run ごとに1つの値):
    • (a) I11:PID ごとの、測定30 tick の I11 の平均(inclusive の wall)
    • (b-1) P1:run ごとの、kernel の simulation_x1 の budget_verdict の値(区間の標本の平均。collector の H1 の定義)
    • (b-2) P2:run ごとの、kernel の simulation_x3 の budget_verdict の値(区間の標本の P95)
  • 前後それぞれ3つの値で、指標ごとに分類します:
    • 改善: 後の版の3つの最大が、前の版の3つの最小より小さい。
    • 悪化: 後の版の3つの最小が、前の版の3つの最大より大きい。
    • 差は確認できない: それ以外(範囲が重なる)。
  • P95・最大・stall の最大、I0〜I10 の各区間の値は、記述として全て報告します。分類には使いません。
  • OPT の受入での扱い:
    • 「改善あり」と書いてよいのは、(a) が「改善」で、かつ (a)・(b-1)・(b-2) のどれも「悪化」でない場合だけです。
    • (a) が「改善」にならなければ、「改善を確認できない」として、OPT の変更を採用しません(原 work の「改善する」を満たさないため)。
    • (b) が「改善」でなくても、悪化でなければ構いません。そのまま記録します。

5. 順序と、harness の正しさと製品の受入の区別

  1. EQ の worker が S_eq を提出します(engine を使わない局所の unit の全件 PASS つき)。
  2. Root が、凍結した S_eq で native を実行します。phase は7つです:
    • import
    • parse-base と parse-wrapper(--check-only)
    • R-A、R-B(R の同じ版の2 PID)
    • O-A、O-B(O の同じ版の2 PID)
  3. Root が raw を結合して bundle を作り、$BUILD_OUTPUT_DIR/p28-02-eq-evidence に置きます。
  4. 正式の validation を行います。p28-02-eq-unit と p28-02-eq-native-verify の両方が必須です。
  5. 独立した新しい Opus がレビューします(非同期の配送)。
  6. prepare → Q_eq の資格の確認 → Root の委任による承認 → integration → final。
  • before の記録: OPT の比較で使う「変更の前の版」の EQ の記録は、手順2の S_eq の native です(製品の1407件は、変更の前と同じです)。Q_eq の資格の確認で、製品の source map・engine・入力・設定・EQ のファイルが一致した場合に限り、そのまま再利用します。一致しなければ、Q_eq でもう一度実行します。
  • harness の正しさ(EQ の受入の条件): 同じ版の2 PID の間で、§3.2 の比較の差が0であること(決定性)。E3/E4/E5 の検査が実際に動いて、結果を記録していること。拒否試験がそろっていること。
  • 製品の結果(EQ の受入の条件ではない): 前の版での E3/E5 の結果は、事実として記録するだけです。失敗したもの(たとえば OPT r02 §3 で予想した E5 の外から内への aliasing)は、既存の不具合として一覧にし、PASS で補いません。それを直すのは OPT の範囲です。

6. 全ての失敗の保持

  • native・validation・review の失敗は、raw と SHA とともに保全し、成功に書き換えません。修正は、通常の repair で、同じ W で行います。