P04-01: 同時発生の更新規約

This commit is contained in:
Agent Control Runner
2026-10-16 04:21:59 +09:00
parent cc3a377841
commit 29a641c540
2 changed files with 42 additions and 14 deletions
@@ -50,7 +50,9 @@ Readerは別PID/profileで各slotのjournal.log/manifest.json/thumbnail.png/worl
Readerはさらに各1079 slotをfresh loadして通常clockの2tickを再現し、1080/1081全Runtimeと勤務差分、
同分guardを検査する。FACILITY_COMPLETION前後とAI_DECISIONS後のphase順と全snapshotもWriterに一致させる。
overtimeはunblock後のCOMPLETED/OFF_DUTYまで全Runtime一致を追加確認する。
raw Dictionary getterと保存用canonical Operationsは別々に保存する。getter joinだけStringName/Stringとkey順差を明示し、
実coordinatorの有効性/実nullと、Runtime保存Operationsのenabled/coordinator値を別々に記録する。
実coordinator不在時はgetter適用外・raw getter未呼出しを明示し、架空のday summaryや診断結果を記録しない。
実coordinatorが存在する場合だけraw Dictionary getterと保存用canonical Operationsを別々に保存する。getter joinだけStringName/Stringとkey順差を明示し、
型・値・欠落・配列順を検査する。全Runtime typed条件は緩和しない。
## Rootの正式実行
@@ -96,3 +98,13 @@ worker実施記録: Python py_compile成功。GD grepは `:=` と禁止された
private/default profileの読取りは0。製品1338のcheck-only成功・native成功を主張しない。
最初のworker planは `build/p04-s2b-worker-check-r01.json`。その後の本書/GD調整を含む最終pin確認には
fresh `build/p04-s2b-worker-check-r02.json` を使用し、r01を上書きしない。
## repair15 nullable診断修正
`_capture`でOperationsCoordinatorをis_instance_validで分岐し、実nullと正式保存値`coordinator: {}`を区別する。
全Runtime snapshotは無加工で保持する。fixtureでOperationsをenableせず、既存の境界・保存・replay判定を維持する。
同GD全体を静的確認し、OperationsCoordinatorの直接呼出しはこの分岐内の2件のみ。
reservation/request/task/shift、FileAccess、DirAccessには既存のnullガードがある。
facility/definition/service/guest/worker、_inventory/_request/_worker/_taskの直接参照は既存fixtureの生成・取得成立が前提である。
これらの前提が崩れた場合のnullリスクは残るが、任意機能Operationsの無効化による同種の無条件アクセスは他にない。
本修正版のRoot fresh r02 nativeは未実測。workerはcode-ready提出のみで受入・readinessを確定しない。
@@ -221,16 +221,33 @@ func _writer_branch(branch: String) -> void:
func _capture() -> Dictionary:
var snapshot: Dictionary = _runtime.create_snapshot()
var raw_day: Dictionary = _runtime.operations_coordinator.get_day_summary(1)
var canonical_operations: Dictionary = _runtime.operations_coordinator.create_snapshot()
var canonical_day: Dictionary = {}
var day_count: int = 0
for day: Dictionary in canonical_operations["day_summaries"]:
if int(day["day"]) == 1:
canonical_day = day
day_count += 1
var getter_differences: Array = []
_expect(_getter_join(raw_day, canonical_day, "$", getter_differences) and day_count == (0 if raw_day.is_empty() else 1), "raw getter joins canonical save contract without relaxing Runtime equality")
var saved_operations: Dictionary = snapshot[&"systems"][&"runtime"][&"operations"]
var coordinator: OperationsCoordinator = _runtime.operations_coordinator
var coordinator_present: bool = is_instance_valid(coordinator)
var getter_diagnostics: Dictionary = {
&"operations_enabled": saved_operations[&"enabled"],
&"saved_coordinator": saved_operations[&"coordinator"],
&"actual_coordinator_present": coordinator_present,
&"actual_coordinator_is_null": coordinator == null,
&"getter_applicable": coordinator_present,
&"raw_getter_called": false,
&"getter_status": "not_applicable: actual coordinator absent; raw getter not called",
}
if coordinator_present:
var raw_day: Dictionary = coordinator.get_day_summary(1)
var canonical_operations: Dictionary = coordinator.create_snapshot()
var canonical_day: Dictionary = {}
var day_count: int = 0
for day: Dictionary in canonical_operations["day_summaries"]:
if int(day["day"]) == 1:
canonical_day = day
day_count += 1
var getter_differences: Array = []
_expect(_getter_join(raw_day, canonical_day, "$", getter_differences) and day_count == (0 if raw_day.is_empty() else 1), "raw getter joins canonical save contract without relaxing Runtime equality")
getter_diagnostics.merge({&"raw_getter_called": true, &"getter_status": "executed",
&"raw_day_getter": raw_day, &"canonical_operations": canonical_operations,
&"canonical_day1": canonical_day, &"getter_differences": getter_differences,
&"getter_bytes_equal": var_to_bytes(raw_day) == var_to_bytes(canonical_day)}, true)
var ledger: Array = []
for entry: LedgerEntry in _runtime.economy_service.get_entries(): ledger.append(entry.to_dictionary())
var row: Dictionary = {&"seed": _seed, &"minute": _clock.absolute_minute, &"snapshot": snapshot,
@@ -238,10 +255,9 @@ func _capture() -> Dictionary:
&"source": _source, &"destination": _destination, &"task_id": _task_id, &"shift_id": _shift_id,
&"target": _target, &"request_id": _request_id, &"guest_id": _guest_id,
&"boundary": ShiftInstance.DAY_END},
&"ledger": ledger, &"raw_day_getter": raw_day,
&"canonical_operations": canonical_operations, &"canonical_day1": canonical_day,
&"getter_differences": getter_differences, &"getter_bytes_equal": var_to_bytes(raw_day) == var_to_bytes(canonical_day),
&"ledger": ledger,
&"commands": _commands.duplicate(true), &"command_results": _command_results.duplicate(true)}
row.merge(getter_diagnostics)
# Raw getters retain their actual StringName keys and insertion order. They
# are diagnostics, never substituted for the entire canonical Runtime save.
if _case == "night_absent":