EQ_S4_STAGE_PLAN r02（P28-02-EQ 段階 S4。EQ_S4_STAGE_PLAN（r01）は、ここで置き換える箇所を除いて、そのまま有効。この r02 は、r01 の §0 の import の範囲、§1.2 の raw3 の名前、実際の API の引数、正式な提出の status、validation の書込みの場所だけを、実際の source に合わせて訂正し、具体化する。S4 の範囲（run_eq.py、verify_eq.py、bundle の正常と拒否の unit、局所の全件 PASS、正式な提出）は小さくしない。SPEC、TASK、6条件、eq/references、eq/registration、補足 r01/r02/r03、段階の計画 r01/r02、S3 の計画 r01/r02、S3b の計画 r01/r02 は変更しない）

1. import の範囲（r01 §0 の4つ目の箇条を置き換える）
- 凍結した EQ SPEC §1 の読取の閉包（RESTART D1 の6つ + DIAG の5つ + EQ 自身）の中のものだけを使う。閉包と権限は広げない。
- collector（execution/p28-01/collector/collect_p28_01.py、SHA a43e1f963ef8505ddd5acf8bf747d9bfac22a028cbb805c0b964ee11b9b40a14）は、閉包の中で、読取専用で import する。
- restart_pair.py（SHA 538302ee…）は RESTART の task の所有物で、EQ の閉包に入らない。import しない。copy_states は、読んで参考にするだけとする。証拠の複製と inventory は、EQ が自分のコードとして eq/ の中に実装する（r01 §1.3 の正確な名前の一覧で）。
- check_eq.py の静的な検査と試験に、restart_pair の import と、閉包の外の import を拒否するものを加える。

2. raw3 の名前（r01 §1.2 の「raw3（stdout、stderr、exit）」を置き換える）
- raw3 は、collector の run_engine（collect_p28_01.py:217、:225）が実際に作る3つのファイル: stdout.log、stderr.log、engine-native.log。engine-native.log（--log-file、--verbose）を落とさない。
- 終了コードは raw3 ではない。owned の受領（process.json など、owned5 の中）にある実際の値を、そこから読んで記録し、結びつける。
- 各 phase で、raw3 の3つのファイルの存在・bytes・SHA と、owned5 の5つの受領を、全て要求する。どれかが欠ければ失敗にする。試験で、engine-native.log の欠落と、終了コードを raw3 から読もうとすることを拒否する。

3. 実際の API の引数（r01 §1.3 と §2 を具体化する）
- check_report(raw, measurement=None, e3_evidence=None, b1_record=None, e45_evidence=None): measurement に lifecycle.measurement、e3_evidence に lifecycle.e3、b1_record に lifecycle.e3_b1、e45_evidence に lifecycle.e45 を渡す。どれかを None のまま呼ばない。
- check_lifecycle(raw, lifecycle, guard): guard は、その phase の guard の受領。
- 各 R/O の phase の private profile の証拠の正確な名前の一覧: checkpoint-00.json〜checkpoint-30.json（31件）、observation-00.json〜observation-30.json（31件）、e3-00.json〜e3-17.json（18件）、e45-00.json〜e45-20.json（21件）、events.json、report.json、lifecycle.json、audio-close.json。これに package の証拠を加える（S3a/S3b で決まった名前のまま）。この一覧と比べて、欠けた・余分な・変わったファイルを拒否する。

4. 正式な提出の status（r01 §4 を具体化する）
- Runner は、worker の JSON の status が "submitted" であることを要求する（core.py:1015）。schema には "pass" もあるが、実装の run では submitted でないと止まる。S4 の最後の JSON の status は、ちょうど "submitted" にする。"pass" や "blocked" にしない。
- commit の欄は、base の 2549cf7d6992560b850bbd11934e3c14b39a1988 とする。worker は git に書き込まない。通常の git commit は Runner.submit が行う。

5. validation の書込みの場所（r01 §2 と §3 を具体化する）
- 正式の validation は、checkout を読取専用にして実行される（core.py:1064 の writable=()）。BUILD_OUTPUT_DIR は、Runner が runtime の build の領域に割り当てる（core.py:827）。
- test_eq.py（p28-02-eq-unit）の bundle の合成の試験は、一時の生成物を、その割り当てられた BUILD_OUTPUT_DIR の下（無い場合は tempfile.gettempdir() の下）の新しい dir にだけ作る。source の tree（eq/ を含む）に書き込む設計にしない。
- verify_eq.py は、bundle を読むだけで、checkout に書き込まない。結果は stdout の JSON で出す。
- 試験で、checkout の中への書込みを検出して拒否する（たとえば、合成の bundle の dir が source の tree の中にあること）。
- 環境・権限・writable の設定は変えない。

6. 変更しないこと
- r01 のそれ以外の全て: 既存の「S4 must」の要件の対応表、7つの phase、guard と profile の規則、gate の None/例外、profile_files の扱い、全証拠の複製と SHA、strict_json と check_observation と check_lifecycle と check_report、39件の scenario、join_report の後の compare_reports、raw と結合した出力と sidecar の分離、R-A/R-B と O-A/O-B の別々の決定性、既存の不具合の保持、source map 1407 と全ての pin、finally の後始末、成功の時だけの seal、「S_eq の native であって Q の測定ではない」の表記、失敗の時の bundle の不作成、verify_eq.py の raw からの再計算、bundle の正常と拒否の試験、119件の本体と全ての失敗の履歴の保持、局所の全件 PASS と生出力の保存。
- worker は、engine の起動、run_eq.py --run の実行、正式の validation の試しの実行、git への書込み、製品の変更、全回帰をしない。
- 提出の後の順序（Root の正確な S の native の7つの phase、bundle の配置、両方の validation、fresh の別の Opus による6条件の全てのレビュー、通常の prepare・資格・承認・integration・final、その後の OPT と whole-unit）と、原本の 23/88・4/30・原本の条件・課金・権限・900秒は変えない。
- 通常の実装上の判断は、記録して進める。
