P08-02: 旧配置の安全な変更

This commit is contained in:
Agent Control Runner
2026-10-13 21:39:16 +09:00
parent e59206b9b2
commit bb34f443c4
8 changed files with 166 additions and 17806 deletions
+13
View File
@@ -2,3 +2,16 @@
Controlled fixture inputs are diagnostic, not production balance values.
Native collection and acceptance remain pending.
Seed: 42588. Registered construction costs for the 16 planned builds total
gold 7110 / materials 88; Gina signing costs 150 and eight raw food units cost
24. Initial resources are gold 5000 / materials 50. The previous fixture had
no change_resources delta (zero), short by gold 2284 / materials 38.
The fixture derives and records this deficit from the actual registry/catalogs
in identity.diagnostic_budget before using the existing change_resources command.
No price or production coefficient is changed.
The first legacy premium job progresses while the six actor/transport facets
are prepared. The second is paid and reserved immediately before saving, with
zero progress; the dormitory is already complete. All three stages share the
same migration batch and whole-state writer/reader comparisons.
+28 -3
View File
@@ -76,8 +76,28 @@ func packages() -> Dictionary:
for member: String in MEMBERS: hashes[suffix+"/"+member] = FileAccess.get_sha256(ProjectSettings.globalize_path(slot+suffix).path_join(member))
return hashes
func observe(event: SimulationDomainEvent) -> void: events.append(event.to_dictionary())
## Controlled diagnostic input; costs come only from registered domain definitions.
func prepare_diagnostic_budget() -> bool:
var planned: Array[StringName] = [&"warehouse",&"kitchen",&"infirmary",&"staff_door",&"reception",&"reception",&"guest_elevator",&"staff_dormitory",&"premium_room",&"premium_room",&"service_stairs",&"service_stairs",&"service_stairs",&"guest_stairs",&"guest_stairs",&"guest_stairs"]
var needed := {&"gold":0,&"materials":0}
var costs: Array = []
for id: StringName in planned:
var definition: FacilityDefinition = runtime.definition_registry.get_facility(id)
if not expect(definition != null,"budget definition "+String(id)): return false
costs.append({&"definition_id":id,&"cost":definition.construction_cost.duplicate(true)})
for resource: StringName in needed: needed[resource] += int(definition.construction_cost.get(resource,0))
var signing := int(runtime.mvp_content_catalog.staff_hire_payload(&"staff_gina").get(&"signing_cost",0))
var food := 8 * int(SupplyCatalog.get_item(SupplyCatalog.RAW_FOOD)[&"unit_price"])
needed[&"gold"] += signing + food
var deltas := {}
for resource: StringName in needed:
var deficit: int = maxi(0,int(needed[resource])-state.get_resource(resource))
if deficit > 0: deltas[resource] = deficit
identity[&"diagnostic_budget"] = {&"seed":42588,&"costs":costs,&"signing":signing,&"food_quantity":8,&"food_cost":food,&"needed":needed,&"initial":state.resources.duplicate(true),&"previous_change_resources":{},&"deltas":deltas}
return deltas.is_empty() or command(&"change_resources",{&"deltas":deltas})
func setup(operations: bool) -> bool:
registry(true)
if not prepare_diagnostic_budget(): return false
if operations and not expect(runtime.enable_production_operations().get(&"ok",false),"Operations enabled at Day 1 06:00"): return false
for row: Array in [[&"warehouse",Vector3i(-8,0,1)],[&"kitchen",Vector3i(2,0,1)],[&"infirmary",Vector3i(6,0,1)],[&"staff_door",Vector3i(0,0,1)],[&"reception",Vector3i(-6,0,0)],[&"reception",Vector3i(5,0,0)],[&"guest_elevator",Vector3i.ZERO]]:
if not build(row[0],row[1],false): return false
@@ -87,12 +107,12 @@ func setup(operations: bool) -> bool:
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
if not build(&"staff_dormitory",Vector3i(-8,2,1)): return false
identity[&"dorm"] = instance(&"staff_dormitory").instance_id
if not build(&"premium_room",Vector3i(-6,2,0),false) or not build(&"premium_room",Vector3i(5,2,0),false): return false
if not build(&"premium_room",Vector3i(-6,2,0),false): return false
clock.advance_minutes(7)
identity[&"jobs"] = []
for job: ConstructionJob in runtime.construction_service.get_jobs():
if not job.is_terminal(): identity[&"jobs"].append(job.job_id)
if not expect(identity[&"jobs"].size() == 2,"two paid active jobs"): return false
if not expect(identity[&"jobs"].size() == 1,"one paid progressing job"): return false
var warehouse := instance(&"warehouse")
var kitchen := instance(&"kitchen")
if not expect(warehouse != null and kitchen != null,"completed logistics endpoints"): return false
@@ -130,9 +150,14 @@ func setup(operations: bool) -> bool:
var car: Dictionary = runtime.elevators.get_report()[&"shafts"][0]
expect(car[&"passenger_count"] == 4 and car[&"waiting_count"] == 1,"passengers and queue coexist")
expect(runtime.create_snapshot()[&"systems"][&"runtime"][&"movement_credits"].size() > 0,"fractional movement credit")
if not build(&"premium_room",Vector3i(5,2,0),false): return false
for candidate: ConstructionJob in runtime.construction_service.get_jobs():
if not candidate.is_terminal() and not identity[&"jobs"].has(candidate.job_id): identity[&"jobs"].append(candidate.job_id)
if not expect(identity[&"jobs"].size() == 2,"two paid active jobs"): return false
identity[&"starting_job"] = identity[&"jobs"][1]
for id: StringName in identity[&"jobs"]:
var job: ConstructionJob = runtime.construction_service.get_job(id)
expect(not job.is_terminal() and job.progress > 0 and job.reserved_cells.size() == 6,"old-size paid jobs remain active")
expect(not job.is_terminal() and (job.progress == 0 if id == identity[&"starting_job"] else job.progress > 0) and not job.construction_cost.is_empty() and job.reserved_cells.size() == 6,"old-size paid starting/progressing jobs remain active")
return failures == 0
func invariant() -> void:
expect(runtime.staff_service.validate_invariants()[&"ok"],"staff ownership")