Fix regressions in roster-only suites from A06/A07/P14-03

The formal collector's roster includes 46 suites the Makefile never ran;
the first formal attempt stopped on test_required_kitchen and a sweep found:
- v15 MIMI purchase saves could not be written once Runtime saves carried
  mana_reserve (P06-01): the format detector now validates that section and
  excludes it before the unchanged v15 allowlist, like special_peeping_rooms.
- test_required_kitchen's legacy14 exact-load comparison now maps the two
  approved migrations (fresh A06 reserve at the restored boundary, elevator
  snapshot v1->v2) after checking each against its contract, in Runtime key
  order; every other byte must still match.
- test_runtime_defense_autonomy allowed Mana to change only by the A06 flow.
- test_p08_normal_placement_ops expects 25 palette slots (two warps); its
  suite-policy pin is updated with flags unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Takeshi
2026-10-20 17:08:40 +09:00
co-authored by Claude Opus 5.5
parent 40364345ab
commit 83b170a4c7
5 changed files with 58 additions and 5 deletions
+40
View File
@@ -274,6 +274,42 @@ func _legacy_controls(writer: Dictionary, reader: Dictionary) -> void:
_legacy_control(writer, reader, "byte-identical deep copy", "copy")
_proof("legacy14-migration-controls", {"attempts": 17, "writer_sha256": _typed_sha(writer), "reader_sha256": _typed_sha(reader), "failures": failures})
## Approved later save migrations applied when an older save is loaded, each
## checked against its own contract and then mapped into `expected` in place:
## A06 starts a fresh finite Mana reserve at the restored boundary, and P14-03
## raises the elevator snapshot from v1 to v2 with every other field unchanged.
func _approved_runtime_migrations(expected: Dictionary, reader: Dictionary) -> Dictionary:
var old: Dictionary = expected[&"systems"][&"runtime"]
var now: Dictionary = reader[&"systems"][&"runtime"]
var fields: Array = []
var proof := {}
var ok := true
if not old.has(&"mana_reserve") and now.has(&"mana_reserve"):
var minute := int(expected[&"clock"][&"absolute_minute"])
var fresh := {&"version": 1, &"policy_id": &"MP-01-r02", &"capacity": 300, &"generation": 20,
&"interval_minutes": 10, &"minute": minute - minute % 10, &"last_flow": {}}
ok = ok and now[&"mana_reserve"] == fresh
old[&"mana_reserve"] = now[&"mana_reserve"].duplicate(true)
fields.append("mana_reserve_absent_to_A06_fresh_start")
proof["mana_reserve"] = {"fresh_start_minute": minute - minute % 10, "matches_contract": ok}
if old.get(&"elevators", {}).get(&"version") == 1 and now.get(&"elevators", {}).get(&"version") == 2:
var raised: Dictionary = old[&"elevators"].duplicate(true)
raised[&"version"] = 2
var same_otherwise: bool = raised == now[&"elevators"]
ok = ok and same_otherwise
old[&"elevators"] = raised
fields.append("elevators_v1_to_v2")
proof["elevators"] = {"only_version_changed": same_otherwise}
if not fields.is_empty():
# Saves keep the Runtime's own key order, so the mapped tree follows it.
ok = ok and old.size() == now.size()
var ordered := {}
for key: Variant in now:
ok = ok and old.has(key)
ordered[key] = old.get(key)
expected[&"systems"][&"runtime"] = ordered
return {"ok": ok, "fields": fields, "proof": proof}
func _compare_loaded(writer: Dictionary, write_path: String, read_path: String, label: String, migrate_relationships_v1: bool = false) -> void:
var reader: Dictionary = runtime.create_snapshot()
var old: Dictionary = writer[&"systems"][&"runtime"][&"domain_events"]["recent_events"].back().duplicate(true)
@@ -286,6 +322,8 @@ func _compare_loaded(writer: Dictionary, write_path: String, read_path: String,
valid = valid and var_to_bytes(event) == var_to_bytes(old)
event["event_type"] = actual["event_type"]; event["payload"] = actual["payload"].duplicate(true); replaced += 1
var migration_proof := {}
var runtime_migrations := _approved_runtime_migrations(expected, reader)
valid = valid and runtime_migrations["ok"]
if migrate_relationships_v1:
_legacy_controls(expected, reader)
var migration := _legacy_checkpoint(expected, reader)
@@ -300,6 +338,8 @@ func _compare_loaded(writer: Dictionary, write_path: String, read_path: String,
if migrate_relationships_v1:
binding["mapped_fields"].append("relationships_v1_to_v2")
binding["relationships_v1_to_v2"] = migration_proof
binding["mapped_fields"].append_array(runtime_migrations["fields"])
binding["approved_runtime_migrations"] = runtime_migrations["proof"]
_proof(label + "-io1-binding", binding)
expect(valid, "whole typed loaded state unchanged except complete identity/saveID-bound IO1: " + label)