10 KiB
10 KiB
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.json7d83ec0e…)。 - OPT の契約の候補は
OPT_CONTRACT_T1.mdr02 です。この SPEC の §3〜§5 が、その r02 の E1 の範囲・改善の判定・順序を確定し、置き換えます。
- P28-02-DIAG は正式に完了しています(Q
- 原本の条件: 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 と配列の変更
- E3: 不正な入力を与えた
- (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 の正しさと製品の受入の区別
- EQ の worker が S_eq を提出します(engine を使わない局所の unit の全件 PASS つき)。
- 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)
- Root が raw を結合して bundle を作り、
$BUILD_OUTPUT_DIR/p28-02-eq-evidenceに置きます。 - 正式の validation を行います。
p28-02-eq-unitとp28-02-eq-native-verifyの両方が必須です。 - 独立した新しい Opus がレビューします(非同期の配送)。
- 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 で行います。