The r03 S f651ce1 failed its formal OPT verification: the save sample of the migration attempt of a rejected out_of_range load stays in K. r04 extends decision D1 to that sample, adds only that statement to the SPEC section 2 sites and derives the fixed table again from the before record only. Docs only; the r03 task keeps its failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25 KiB
25 KiB
P28-02-OPT 仕様(r04。原本の加算は whole-unit final の後だけ)
- 状態: 登録のための固定版です(r04。候補 r01〜r03 と r04 の候補は Root 制御フォルダの
opt-registration-proposal-r01/〜-r04/にそのまま保持)。docs/plans/original-completion-2026-10-02/execution/p28-02/opt/SPEC.mdとして main に固定し、その実 SHA を base にして、Root が新しい継続登録(projectthe-tree-p28-02-opt-r04、taskP28-02-OPT-R04)をします(Root の決定: 案 1。既存のユーザーの「対象受入に必要な不具合を優先」の範囲、Opus への実装の委任、main の更新の許可を適用した Root の実装判断で、新たな人間の発言を主張する承認ではありません)。r03 で登録したthe-tree-p28-02-optの taskP28-02-OPTは、repair_pending と失敗の履歴のまま残します。r03(maina916841に固定、SHA6441437c…)で登録した task P28-02-OPT の Sf651ce1は、正式の validation で失敗しました(opt/verify_opt.pyの after の既存の不具合が R・O で各1件: E3/load_from_path/out_of_range の K に、移行の試行の save の標本が残った。§3 (iii))。r04 は、その原因の箇所だけを §2・§3・§4・§7 に限定して足し、固定表を before の記録だけから導き直したものです。§3 の決定 D1(案 B)は、失敗した load の移行の試行の save の標本まで同じ扱いに広げます。全ての E の合格、固定表との完全一致、後の版の既存の不具合 0 件、§5 の3指標の規則、全 roster(192 suite)、独立レビュー、原本の 30/88 の分母は変えません。 - 前提:
- P28-02-DIAG は正式に完了しています(Q
fdb309f3bc81529135915429d2432a6644696311、execution/p28-02/DIAG_FORMAL_COMPLETION_FDB309F.json)。T1 の選定の根拠です。 - P28-02-EQ は正式に完了しています(S
9adbbee334548ac36cd49d68efc021abb7acd003、Q4e34e5209706e3e16a4860e65e52b90287722c36、execution/p28-02/EQ_FORMAL_COMPLETION_4E34E52.json)。凍結した EQ(execution/p28-02/eq/**)が、この task の同等性の比較器です。 - 改善の契約は
execution/p28-02/eq/references/OPT_CONTRACT_T1.md(EQ に凍結、SHAad9f3d76…)と、EQ のSPEC.md(SHA3791ccdc…)です。この SPEC はそれらを具体化するもので、置き換えません。両者の違いは §5 に書きます。
- P28-02-DIAG は正式に完了しています(Q
1. 原本の条件(変更しない)
- 成果単位 P28-02(
work_packages.jsonの P28.remaining_deliverables)- work: 失敗時拒否を含む同等性を先に固定し、snapshot変換・検証・コピー・経路接続の実測上位から改善する。
- acceptance: 同条件の反復比較と全状態・全イベント一致を確認し、キャッシュの古さ・所有権・不正入力を検証する。
- P28 の横断条件6件(原文): 原本条件とUI操作が一致 / Runtimeの実利用・会計・行動へ接続 / 途中保存・再起動で再現 / 異常/境界/中断を検証 / 関連回帰PASS / 要件別ログとソースハッシュを保存。
- 補助(原本の分母を増やさない): U1 未達と、実施していない分岐の開示。U2 証拠の範囲の適用。
- 分母は 30/88 で、部分点はありません。現在の正式完了は 23/88、パッケージは 4/30 です。P28 パッケージは P27 と P28-03 が残るため、この task の後も完了になりません。予算の false 6件(R0 の2件、P1 の2件、P2 の2件)は、改善が無ければそのまま残します。原本の条件を満たさなければ、P28-02 は未達のまま保持します。
2. 範囲(OPT_CONTRACT_T1 §1〜§2 を、変えてよい箇所まで具体化する)
- 改善の対象は T1 だけです(I11 PUBLISH_SNAPSHOT、平均 約 81 ms/tick。tick の外の Runtime の
create_snapshotの独立の計測が 約 77 ms)。T2(PathService の query)は選びません(OPT_CONTRACT_T1 §1 の理由。U1 に開示します)。 - 変えてよい製品のファイルは、次の既存の6つだけです。source map の対象で、ファイルの追加と削除は禁止です。各ファイルの中で変えてよい箇所も、次の表に限ります(「許可ファイルなら全ての箇所を自由に変えてよい」とは解釈しません)。
| ファイル | 変えてよい箇所 | 目的 |
|---|---|---|
autoload/simulation_runtime.gd |
create_snapshot、_publish_snapshot、latest_snapshot と latest_digest(宣言と getter、:148-156) |
T1 と E5 の所有権 |
| 同上 | _restore_snapshot_internal のうち domain_events を検証する文(restored_domain_events、:788-790)と確定する文(:1346)だけ |
E4(§3) |
| 同上 | load_from_path の pause の扱い(:4225-4226)と、load_from_path の移行の試行の _record_runtime_performance(&"save", …)(:4235。移行の時間を変数に保持し、受け入れた load だけ _finish_load_operation の後に記録する。決定 D1、r04)と、_finish_load_operation の失敗の分岐のうち operation == &"load" の pause の復元と、同じ失敗の分岐の _record_runtime_performance(&"load", …)(記録しない。決定 D1) |
E3(§3) |
scripts/world/path_service.gd |
create_snapshot だけ |
T1 |
scripts/core/command_queue.gd |
create_snapshot だけ |
T1 |
scripts/world/world_service.gd |
create_snapshot と _create_geometry_snapshot だけ |
T1 |
scripts/world/route_subslot_path_adapter.gd |
create_snapshot だけ |
T1 |
scripts/core/simulation_snapshot.gd |
変更しない(このファイルは validate と restore だけを持ち、create_snapshot の経路の関数が無い。どちらも E3 の対象の API)。変更が必要になった場合は判断に戻す |
— |
- 上の関数の中から呼ぶための新しい private の関数を、同じファイルに足すことは認めます。その関数を呼んでよいのは、上の表の箇所だけです。
- OPT の試験・checker・verifier は
docs/plans/original-completion-2026-10-02/execution/p28-02/opt/**(source map の外)に置きます。 - EQ・DIAG・collector・RESTART の各ファイルの bytes は変えません(OPT_CONTRACT_T1 §2)。それらは変更せずに OPT の S で実行し、検証にもそのまま使います。
3. 前の版の既存の不具合と、OPT での扱い(OPT_CONTRACT_T1 §3「判定の扱い」)
before の記録(EQ の S_eq native native-9adbbee-r01。R-A と O-A の stored checker)にある既存の不具合は、次のとおりです。行の番号は joined report の scenarios の位置です(R と O で同じ並び)。
| 種類 | before の行 | 原因(製品の source) | OPT での扱い |
|---|---|---|---|
| E5 outside_in の aliasing | 27、29、31、33、35、37(latest_snapshot / snapshot_published / state_updated × dict / array。defect: external_mutation_latest、cached_digest_aliasing、computed_latest_digest_changed) | _publish_snapshot(simulation_runtime.gd:12616-12621)が同じ dict を latest_snapshot と2つの signal に渡し、latest_digest を遅延で計算する(:151-156) |
T1 の対象の箇所そのもの。OPT で直す |
| E4 restore/load の event stream の差し替え | 20 E4/restore_snapshot、21 E4/load_from_path(defect: event_stream_replaced_subscribers_not_carried) |
_restore_snapshot_internal が新しい DomainEventStream で置き換え、購読を引き継がない(:788、:1346) |
最小の原因の修正: 検証は従来どおり一時のインスタンスで行い、確定の時に、今の domain_events のインスタンスへ同じ内容を restore_snapshot で入れる(DomainEventStream.restore_snapshot は購読に触れない)。確定の前に、今のインスタンスで restore が失敗しない条件(配送中でない、保留の配送が無い)を確かめ、原子性を保つ |
| E3 load の失敗で K が変わる | R: 12〜17、O: 12〜15、17(E3/load_from_path の各入力。defect: K_changes。O の 16 は NA) | (i) load_from_path が既に paused でも _clock.set_paused(true) を呼び(:4226)、失敗の分岐が _clock.set_paused(previous_paused) で同じ値に戻す(_finish_load_operation)ので、kernel の _pause_request_serial が失敗ごとに +2 される(kernel 側は simulation_kernel.gd:172-178)。(ii) 同じ失敗の分岐が _record_runtime_performance(&"load", …) で performance_budget に標本を1つ足す(_sample_counts.load +1、_samples・_totals の load)。(iii) out_of_range の入力では、load_from_path が UNSUPPORTED_FORMAT を受けて自動の移行を試み(:4228-4242。移行は MIGRATION_DOWNGRADE_UNSUPPORTED で失敗し、ファイルは書かない)、移行の結果にかかわらず _record_runtime_performance(&"save", …)(:4235)で save の標本を1つ足す(_sample_counts.save +1、_samples・_totals の save。R・O とも scenario 14) |
最小の原因の修正: load_from_path の失敗の経路でだけ、(i) kernel の paused と _pause_request_serial を load の前の値に戻し、(ii) その失敗の試行の performance telemetry(load の標本と、(iii) 移行を試みた場合の save の標本)を記録しない(決定 D1)。成功の経路(set_paused(true) とその serial の +1、成功した load の状態・event・telemetry)と、他の load 系の操作は変えない。移行を伴って受け入れた load の save の標本は保つ(記録の位置が _finish_load_operation の後になる。指標ごとの値は同じ)。kernel のファイルは変えない |
- 決定 D1(案 B): Root が、既存のユーザーの「対象受入に必要な不具合を優先」の範囲、Opus への実装の委任、main の更新の許可を適用した実装判断です(新たな人間の発言を主張する承認ではありません)。
- before の E3 の K_changes は (i) と (ii)、out_of_range ではさらに (iii) からなり、凍結した EQ の E3 の判定は、拒否の前後の K の層の全体(telemetry を含む全ての欄の bytes)を比べます。(i) だけでは後の版の「全ての E の合格」(OPT_CONTRACT_T1 §3)に届かないので、(ii) と (iii) も同じ失敗の経路でだけ止めます。
- 凍結 E3 の基準(失敗の前後で S/K/C が不変)は変えません。止めるのは、
load_from_pathの失敗した試行の performance telemetry の記録(load の標本と、移行の試行の save の標本)だけです。成功した load(移行を伴う場合の save の標本を含む)と他の操作(migrate_save_pathを含む)の telemetry は維持します。E3 の K から telemetry を除くという基準の除外(案 A)は採用しません。失敗の標本を除外して通すことはしません。 - r04 の補正の経緯: r03 の §3・D1・固定表は (iii) を見落としていました(r02 の表の導出が、失敗した load の K の変化のうち load の標本だけを確かめていたため)。S
f651ce1の正式の validation で見つかりました(Root 制御フォルダのFORMAL_VALIDATE_F651CE1_SUMMARY.json、OPT_F651CE1_E3_MIGRATION_TELEMETRY_FINDING.json、opt-registration-proposal-r04/OUT_OF_RANGE_ACTUAL_VALUES.json)。 - 失敗の記録と通知は残します:
_complete_save_operationによる SAVE_LOAD_FAILED の event、latest_save_operation_result、save_operation_completedの signal、戻り値と payload のduration_us・runtime_duration_us・message・save_path。凍結 E3 は、この event の形、payload とlatest_save_operation_resultの一致、戻り値と payload の一致、preload_pause_restoredとloaded_clock_pausedを検査します。
- 修正は、その不具合の原因だけを変えます。他の挙動(公開の順序と回数、event の ID と counter と全欄、成功した restore/load の状態)は、§4 の固定表の外で前の版と一致しなければなりません。
4. 同等性の受入規則(凍結した EQ の比較の上に OPT が足す規則。EQ 独立レビューの low 1 への対応)
- 後の版の EQ の記録は、OPT の提出 S で、凍結した
eq/run_eq.py --run <共通> --opt-changed <実際に変更した OPT ファイル>… --output …/eq-after-<S>-r01で取ります(7 phase、version after、measured_sourceS_opt-native-not-Q)。その束は、凍結したeq/verify_eq.py(native-verify と同じ規則)で検証します。R-A と R-B、O-A と O-B の差 0(決定性)と、before と同じ全範囲(各 39 シナリオ)が必要です。 - 版の間の比較は、凍結した
verify_eq.compare_bundles(before, after)の結果の全体を使います(そのokは差が1件でもあれば false。EQ の設計どおり)。 - 許容する差は、before の記録だけから事前に導いて固定した表
opt/registration/BEFORE_DEFECT_ALLOWED_DIFFERENCES.json(SHAa763f0110284326afa5f9001a72261dcd1b9c729c5dd97f9cd82598b841ac9de、role ごとに 196 行)だけです。 表はopt-registration-proposal-r04/derive_opt_allowed_differences_r04.py(Root 制御フォルダ、SHA3f569d94…)が、before の bundle(4c54b665…)の R-A/O-A の joined report・stored checker と、正式の native-verify の比較の結果(digest の方式)から導いたものです。失敗した load ごとに K の変化の全体を取り、serial と、その試行が記録した指標の標本(load、移行を試みた行では save)以外の変化があれば導出を止めます。r03 の表(3bd40d64…)との違いは、role ごとに_sample_countsの 83 行(scenario 14 の checkpoint 1 以降)の after の値だけで、path の集合・行数・before の値は同じです。後の版の観測は使っていません。 - 表の各行は、比較の path(
compare_reportsの path の形そのもの)、before の値、after の値(または K の差の量)、原因です。内訳は role ごとに次のとおりです。- E5 の6行: 操作の直後の観測(checkpoint 2)で、
latestの木の、before の defect に記録された mutation の path(dict はsystems/runtime/id_generator/counters/__p28_eq_probe、array はsystems/runtime/domain_events/published_idsの実際の index)。digest_self_consistent(false → true)。before の比較がその checkpoint で記録した digest の欄(R は product のcomputed_latest_digest、O はharness_normalized_digest。after の値は同じ行の checkpoint 1 の値)。 - E4 の2行:
result.facts.event_streamのkeys(3つ →replacedだけ)とreplaced(true → false)。 - E3 の修正による K の差: 失敗した load の行の最後の checkpoint 以降の全ての scenario の checkpoint で、
K._pause_request_serialの before と after の差が、before の実行の順序で、それまでに通った失敗した load の行の実際の増分(before の defect に記録された値、各 +2)の合計とちょうど等しいこと(R は最後に 12、O は 10)。成功した E4/load_from_path の +1 は両版で同じ。 - 決定 D1 による K の差: 同じ checkpoint の
K.performance_budget._sample_countsで、before の実行の順序で、loadの件数がそれまでに通った失敗した load の行の数(before の defect に記録された各 +1)だけ、saveの件数がそれまでに通った移行を試みた失敗した load の行の数(out_of_range、before の defect に記録された各 +1)だけ少ないこと(R は最後に load 6・save 1、O は load 5・save 1)。他の metric の件数は同じ。_samples・_totalsは EQ の SPEC §3.2 の除外(実時間)のまま、両版の値つきで記録します。
- E5 の6行: 操作の直後の観測(checkpoint 2)で、
- 判定(
opt/check_opt.py)。どれか1つでも満たさなければ不合格です。compare_bundlesの差の集合が、表の行の集合(path・before の値・after の値)と完全に一致すること。表に無い差があっても、表の行の差が出なくても不合格です。仮の定数、path の前方一致での包括の許容、後の版の観測から許容を足すことはしません。- 主の 31 checkpoint(B1 と 30 分)の S・latest・latest_digest・K・C と、全イベント(E2)は差 0 件(表に行が無い)。
- 後の版の
existing_defectsは R と O の両方で 0 件(after_all_e_passtrue)。 - 除外(
excluded)は EQ の SPEC §3.2 の規則のとおりで、両版の実際の値つき。除外で差を隠すことはしません。
- 試験(
opt/test_opt.py): 本物の経路(凍結したcompare_bundlesの結果の形をそのまま使い、外部の入力だけを差し替えたもの)と、モックの試験を区別して記録します。
5. 改善の判定(正式完了した EQ の SPEC §4 を使う。新しい閾値は作らない)
- 二つの文書の違い:
- 凍結の
OPT_CONTRACT_T1.md§4(83 行目): 「改善した」と書いてよいのは、I11(と、(b) の P1/P2 の kernel の標本)で、後の版の3 PID が前の版の3 PID と重ならずに低い場合だけ。重なる場合は「差は確認できない」。「この規則は管制の提案で、独立レビューの確認を受けます」。 - 正式完了した EQ の
SPEC.md§4(76〜79 行目): 「改善あり」と書いてよいのは、(a) が「改善」で、かつ (a)・(b-1)・(b-2) のどれも「悪化」でない場合だけ。(a) が「改善」にならなければ OPT の変更を採用しない。(b) が「改善」でなくても、悪化でなければ構わない。
- 凍結の
- 採用の根拠: EQ の SPEC の冒頭(6 行目)は「この SPEC の §3〜§5 が、その r02(OPT_CONTRACT_T1)の E1 の範囲・改善の判定・順序を確定し、置き換えます」と明示しています。その EQ の SPEC は main に固定されて EQ の登録の base になり、EQ は正式に完了しました(
EQ_FORMAL_COMPLETION_4E34E52.json)。そこで OPT は、EQ の SPEC §4 をそのまま使います。OPT_CONTRACT_T1 §4 の規則で受入を強めることも、弱めることもしません。 - 指標と分類(EQ の SPEC §4 のとおり):
- (a) I11:PID ごとの、測定 30 tick の I11 の平均(inclusive の wall)。前の版は既存の DIAG の native の bundle(S
d6ce6dd、3 PID)を再利用します(条件: 製品の source map が651f7036…、DIAG の5ファイル・engine・fixture・設定が一致)。後の版は OPT の S でdiag/diag_p28_02.py --runを1回(3 PID)。 - (b-1) P1:run ごとの kernel の
simulation_x1の budget_verdict の値(区間の標本の平均)。(b-2) P2:simulation_x3の値(区間の標本の P95)。前の版は既存の full9(db9d613)と frame-before-r02・r03(p28-02-opt/FRAME_BEFORE_R02_R03_SUMMARY.json)の3回、後の版は OPT の S でcollector/collect_p28_01.py --runを3回。 - 分類(指標ごと、前後それぞれ3つの値): 改善(後の3つの最大 < 前の3つの最小)、悪化(後の3つの最小 > 前の3つの最大)、差は確認できない(それ以外)。
- (a) I11:PID ごとの、測定 30 tick の I11 の平均(inclusive の wall)。前の版は既存の DIAG の native の bundle(S
- 記述の規則: 「改善あり」と書いてよいのは、(a) が「改善」で、かつ (a)・(b-1)・(b-2) のどれも「悪化」でない場合だけです。(b-1)・(b-2) が「差は確認できない」の場合は、その指標を「改善した」とは書かず、「差は確認できない(悪化ではない)」と書きます。(a) が「改善」にならなければ、OPT の変更を採用せず、P28-02 は未達のまま保持します。
- P95・最大・stall の最大、I0〜I10 の各区間の値は、記述として全て報告します。予算の false は、改善が無ければそのまま残します。
6. 実行と記録(全て OPT の提出 S で行い、「S で実行した」と記録する)
| 比較 | 前の版 | 後の版(OPT の S) | engine の phase の数 |
|---|---|---|---|
| EQ | native-9adbbee-r01(S_eq、version before。Q_eq 4e34e52 で資格確認済み) |
eq/run_eq.py --run <共通> --opt-changed … を1回 |
7 |
| (a) phase | DIAG d6ce6dd の bundle(再利用) |
diag/diag_p28_02.py --run <共通> を1回 |
6 |
| (b) frame | full9 db9d613 + frame-before-r02・r03 |
collector/collect_p28_01.py --run <共通> を3回 |
27 |
| (c) RESTART | — | p28-01/restart/probe/restart_pair.py --run <共通> を1回 |
7 |
| (d) 関連回帰 | — | tools/run_all_tests.py --project-root <凍結した S の checkout> --godot <engine> |
約194 |
- 共通の引数・出力の場所・凍結した checkout の規則は、OPT_CONTRACT_T1 §4 のとおりです。
- 実行は Root の役割で行います(ユーザーの委任により、現在は Desktop の統括セッション)。実行者・commit・source map・全 raw と SHA を記録します。
- integration の後の Q での再利用は、OPT_CONTRACT_T1 §5 の全ての条件が一致する場合だけです。製品の source map が S と Q で変われば、Q で必要な検証をやり直します。
7. 成果物(execution/p28-02/opt/**)
| ファイル | 役割 |
|---|---|
opt/registration/BEFORE_DEFECT_ALLOWED_DIFFERENCES.json |
§4 の固定表(登録の時に固定。SHA を §4 に記載) |
opt/check_opt.py |
§4 の差の判定、§5 の改善の分類、§2 の変更の箇所の検査(base と S の差分の hunk が、§2 の表の箇所と、そこから呼ぶ新しい private 関数の中だけにあること)、各束の結合(engine を使わない) |
opt/verify_opt.py |
$BUILD_OUTPUT_DIR/p28-02-opt-evidence/ の束(EQ の before/after、DIAG の after、frame の after 3回と before 2回、RESTART、全 roster)を結合して判定します。束が無ければ失敗します |
opt/test_opt.py |
engine を使わない unittest(§2・§4・§5 の正負、束の欠落、偽の合格の拒否。凍結 E3 の判定が K の全体を比べ、telemetry だけの変化も K_changes にすること(移行の save の標本だけが残る場合を含む)、失敗の SAVE_LOAD_FAILED の event と payload を消すと E3 が不合格になることを含む) |
opt/PROGRESS.md、opt/IMPLEMENTATION.md |
経緯と実装の判断 |
8. 順序
- OPT の worker が S_opt を提出します(§2 の箇所だけの変更、engine を使わない局所の unit の全件 PASS、変更した OPT ファイルの一覧)。
- Root が、凍結した S_opt で §6 の (EQ)(a)(b)(c)(d) を実行し、束を作って
$BUILD_OUTPUT_DIRに置きます。 - 正式の validation(unit、EQ の after の native-verify、DIAG の after の verify、OPT の結合 verify)を行います。
- 独立した新しい Opus が、原 work・原 acceptance・横断条件6件・U1/U2 を whole-unit としてレビューします(非同期の配送)。
- prepare → Q での再利用の資格の確認(§6、OPT_CONTRACT_T1 §5)→ 承認 → integration → final → 台帳で 23→24。
9. 全ての失敗の保持
- native・validation・review の失敗は、raw と SHA とともに保全し、成功に書き換えません。修正は、通常の repair で、同じ W で行います。E1〜E5 が1つでも崩れた変更は採用しません。
- r03 の S
f651ce1の記録(EQ・DIAG・collector 3回・RESTART の native、全 roster の r01(容量で停止)と r02(192 suite PASS)、正式の validation の失敗)は、その S の記録として保持します。r04 では製品の source が変わるので、§6 の後の版の全て(EQ、(a)、(b) の3回、(c)、(d))を r04 の S でやり直し、f651ce1の結果を流用しません。前の版の記録(EQ の before、DIAGd6ce6dd、frame の before 3回)は、§5・§6 の条件の一致を確かめて再利用します。 - r04 の実装は、新しい W に
f651ce1の成果(製品の T1・E3・E4・E5 の変更と OPT の道具)を SHA の一致で引き継ぎ(Root 制御フォルダの引き継ぎの manifest)、§2・§3 の r04 の差分と、固定表・規則の更新だけを足します。全てを作り直すことはしません。 - r04 の S では、局所の確認と必要な native で、次も確かめます: 移行が成功した後に load(または restore)が失敗する分岐で、K が不変で save の標本が残らないこと。移行を伴って受け入れた load で、save の標本が1件、移行の
duration_usの値で記録されること。通常の save の標本と、SAVE_LOADED・save_operation_completedの通知の順序と値が変わらないこと。受入の規則に合わなければ、失敗として保持します。後の版を見て固定表の許容を足すことはしません。