Record original-alignment implementation and traceability checkpoint

Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
This commit is contained in:
Takeshi
2026-09-30 23:52:24 +09:00
parent 6077e02ebe
commit 5dde0c5ec2
490 changed files with 54051 additions and 809 deletions
@@ -0,0 +1,129 @@
extends RefCounted
## Read-only geometry preflight. A successful preview is NOT a migration commit:
## Runtime ownership, routes, jobs, actor positions and backups need their own gate.
const DIMENSIONS := {
&"premium_room": {&"old": Vector2i(3, 2), &"new": Vector2i(4, 1), &"layer": 0},
&"staff_dormitory": {&"old": Vector2i(4, 2), &"new": Vector2i(2, 1), &"layer": 1},
&"black_market": {&"old": Vector2i(3, 2), &"new": Vector2i(4, 2), &"layer": 0},
}
static func inspect(world: WorldService, instance: Dictionary, weight_per_cell: int, entity_weights: Dictionary = {}) -> Dictionary:
var result := {&"geometry_ok": false, &"ready_to_apply": false, &"errors": [],
&"added": [], &"removed": [], &"target_cells": [], &"affected_entities": [],
&"remaining_gates": [&"DEFINITION_WEIGHT_VALIDATION", &"RUNTIME_CROSSLINKS", &"ROUTES_AND_ACTORS", &"CONSTRUCTION_JOBS", &"BACKUP_AND_ATOMIC_COMMIT"]}
if typeof(instance.get(&"instance_id")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(instance.get(&"definition_id")) not in [TYPE_STRING, TYPE_STRING_NAME]:
result[&"errors"].append(&"INVALID_ID")
return result
var id := StringName(instance.get(&"instance_id", &""))
var definition_id := StringName(instance.get(&"definition_id", &""))
if world == null or id.is_empty() or not DIMENSIONS.has(definition_id) or weight_per_cell <= 0:
result[&"errors"].append(&"INVALID_INPUT")
return result
var origin: Variant = instance.get(&"origin")
var rotation: Variant = instance.get(&"rotation")
var cells: Variant = instance.get(&"occupied_cells")
if not origin is Vector3i or typeof(rotation) != TYPE_INT or rotation not in [0, 90, 180, 270] or not cells is Array:
result[&"errors"].append(&"INVALID_GEOMETRY")
return result
var specification: Dictionary = DIMENSIONS[definition_id]
if origin.z != specification[&"layer"]:
result[&"errors"].append(&"LAYER_MISMATCH")
return result
var old_size: Vector2i = specification[&"old"]
var new_size: Vector2i = specification[&"new"]
if rotation in [90, 270]:
old_size = Vector2i(old_size.y, old_size.x)
new_size = Vector2i(new_size.y, new_size.x)
var expected_old := world.cells_for_footprint(origin, old_size)
var target := world.cells_for_footprint(origin, new_size)
if not _same_cells(cells, world.get_entity_cells(id)) or (not _same_cells(cells, expected_old) and not _same_cells(cells, target)):
result[&"errors"].append(&"SOURCE_OWNERSHIP_OR_SHAPE_MISMATCH")
return result
result[&"target_cells"] = target.duplicate()
for cell: Vector3i in target:
if cell not in cells: result[&"added"].append(cell)
if not world.is_in_bounds(cell): result[&"errors"].append({&"code": &"OUT_OF_BOUNDS", &"cell": cell})
elif cell.y < 0 and not world.is_excavated(cell): result[&"errors"].append({&"code": &"NOT_EXCAVATED", &"cell": cell})
if definition_id == &"black_market" and cell.y >= 0: result[&"errors"].append({&"code": &"ZONE_MISMATCH", &"cell": cell})
var other := world.get_occupant(cell)
if not other.is_empty() and other != id:
result[&"errors"].append({&"code": &"OVERLAP", &"cell": cell, &"entity_id": other})
for cell: Vector3i in cells:
if cell not in target: result[&"removed"].append(cell)
if not result[&"errors"].is_empty(): return result
var candidate := WorldService.new()
if not candidate.restore_snapshot(world.create_snapshot()) or not candidate.release(id) or not candidate.occupy(id, target, world.get_entity_kind(id)):
result[&"errors"].append(&"CANDIDATE_REJECTED")
return result
if not candidate.validate_support(target, weight_per_cell, entity_weights)[&"ok"]:
result[&"errors"].append(&"TARGET_UNSUPPORTED")
# Recheck every previously supported occupied component; removal may split
# a component even when the resized facility itself remains anchored.
for row: Dictionary in world.create_snapshot()[&"occupancies"]:
if row[&"entity_id"] == id: continue
if world.validate_support(row[&"cells"], int(entity_weights.get(row[&"entity_id"], 1)), entity_weights)[&"ok"] and not candidate.validate_support(row[&"cells"], int(entity_weights.get(row[&"entity_id"], 1)), entity_weights)[&"ok"]:
result[&"affected_entities"].append(row[&"entity_id"])
result[&"errors"].append({&"code": &"SUPPORT_LOSS", &"entity_id": row[&"entity_id"]})
result[&"geometry_ok"] = result[&"errors"].is_empty()
return result
static func _same_cells(a: Array, b: Array) -> bool:
if a.size() != b.size(): return false
var seen := {}
for value: Variant in a:
if not value is Vector3i or seen.has(value) or value not in b: return false
seen[value] = true
return true
## Build a validated construction/world candidate without touching live state.
## Other Runtime services and disk backup still need validation before commit.
static func prepare_construction_candidate(world: WorldService, construction: ConstructionService, owner_id: StringName, weight: int, weights: Dictionary = {}) -> Dictionary:
var source := construction.create_snapshot()
var result := {&"ok": false, &"ready_to_apply": false, &"errors": []}
var validator := ConstructionService.new(world)
if source.is_empty() or not validator.restore_snapshot(source):
result[&"errors"].append(&"INVALID_SOURCE_CONSTRUCTION")
return result
var instance := construction.get_facility(owner_id)
var source_job_id: StringName = instance.get(&"source_job_id", &"")
if instance.is_empty():
for job: ConstructionJob in construction.get_jobs():
if job.job_id != owner_id or job.is_terminal(): continue
source_job_id = job.job_id
instance = {&"instance_id": job.job_id, &"definition_id": job.definition_id,
&"origin": job.origin, &"rotation": job.rotation, &"occupied_cells": job.reserved_cells.duplicate()}
break
if instance.is_empty():
result[&"errors"].append(&"MIGRATABLE_OWNER_REQUIRED")
return result
var preview := inspect(world, instance, weight, weights)
result[&"preview"] = preview
if not preview[&"geometry_ok"]:
result[&"errors"] = preview[&"errors"].duplicate(true)
return result
var target: Array = preview[&"target_cells"]
var candidate_world := WorldService.new()
if not candidate_world.restore_snapshot(world.create_snapshot()):
result[&"errors"].append(&"CANDIDATE_WORLD_REJECTED")
return result
if not _same_cells(world.get_entity_cells(owner_id), target) and (not candidate_world.release(owner_id) or not candidate_world.occupy(owner_id, target, world.get_entity_kind(owner_id))):
result[&"errors"].append(&"CANDIDATE_WORLD_REJECTED")
return result
var encoded: Array = []
for cell: Vector3i in target: encoded.append([cell.x, cell.y, cell.z])
var candidate := source.duplicate(true)
for saved: Dictionary in candidate[&"jobs"]:
if StringName(saved[&"job_id"]) == source_job_id:
saved[&"reserved_cells"] = encoded.duplicate(true)
for saved: Dictionary in candidate[&"facilities"]:
if StringName(saved[&"instance_id"]) == owner_id:
saved[&"occupied_cells"] = encoded.duplicate(true)
var restored := ConstructionService.new(candidate_world)
if not restored.restore_snapshot(candidate):
result[&"errors"].append(&"CANDIDATE_CONSTRUCTION_REJECTED")
return result
result[&"ok"] = true
result[&"world"] = candidate_world.create_snapshot()
result[&"construction"] = restored.create_snapshot()
return result
@@ -0,0 +1 @@
uid://5pyjfutw6xl2
@@ -0,0 +1,103 @@
extends RefCounted
## Compare actual guest/staff access queries on two isolated Runtime states.
## Reachability alone is not a relocation or in-flight transport migration.
static func inspect(before: Variant, after: Variant, facility_id: StringName) -> Dictionary:
var result := {&"ok": false, &"errors": [], &"guest_replans": [], &"checked_routes": 0}
var old_room: FacilityInstance = before.facility_service.get_instance(facility_id)
var new_room: FacilityInstance = after.facility_service.get_instance(facility_id)
if old_room == null or new_room == null:
result[&"errors"].append(&"FACILITY_REQUIRED")
return result
_check(result, before.get_facility_access_report(facility_id), after.get_facility_access_report(facility_id), &"ENTRANCE_ACCESS_LOST", &"")
for guest: GuestRuntime in before.guest_service.get_guests():
if guest.target_facility_id != facility_id: continue
var restored: GuestRuntime = after.guest_service.get_guest(guest.guest_id)
if restored == null:
result[&"errors"].append({&"code": &"GUEST_MISSING", &"id": guest.guest_id})
continue
var old_route: Dictionary = before._find_facility_access_path(guest.current_cell, old_room)
var new_route: Dictionary = after._find_facility_access_path(restored.current_cell, new_room)
_check(result, old_route, new_route, &"GUEST_ACCESS_LOST", guest.guest_id)
if restored.state == GuestRuntime.State.MOVING and new_route[&"reachable"]:
var target: Vector3i = after._path_handle_target(restored.path_handle, restored.current_cell)
# A new best destination must be applied explicitly to the saved route.
if target != new_route[&"target_cell"]:
result[&"guest_replans"].append({&"id": guest.guest_id, &"old_target": target, &"target": new_route[&"target_cell"]})
for worker: StaffRuntime in before.staff_service.get_staff_members():
var assignment: Dictionary = before.staff_service.get_work_assignment(worker.staff_id)
var rest: Dictionary = before.get_staff_rest_report(worker.staff_id)
var resting_here := StringName(rest.get(&"facility_id", &"")) == facility_id
if worker.assigned_facility_id != facility_id and StringName(assignment.get(&"facility_id", &"")) != facility_id and not resting_here: continue
var restored: StaffRuntime = after.staff_service.get_staff(worker.staff_id)
if restored == null:
result[&"errors"].append({&"code": &"STAFF_MISSING", &"id": worker.staff_id})
continue
_check(result, before.staff_commute.find_facility_access_path(worker.current_cell, old_room), after.staff_commute.find_facility_access_path(restored.current_cell, new_room), &"STAFF_ACCESS_LOST", worker.staff_id)
var access_cells := {}
for cell: Vector3i in new_room.occupied_cells:
for offset: Vector3i in [Vector3i.ZERO, Vector3i.LEFT, Vector3i.RIGHT]: access_cells[cell + offset] = true
for task: StaffTask in before.staff_service.get_tasks():
if task.is_terminal() or (task.target_entity_id != facility_id and task.rescue_facility_id != facility_id): continue
var restored: StaffTask = after.staff_service.get_task(task.task_id)
if restored == null or restored.create_snapshot() != task.create_snapshot():
result[&"errors"].append({&"code": &"TASK_STATE_CHANGED", &"id": task.task_id})
continue
if not access_cells.has(task.target_cell):
result[&"errors"].append({&"code": &"TASK_DESTINATION_CHANGED", &"id": task.task_id})
continue
if task.assigned_staff_id.is_empty(): continue
var old_worker: StaffRuntime = before.staff_service.get_staff(task.assigned_staff_id)
var new_worker: StaffRuntime = after.staff_service.get_staff(task.assigned_staff_id)
if old_worker == null or new_worker == null:
result[&"errors"].append({&"code": &"STAFF_MISSING", &"id": task.assigned_staff_id})
continue
_check(result, {&"reachable":_task_reachable(before, old_worker, task)}, {&"reachable":_task_reachable(after, new_worker, restored)}, &"TASK_ACCESS_LOST", task.task_id)
result[&"ok"] = result[&"errors"].is_empty() and result[&"guest_replans"].is_empty()
return result
static func _check(result: Dictionary, old_route: Dictionary, new_route: Dictionary, code: StringName, actor_id: StringName) -> void:
result[&"checked_routes"] += 1
if old_route.get(&"reachable", false) and not new_route.get(&"reachable", false):
result[&"errors"].append({&"code": code, &"id": actor_id})
## Apply only to an isolated candidate. Validate the entire batch before changes.
## Position, movement credit, service request, wallet and transport stay intact.
static func retarget_guests(candidate: Variant, report: Dictionary) -> Dictionary:
var result := {&"ok": false, &"errors": [], &"changed": []}
if not report.get(&"errors", []).is_empty():
result[&"errors"].append(&"ACCESS_LOSS")
return result
var updates: Array = []
var seen := {}
for plan: Dictionary in report.get(&"guest_replans", []):
var id := StringName(plan.get(&"id", &""))
var guest: GuestRuntime = candidate.guest_service.get_guest(id)
if guest == null or seen.has(id) or guest.state != GuestRuntime.State.MOVING or not guest.path_handle is Dictionary or not plan.get(&"target") is Vector3i:
result[&"errors"].append(&"INVALID_REPLAN")
return result
seen[id] = true
if candidate._path_handle_target(guest.path_handle, guest.current_cell) != plan.get(&"old_target"):
result[&"errors"].append(&"STALE_REPLAN")
return result
if not candidate.elevators.get_actor_trip(candidate._guest_path_actor_id(id)).is_empty():
result[&"errors"].append(&"TRANSPORT_REPLAN_REQUIRED")
return result
if candidate.path_service.find_path(guest.current_cell, plan[&"target"]).is_empty():
result[&"errors"].append(&"TARGET_UNREACHABLE")
return result
updates.append({&"guest": guest, &"target": plan[&"target"]})
for update: Dictionary in updates:
var guest: GuestRuntime = update[&"guest"]
var handle: Dictionary = guest.path_handle.duplicate(true)
handle[&"target_cell"] = update[&"target"]
handle[&"graph_revision"] = candidate.path_service.graph_revision
guest.path_handle = handle
result[&"changed"].append(guest.guest_id)
result[&"ok"] = true
return result
static func _task_reachable(runtime: Variant, worker: StaffRuntime, task: StaffTask) -> bool:
if task.task_type in [&"rescue_pickup", &"rescue_transport"]:
return not runtime.path_service.find_backyard_path(worker.current_cell, task.target_cell, true).is_empty()
return not runtime.path_service.find_path(worker.current_cell, task.target_cell, [WorldService.LAYER_FRONT, WorldService.LAYER_BACK], [&"staff"]).is_empty()
@@ -0,0 +1 @@
uid://bu8b3e66tt4lc