Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7e3069b16 | ||
|
|
27fc5f0544 | ||
|
|
e930a1dedf |
@@ -20,6 +20,7 @@ const OPERATING_EXPENSE_ACCOUNT := &"OPERATING_EXPENSE"
|
|||||||
const AUTHORITY_FINE_ACCOUNT := &"AUTHORITY_FINE_EXPENSE"
|
const AUTHORITY_FINE_ACCOUNT := &"AUTHORITY_FINE_EXPENSE"
|
||||||
const WAGE_EXPENSE_ACCOUNT := &"WAGE_EXPENSE"
|
const WAGE_EXPENSE_ACCOUNT := &"WAGE_EXPENSE"
|
||||||
const RUNTIME_SNAPSHOT_VERSION := 14
|
const RUNTIME_SNAPSHOT_VERSION := 14
|
||||||
|
const PeepingRooms := preload("res://scripts/special/peeping_room_service.gd")
|
||||||
const AUTO_PURCHASE_RUNTIME_SNAPSHOT_VERSION := 14
|
const AUTO_PURCHASE_RUNTIME_SNAPSHOT_VERSION := 14
|
||||||
const EVENT_THREAT_RUNTIME_SNAPSHOT_VERSION := 13
|
const EVENT_THREAT_RUNTIME_SNAPSHOT_VERSION := 13
|
||||||
const MIMI_PURCHASE_RUNTIME_SNAPSHOT_VERSION := 15
|
const MIMI_PURCHASE_RUNTIME_SNAPSHOT_VERSION := 15
|
||||||
@@ -97,6 +98,7 @@ const DEFENSE_COMMAND_TYPES: Array[StringName] = [
|
|||||||
var definition_registry := DefinitionRegistry.new()
|
var definition_registry := DefinitionRegistry.new()
|
||||||
var command_queue := CommandQueue.new()
|
var command_queue := CommandQueue.new()
|
||||||
var id_generator := StableIdGenerator.new()
|
var id_generator := StableIdGenerator.new()
|
||||||
|
var peeping_room_service := PeepingRooms.new()
|
||||||
var domain_events := DomainEventStream.new()
|
var domain_events := DomainEventStream.new()
|
||||||
var world_service := WorldService.new()
|
var world_service := WorldService.new()
|
||||||
var path_service := PathService.new()
|
var path_service := PathService.new()
|
||||||
@@ -233,6 +235,7 @@ func initialize(clock: SimulationKernel, state: Variant, seed := DEFAULT_WORLD_S
|
|||||||
_hired_staff_candidate_ids.clear()
|
_hired_staff_candidate_ids.clear()
|
||||||
command_queue = CommandQueue.new()
|
command_queue = CommandQueue.new()
|
||||||
id_generator = StableIdGenerator.new()
|
id_generator = StableIdGenerator.new()
|
||||||
|
peeping_room_service = PeepingRooms.new()
|
||||||
domain_events = DomainEventStream.new()
|
domain_events = DomainEventStream.new()
|
||||||
world_service = WorldService.new()
|
world_service = WorldService.new()
|
||||||
path_service = PathService.new()
|
path_service = PathService.new()
|
||||||
@@ -253,6 +256,7 @@ func initialize(clock: SimulationKernel, state: Variant, seed := DEFAULT_WORLD_S
|
|||||||
_initialize_s5_defense()
|
_initialize_s5_defense()
|
||||||
construction_service = ConstructionService.new(world_service, construction_resource_state)
|
construction_service = ConstructionService.new(world_service, construction_resource_state)
|
||||||
construction_service.current_minute = _clock.absolute_minute
|
construction_service.current_minute = _clock.absolute_minute
|
||||||
|
peeping_room_service.configure(world_service, facility_service, construction_service, path_service, id_generator)
|
||||||
_connect_construction_signals()
|
_connect_construction_signals()
|
||||||
var initial_infrastructure_ok := _initialize_infrastructure_services()
|
var initial_infrastructure_ok := _initialize_infrastructure_services()
|
||||||
_next_command_id = 1
|
_next_command_id = 1
|
||||||
@@ -298,6 +302,8 @@ func initialize(clock: SimulationKernel, state: Variant, seed := DEFAULT_WORLD_S
|
|||||||
register_command_executor(&"build_facility", Callable(self, "_execute_build_facility"))
|
register_command_executor(&"build_facility", Callable(self, "_execute_build_facility"))
|
||||||
register_command_executor(&"cancel_construction", Callable(self, "_execute_cancel_construction"))
|
register_command_executor(&"cancel_construction", Callable(self, "_execute_cancel_construction"))
|
||||||
register_command_executor(&"demolish_facility", Callable(self, "_execute_demolish_facility"))
|
register_command_executor(&"demolish_facility", Callable(self, "_execute_demolish_facility"))
|
||||||
|
for command_type: StringName in [&"peeping_room_validate", &"peeping_room_place", &"peeping_room_relink", &"peeping_room_record_evidence"]:
|
||||||
|
register_command_executor(command_type, Callable(self, "_execute_peeping_room"))
|
||||||
register_command_executor(&"set_elevator_operation", Callable(self, "_execute_set_elevator_operation"))
|
register_command_executor(&"set_elevator_operation", Callable(self, "_execute_set_elevator_operation"))
|
||||||
register_command_executor(&"start_excavation", Callable(self, "_execute_start_excavation"))
|
register_command_executor(&"start_excavation", Callable(self, "_execute_start_excavation"))
|
||||||
register_command_executor(&"pause_excavation", Callable(self, "_execute_pause_excavation"))
|
register_command_executor(&"pause_excavation", Callable(self, "_execute_pause_excavation"))
|
||||||
@@ -565,6 +571,8 @@ func create_snapshot() -> Dictionary:
|
|||||||
}
|
}
|
||||||
if PurchaseQuoteV2.has_history(owned_systems[&"runtime"]):
|
if PurchaseQuoteV2.has_history(owned_systems[&"runtime"]):
|
||||||
owned_systems[&"runtime"][&"runtime_schema_version"] = MIMI_PURCHASE_RUNTIME_SNAPSHOT_VERSION
|
owned_systems[&"runtime"][&"runtime_schema_version"] = MIMI_PURCHASE_RUNTIME_SNAPSHOT_VERSION
|
||||||
|
if not peeping_room_service.is_empty():
|
||||||
|
owned_systems[&"runtime"][&"special_peeping_rooms"] = peeping_room_service.create_snapshot()
|
||||||
# Every component above returns detached containers. Transfer this fresh
|
# Every component above returns detached containers. Transfer this fresh
|
||||||
# tree into the envelope instead of deep-copying all component snapshots a
|
# tree into the envelope instead of deep-copying all component snapshots a
|
||||||
# second time. Keep generic capture's caller-owned-extra contract unchanged.
|
# second time. Keep generic capture's caller-owned-extra contract unchanged.
|
||||||
@@ -666,6 +674,8 @@ func _restore_snapshot_internal(snapshot: Dictionary, recovery_mode: bool) -> bo
|
|||||||
runtime_current_keys.append(&"facility_cleanliness")
|
runtime_current_keys.append(&"facility_cleanliness")
|
||||||
if runtime_schema_version >= AUTO_PURCHASE_RUNTIME_SNAPSHOT_VERSION:
|
if runtime_schema_version >= AUTO_PURCHASE_RUNTIME_SNAPSHOT_VERSION:
|
||||||
runtime_current_keys.append(&"auto_purchase_plans")
|
runtime_current_keys.append(&"auto_purchase_plans")
|
||||||
|
if runtime_data.has(&"special_peeping_rooms"):
|
||||||
|
runtime_current_keys.append(&"special_peeping_rooms")
|
||||||
if not _dictionary_has_exact_canonical_keys(runtime_data, runtime_current_keys) \
|
if not _dictionary_has_exact_canonical_keys(runtime_data, runtime_current_keys) \
|
||||||
or typeof(runtime_data.get(&"runtime_schema_version", null)) != TYPE_INT \
|
or typeof(runtime_data.get(&"runtime_schema_version", null)) != TYPE_INT \
|
||||||
or typeof(runtime_data.get(&"world_seed", null)) != TYPE_INT \
|
or typeof(runtime_data.get(&"world_seed", null)) != TYPE_INT \
|
||||||
@@ -1290,6 +1300,16 @@ func _restore_snapshot_internal(snapshot: Dictionary, recovery_mode: bool) -> bo
|
|||||||
var restored_next_id := int(runtime_data.get(&"next_command_id", 0))
|
var restored_next_id := int(runtime_data.get(&"next_command_id", 0))
|
||||||
if restored_next_id <= 0:
|
if restored_next_id <= 0:
|
||||||
return false
|
return false
|
||||||
|
var restored_peeping_rooms := PeepingRooms.new()
|
||||||
|
restored_peeping_rooms.configure(restored_world, restored_facilities, restored_construction, restored_path, restored_id_generator)
|
||||||
|
if runtime_data.has(&"special_peeping_rooms"):
|
||||||
|
if not runtime_data[&"special_peeping_rooms"] is Dictionary:
|
||||||
|
return false
|
||||||
|
for raw_key: Variant in runtime_data:
|
||||||
|
if raw_key == &"special_peeping_rooms" and typeof(raw_key) != TYPE_STRING_NAME:
|
||||||
|
return false
|
||||||
|
if not restored_peeping_rooms.restore_section(runtime_data.get(&"special_peeping_rooms", null), restored_minute):
|
||||||
|
return false
|
||||||
if not SimulationSnapshot.restore(snapshot, _clock, _state):
|
if not SimulationSnapshot.restore(snapshot, _clock, _state):
|
||||||
return false
|
return false
|
||||||
world_seed = restored_world_seed
|
world_seed = restored_world_seed
|
||||||
@@ -1297,6 +1317,7 @@ func _restore_snapshot_internal(snapshot: Dictionary, recovery_mode: bool) -> bo
|
|||||||
_staffing_projection_enabled = restored_staffing_projection
|
_staffing_projection_enabled = restored_staffing_projection
|
||||||
command_queue = restored_queue
|
command_queue = restored_queue
|
||||||
id_generator = restored_id_generator
|
id_generator = restored_id_generator
|
||||||
|
peeping_room_service = restored_peeping_rooms
|
||||||
domain_events = restored_domain_events
|
domain_events = restored_domain_events
|
||||||
_rng_streams = restored_streams
|
_rng_streams = restored_streams
|
||||||
world_service = restored_world
|
world_service = restored_world
|
||||||
@@ -5546,6 +5567,7 @@ func _connect_facility_signals() -> void:
|
|||||||
return
|
return
|
||||||
facility_service.instance_registered.connect(Callable(self, "_on_cleanliness_facility_registered"))
|
facility_service.instance_registered.connect(Callable(self, "_on_cleanliness_facility_registered"))
|
||||||
facility_service.instance_unregistered.connect(Callable(self, "_on_cleanliness_facility_unregistered"))
|
facility_service.instance_unregistered.connect(Callable(self, "_on_cleanliness_facility_unregistered"))
|
||||||
|
facility_service.instance_unregistered.connect(Callable(self, "_on_peeping_target_removed"))
|
||||||
facility_service.facility_state_changed.connect(Callable(self, "_on_facility_state_changed"))
|
facility_service.facility_state_changed.connect(Callable(self, "_on_facility_state_changed"))
|
||||||
facility_service.service_started.connect(Callable(self, "_on_service_started"))
|
facility_service.service_started.connect(Callable(self, "_on_service_started"))
|
||||||
facility_service.service_interrupted.connect(Callable(self, "_on_service_interrupted"))
|
facility_service.service_interrupted.connect(Callable(self, "_on_service_interrupted"))
|
||||||
@@ -10817,6 +10839,7 @@ func _on_excavation_completed(report: Dictionary) -> void:
|
|||||||
))
|
))
|
||||||
|
|
||||||
func _on_facility_demolished(instance_id: StringName, refund: Dictionary) -> void:
|
func _on_facility_demolished(instance_id: StringName, refund: Dictionary) -> void:
|
||||||
|
peeping_room_service.target_removed(instance_id)
|
||||||
if not mana_network_service.get_node(instance_id).is_empty():
|
if not mana_network_service.get_node(instance_id).is_empty():
|
||||||
mana_network_service.unregister_node(instance_id)
|
mana_network_service.unregister_node(instance_id)
|
||||||
if facility_service.has_instance(instance_id):
|
if facility_service.has_instance(instance_id):
|
||||||
@@ -10831,6 +10854,31 @@ func _on_facility_demolished(instance_id: StringName, refund: Dictionary) -> voi
|
|||||||
0
|
0
|
||||||
))
|
))
|
||||||
|
|
||||||
|
func _on_peeping_target_removed(instance_id: StringName) -> void:
|
||||||
|
peeping_room_service.target_removed(instance_id)
|
||||||
|
|
||||||
|
func _execute_peeping_room(command: SimulationCommand) -> CommandResult:
|
||||||
|
var payload := command.payload
|
||||||
|
var report: Dictionary
|
||||||
|
if command.command_type == &"peeping_room_place":
|
||||||
|
report = PeepingRooms.result(&"BUILD_DEFINITION_PENDING_D04")
|
||||||
|
elif command.command_type == &"peeping_room_validate":
|
||||||
|
if typeof(payload.get(&"origin")) != TYPE_VECTOR3I or typeof(payload.get(&"footprint", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&"target_instance_id", &"")) not in [TYPE_STRING, TYPE_STRING_NAME]:
|
||||||
|
report = PeepingRooms.result(&"INVALID_PAYLOAD")
|
||||||
|
else:
|
||||||
|
report = peeping_room_service.validate_placement(payload[&"origin"], payload.get(&"footprint", Vector2i(2, 1)), StringName(payload.get(&"target_instance_id", &"")))
|
||||||
|
else:
|
||||||
|
var key: StringName = &"target_instance_id" if command.command_type == &"peeping_room_relink" else &"source_event_key"
|
||||||
|
if typeof(payload.get(&"room_id")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &"")) not in [TYPE_STRING, TYPE_STRING_NAME]:
|
||||||
|
report = PeepingRooms.result(&"INVALID_PAYLOAD")
|
||||||
|
elif command.command_type == &"peeping_room_relink":
|
||||||
|
report = peeping_room_service.relink(StringName(payload[&"room_id"]), StringName(payload.get(key, &"")))
|
||||||
|
else:
|
||||||
|
report = peeping_room_service.record_evidence(StringName(payload[&"room_id"]), StringName(payload.get(key, &"")), _runtime_event_minute())
|
||||||
|
if report[&"ok"]:
|
||||||
|
return CommandResult.succeeded(command.command_id, report)
|
||||||
|
return CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&"reason"]), report)
|
||||||
|
|
||||||
func _on_ledger_transaction_posted(transaction_id: StringName, _entries: Array) -> void:
|
func _on_ledger_transaction_posted(transaction_id: StringName, _entries: Array) -> void:
|
||||||
if _operations_flushing_economy_notifications.has(transaction_id):
|
if _operations_flushing_economy_notifications.has(transaction_id):
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -3734,6 +3734,61 @@
|
|||||||
"path": "docs/spec/acceptance/P23-03.json",
|
"path": "docs/spec/acceptance/P23-03.json",
|
||||||
"scope": "component and read-only observation only; native unexecuted; whole unit blocked"
|
"scope": "component and read-only observation only; native unexecuted; whole unit blocked"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test": "tests/special/test_peeping_room_geometry.gd",
|
||||||
|
"template": "Peeping room geometry: <checks> checks, <failures> failures",
|
||||||
|
"required": true,
|
||||||
|
"fixed_check_count_used": false,
|
||||||
|
"source_sha256_at_schema_audit": "103d85f83e1e97a8637892504264275eef23f172eeec56c94e5c022d81bf6945",
|
||||||
|
"authority": {
|
||||||
|
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
||||||
|
"scope": "new backend suite marker; native execution pending"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test": "tests/special/test_peeping_room_reference.gd",
|
||||||
|
"template": "Peeping room reference: <checks> checks, <failures> failures",
|
||||||
|
"required": true,
|
||||||
|
"fixed_check_count_used": false,
|
||||||
|
"source_sha256_at_schema_audit": "188b00a60f7aefda69dc4973f1de9c14447a0d4bcdd1257a2eabe7c4782e4caf",
|
||||||
|
"authority": {
|
||||||
|
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
||||||
|
"scope": "new backend suite marker; native execution pending"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test": "tests/special/test_peeping_room_evidence.gd",
|
||||||
|
"template": "Peeping room evidence: <checks> checks, <failures> failures",
|
||||||
|
"required": true,
|
||||||
|
"fixed_check_count_used": false,
|
||||||
|
"source_sha256_at_schema_audit": "390e0032d14de9a8875ced163a922341ce655744200d78b4ffa776d42c4f8c2a",
|
||||||
|
"authority": {
|
||||||
|
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
||||||
|
"scope": "new backend suite marker; native execution pending"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test": "tests/special/test_peeping_room_save.gd",
|
||||||
|
"template": "Peeping room save: <checks> checks, <failures> failures",
|
||||||
|
"required": true,
|
||||||
|
"fixed_check_count_used": false,
|
||||||
|
"source_sha256_at_schema_audit": "ba0e7644277477c1821135cae6d6fd533651799c6f9bd8c43ccf45e63b96c63c",
|
||||||
|
"authority": {
|
||||||
|
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
||||||
|
"scope": "new backend suite marker; native execution pending"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test": "tests/special/test_peeping_room_runtime.gd",
|
||||||
|
"template": "Peeping room runtime: <checks> checks, <failures> failures",
|
||||||
|
"required": true,
|
||||||
|
"fixed_check_count_used": false,
|
||||||
|
"source_sha256_at_schema_audit": "924efd34414c12a325a1b700f799aef0396de9f15441fd88a3608292ff221657",
|
||||||
|
"authority": {
|
||||||
|
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
||||||
|
"scope": "new backend suite marker; native execution pending"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"unknown_roster_suite_policy": "refuse, explicitly review its source/schema before accepting",
|
"unknown_roster_suite_policy": "refuse, explicitly review its source/schema before accepting",
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
# P13-02-CODE1 implementation handoff
|
||||||
|
|
||||||
|
This is non-graphic state/reference/occupancy/save machinery only. It does not
|
||||||
|
complete P13-02, grant partial credit, or change the original 30/88 denominator
|
||||||
|
or formal 14/88 count. Native execution and acceptance are pending.
|
||||||
|
|
||||||
|
## Declared scope and verification
|
||||||
|
|
||||||
|
Before editing, the worker declared the new service, bounded Runtime hooks,
|
||||||
|
special tests, narrow runner, marker additions and this documentation. SaveService
|
||||||
|
was conditional on an exact-key dependency; inspection found
|
||||||
|
`SupplyAutoPurchaseQuotePlans.valid_runtime_format` has that dependency.
|
||||||
|
Only allowed paths were edited. No asset, UI, content, model, policy, clock phase,
|
||||||
|
or P04 change is involved.
|
||||||
|
|
||||||
|
The full ignored `build/owner-handoff/ACTUAL_OPUS_RUN_DECISION.json` was read and
|
||||||
|
left untouched. Base HEAD is `1e8d4ea88876865a72547ff0edf43ed5b0e74c7e`.
|
||||||
|
The immutable spec was not edited. Its SHA-256 without the terminal newline is
|
||||||
|
the registered `8ea65f2eefedc772c08170186f5cd03ac017432f4b069ade4f9210d4215c2d43`;
|
||||||
|
the on-disk file including that newline is
|
||||||
|
`988d6e18a49372549863cd433432c2852c962fa64b138e490361c023e80249dc`.
|
||||||
|
|
||||||
|
Worker verification: Python AST parsing/compilation only, without executing the
|
||||||
|
runner or importing its dependencies; source/JSON/hash review. GDScript parsing,
|
||||||
|
all tests, `--prepare-only`, native collection and regression were **not run**.
|
||||||
|
No check totals or native success receipts are claimed. No git writes, commits,
|
||||||
|
branches, other agents, integration or Runner operations were performed.
|
||||||
|
|
||||||
|
## Service and commands
|
||||||
|
|
||||||
|
`PeepingRoomService` is a separate RefCounted service with no content or UI.
|
||||||
|
All command executors use the existing Runtime queue; queue/history receipts
|
||||||
|
remain normal Runtime behavior even for rejected/read-only domain commands.
|
||||||
|
|
||||||
|
| Command | Preconditions and result |
|
||||||
|
| --- | --- |
|
||||||
|
| `peeping_room_validate` | `origin: Vector3i`, optional `footprint: Vector2i` (2x1), optional `target_instance_id: String/StringName`. Pure domain validation. |
|
||||||
|
| `peeping_room_place` | Always `BUILD_DEFINITION_PENDING_D04`; no occupancy, resource, room or ID mutation. |
|
||||||
|
| `peeping_room_relink` | Existing `room_id`, explicit nonempty `target_instance_id`; full geometry and ownership validation excluding only the room's exact own occupancy. Leaves `LINKED`, stopped, `RELINKED_PENDING_RESUME`. |
|
||||||
|
| `peeping_room_record_evidence` | Existing `room_id`, nonblank named `source_event_key`. Uses Runtime minute, never caller-supplied time. Checks stopped, target power, target closure/opening hours, completed construction authority, and lost target in that order. Otherwise rejects with `RECORDER_ELIGIBILITY_PENDING_D04_D08_P16`. Never writes the ledger. |
|
||||||
|
|
||||||
|
Malformed command field types return `INVALID_PAYLOAD`. Missing/blank source keys
|
||||||
|
return `SOURCE_EVENT_KEY_REQUIRED` before operational checks. Loss latches both
|
||||||
|
`TARGET_LOST` and stopped, so collection after normal demolition returns `STOPPED`
|
||||||
|
while the room's link/stop reason identifies `TARGET_LOST`. No resume command or
|
||||||
|
automatic resume is defined. Power/closure guards read actual target conditions;
|
||||||
|
they do not define special-room power demand, staffing or normal operation.
|
||||||
|
|
||||||
|
Placement is exactly 2x1 BACK, fully behind a single completed FRONT
|
||||||
|
`public_bath` or `adult_private_room`. It checks bounds/excavation, both real
|
||||||
|
FacilityService and ConstructionService ownership, FRONT cells, World occupancy,
|
||||||
|
and both World walkability and PathService membership. Exact rejection families:
|
||||||
|
`WRONG_LAYER`, `WRONG_FOOTPRINT`, `OUT_OF_BOUNDS`, `NOT_EXCAVATED`,
|
||||||
|
`TARGET_INCOMPLETE`, `TARGET_MISSING`, `PARTIAL_TARGET`, `MULTIPLE_TARGETS`,
|
||||||
|
`TARGET_MISMATCH`, `TARGET_UNKNOWN`, `TARGET_NOT_ALLOWED`, `TARGET_WRONG_LAYER`,
|
||||||
|
`CORRIDOR_CONFLICT`, `BACK_OCCUPIED`. The named `vip_suite` request returns
|
||||||
|
`PENDING_P10_01`; `vip_private_salon` is not an allowed substitute.
|
||||||
|
|
||||||
|
Any existing corridor cell conflicts. A proposed cut through a connected corridor
|
||||||
|
is rejected before mutation, preserving the route; no reroute or bypass is
|
||||||
|
invented. Accepted fixture cells were already nonwalkable and become occupied
|
||||||
|
under `special_peeping_room`. No special-room construction weight/cost is assumed.
|
||||||
|
|
||||||
|
Runtime demolition and FacilityService unregistration latch loss. Collection also
|
||||||
|
detects missing FRONT occupancy/identity. Rebuilding the same cells produces a
|
||||||
|
different construction ID and never silently reattaches rooms. Relink is explicit.
|
||||||
|
|
||||||
|
## CONTROLLED_FIXTURE boundary
|
||||||
|
|
||||||
|
Only service methods named `controlled_fixture_place`,
|
||||||
|
`controlled_fixture_set_stopped`, and `controlled_fixture_record_evidence` create
|
||||||
|
test rooms, enable fixture collection, or write evidence. They are labeled
|
||||||
|
CONTROLLED_FIXTURE in code and tests. They have no command/palette registration,
|
||||||
|
and no Runtime executor calls them. Test helpers disclose direct underground
|
||||||
|
geometry setup and MIMI registration; those do not assert natural unlock/join or
|
||||||
|
production eligibility. Target construction uses existing definitions/costs/times.
|
||||||
|
|
||||||
|
Room IDs come from the existing StableIdGenerator's `peeping_room` counter.
|
||||||
|
Evidence IDs encode the UTF-8 lengths and hex bytes of the full
|
||||||
|
`(room_id, target_instance_id, source_event_key)` tuple. This is injective rather
|
||||||
|
than delimiter concatenation or a hash with possible collisions. Replays return
|
||||||
|
the existing ID with `duplicated=true` and retain the first minute. Evidence is
|
||||||
|
only IDs, source key and minute. Room `target_history` retains prior bindings so
|
||||||
|
relink does not orphan existing opaque evidence.
|
||||||
|
|
||||||
|
## Save invariants
|
||||||
|
|
||||||
|
Runtime versions remain 14 and 15, with version 15 only for existing v2 purchase
|
||||||
|
history. Optional canonical StringName key `special_peeping_rooms` has section
|
||||||
|
version 1 and exact keys `version`, `rooms`, `evidence`. Empty service state emits
|
||||||
|
no key, preserving original snapshots. Absent sections restore empty only if no
|
||||||
|
world occupancy uses the special kind or `peeping_room.` prefix. Thus removing
|
||||||
|
the section from a current room-bearing save is rejected without a version bump.
|
||||||
|
|
||||||
|
Restore stages the entire section against staged world, path, facilities,
|
||||||
|
construction and ID generator before committing any Runtime state. It checks
|
||||||
|
canonical keys/types, version, duplicate room/evidence identities, deterministic
|
||||||
|
evidence tuple encoding, bounds/geometry, room/occupancy correspondence in both
|
||||||
|
directions, generator high-water mark, known historical facility IDs, present
|
||||||
|
target definition/geometry, loss/stopped coherence, and evidence room/history/time
|
||||||
|
references. Null/present-empty sections are invalid; absence is the only empty
|
||||||
|
encoding. Existing pending command/reference and schema migration checks remain.
|
||||||
|
|
||||||
|
SaveService validates a present section through the same staged service validator,
|
||||||
|
then supplies a shallow copy without this one key to the original purchase-format
|
||||||
|
allowlist. No other keys are removed. The original format 1 (Runtime 1–14),
|
||||||
|
format 2 (Runtime 15), manifest duplicate 15 and MIMI checks remain unchanged.
|
||||||
|
|
||||||
|
## Verification handoff
|
||||||
|
|
||||||
|
Five strict suites cover geometry/corridor, removal/relink, evidence/guards,
|
||||||
|
typed atomic save corruption and physical format 1, and Runtime commands plus
|
||||||
|
physical MIMI format 2. Tests use `var_to_bytes` for whole Runtime atomicity and
|
||||||
|
roundtrip checks. New marker rows carry final test source hashes; prior rows and
|
||||||
|
policy are unchanged. A helper under `tests/special/` is not a discovered suite.
|
||||||
|
|
||||||
|
`tools/run_p13_reference_tests.py` defaults to read-only verification of
|
||||||
|
`$BUILD_OUTPUT_DIR/p13-reference-native`, failing closed without an absolute
|
||||||
|
environment path. Explicit `--output --collect` is for Root only. The strict flag
|
||||||
|
parser rejects abbreviations, repeated flags, positional inputs and `=` aliases.
|
||||||
|
`--prepare-only` is non-native but was not executed by this worker.
|
||||||
|
|
||||||
|
The runner imports the existing P18 core by path. Since its three entry functions
|
||||||
|
hardcode their label and seven/nine counts, a bounded AST adapter changes only
|
||||||
|
protocol/runner identities, those explicit roster cardinalities, and diagnostic
|
||||||
|
labels. It checks the exact adaptation-site counts and fails closed on drift.
|
||||||
|
All confinement, inventory, JSON, sealing, source/engine/marker/policy binding,
|
||||||
|
process, diagnostic, profile and cleanup gates are reused. It neither copies the
|
||||||
|
whole runner nor modifies P18/helpers. The whole selected source map binds both
|
||||||
|
runner sources. Phase count derives from `len(ROSTER) + 2`.
|
||||||
|
|
||||||
|
Roster includes all five new suites and existing construction/world/path/runtime
|
||||||
|
construction, supply migration, transport save, Runtime weather, snapshot
|
||||||
|
serialization, save lifecycle and MIMI purchase suites. Receipts retain
|
||||||
|
`formal_acceptance=false` and `original_unit_complete=false`.
|
||||||
|
|
||||||
|
Root must perform serialized native collection with the allocation/private
|
||||||
|
profile, then registered `p13-reference` validation, a separate actual Opus
|
||||||
|
review, and the final exact-version required regression. Only those steps can
|
||||||
|
establish execution results.
|
||||||
|
|
||||||
|
## Still pending, without invented values
|
||||||
|
|
||||||
|
D04 build/upkeep/build minutes and other product numbers; recorder staffing and
|
||||||
|
natural triggers/rates D04/D08/P16; VIP suite P10-01; D05 transaction decisions
|
||||||
|
(no tick-phase changes here); P19 evidence use and P24 camera UI; normal palette
|
||||||
|
registration/construction/operation and natural production evidence; whole P13
|
||||||
|
acceptance, final review/integration, and applicable native Windows conditions.
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"actual_suites": 184,
|
|
||||||
"missing_marker_paths": [],
|
|
||||||
"remaining_unexecuted_tests": [],
|
|
||||||
"available_marker_checks": 21903,
|
|
||||||
"actual_all_roster_checks": 21903,
|
|
||||||
"strict_accepted_checks": 21903,
|
|
||||||
"verified": true,
|
|
||||||
"composed": true,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"whole_original_acceptance": false,
|
|
||||||
"parse_checks": 329,
|
|
||||||
"setup_phases": 2,
|
|
||||||
"owned_ended": 186,
|
|
||||||
"tested_source": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"engines_started": 0,
|
|
||||||
"verifier_sha256": "d00bf46bfcc0e0bb197edd284a3ae14610ca710507831e18e071a79461946e8a"
|
|
||||||
}
|
|
||||||
-73
@@ -1,73 +0,0 @@
|
|||||||
{
|
|
||||||
"controller_sha256": "d00bf46bfcc0e0bb197edd284a3ae14610ca710507831e18e071a79461946e8a",
|
|
||||||
"harness_sha256": "744177b243fb97ff7ad954880a433acf6a9b879c06d4ee51cfe02ed95be29422",
|
|
||||||
"cases": [
|
|
||||||
{
|
|
||||||
"case": "copytree string arguments create separate byte-exact support files",
|
|
||||||
"expected": "accept",
|
|
||||||
"actual": "accept"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "exact whole private-profile move and readback",
|
|
||||||
"expected": "accept",
|
|
||||||
"actual": "accept"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "absent empty startup profile explicitly retained",
|
|
||||||
"expected": "accept",
|
|
||||||
"actual": "accept"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject unowned profile name",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject valid nonce at wrong canonical location",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject changed original profile",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject undeclared profile member",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject profile symlink",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject existing retention destination",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "large profile lossless compression entire readback",
|
|
||||||
"expected": "accept",
|
|
||||||
"actual": "accept"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject compressed bytes changed",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject incomplete compressed member manifest",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "reject invalid archive hash",
|
|
||||||
"expected": "reject",
|
|
||||||
"actual": "reject"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"passed": true,
|
|
||||||
"native_engines_started": 0
|
|
||||||
}
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"passed": true,
|
|
||||||
"error": null,
|
|
||||||
"ended_unix_ns": 1792230973546897000,
|
|
||||||
"controller_sha256": "d00bf46bfcc0e0bb197edd284a3ae14610ca710507831e18e071a79461946e8a",
|
|
||||||
"owner_runner_pid": 92258,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"whole_original_acceptance": false
|
|
||||||
}
|
|
||||||
-80
@@ -1,80 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"original_import_and_parse_passed": 2,
|
|
||||||
"reusable_suites": 58,
|
|
||||||
"raw057_qualified_after_archival_recovery": true,
|
|
||||||
"original_owned_ended_pids": [
|
|
||||||
73903,
|
|
||||||
73987,
|
|
||||||
74026,
|
|
||||||
74052,
|
|
||||||
74079,
|
|
||||||
74092,
|
|
||||||
74125,
|
|
||||||
74151,
|
|
||||||
74171,
|
|
||||||
74194,
|
|
||||||
74212,
|
|
||||||
74236,
|
|
||||||
74256,
|
|
||||||
74284,
|
|
||||||
74327,
|
|
||||||
74632,
|
|
||||||
75319,
|
|
||||||
75331,
|
|
||||||
75368,
|
|
||||||
75392,
|
|
||||||
75429,
|
|
||||||
75453,
|
|
||||||
75466,
|
|
||||||
75555,
|
|
||||||
75577,
|
|
||||||
75603,
|
|
||||||
75619,
|
|
||||||
75654,
|
|
||||||
75687,
|
|
||||||
75932,
|
|
||||||
76254,
|
|
||||||
76409,
|
|
||||||
76434,
|
|
||||||
76455,
|
|
||||||
76480,
|
|
||||||
76487,
|
|
||||||
76566,
|
|
||||||
76851,
|
|
||||||
76898,
|
|
||||||
76931,
|
|
||||||
76945,
|
|
||||||
76973,
|
|
||||||
76989,
|
|
||||||
77012,
|
|
||||||
77035,
|
|
||||||
77087,
|
|
||||||
77108,
|
|
||||||
77120,
|
|
||||||
77143,
|
|
||||||
77158,
|
|
||||||
77179,
|
|
||||||
77206,
|
|
||||||
77240,
|
|
||||||
77253,
|
|
||||||
77277,
|
|
||||||
77297,
|
|
||||||
77325,
|
|
||||||
77340,
|
|
||||||
77364,
|
|
||||||
77382
|
|
||||||
],
|
|
||||||
"original_checks": 10991,
|
|
||||||
"remaining_suites": 126,
|
|
||||||
"engine_runs": 0,
|
|
||||||
"whole_original_acceptance": false,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"controller_sha256": "d00bf46bfcc0e0bb197edd284a3ae14610ca710507831e18e071a79461946e8a",
|
|
||||||
"free_bytes": 4484616192,
|
|
||||||
"admission_required_bytes": 3467374666,
|
|
||||||
"root_owner_pid": 92258,
|
|
||||||
"run_id": "52bfe67d08e54acd9478d74d5b030293",
|
|
||||||
"started_unix_ns": 1792229968318418000,
|
|
||||||
"original_input_sha256": "24d10b3a91553df54b3b2fd4b1a57dce683cc72a55576e0c73c9e142b335ad40"
|
|
||||||
}
|
|
||||||
-72
@@ -1,72 +0,0 @@
|
|||||||
{
|
|
||||||
"at_jst": "2026-10-17T18:59:44.626679+09:00",
|
|
||||||
"plan_id": "P13-02",
|
|
||||||
"batch": "P13-02-CODE1",
|
|
||||||
"S": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"original_packages": 30,
|
|
||||||
"original_units": 88,
|
|
||||||
"formally_completed": 14,
|
|
||||||
"new_credit": 0,
|
|
||||||
"normal_validation": "passed; exact S narrow15/863/329parse/17nativeended",
|
|
||||||
"actual_full": {
|
|
||||||
"actual_suites": 184,
|
|
||||||
"missing_marker_paths": [],
|
|
||||||
"remaining_unexecuted_tests": [],
|
|
||||||
"available_marker_checks": 21903,
|
|
||||||
"actual_all_roster_checks": 21903,
|
|
||||||
"strict_accepted_checks": 21903,
|
|
||||||
"verified": true,
|
|
||||||
"composed": true,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"whole_original_acceptance": false,
|
|
||||||
"parse_checks": 329,
|
|
||||||
"setup_phases": 2,
|
|
||||||
"owned_ended": 186,
|
|
||||||
"tested_source": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"engines_started": 0,
|
|
||||||
"verifier_sha256": "d00bf46bfcc0e0bb197edd284a3ae14610ca710507831e18e071a79461946e8a"
|
|
||||||
},
|
|
||||||
"formal_review": {
|
|
||||||
"state": "actual provider running",
|
|
||||||
"exec_session": 96001,
|
|
||||||
"run_id": "ead8e74b9683404d8cf3d97bca118726",
|
|
||||||
"pid": 17285,
|
|
||||||
"model": "claude-opus-5-5",
|
|
||||||
"frozen_checkout": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/P13-02-CODE1-review-e6fc1237",
|
|
||||||
"material_files": 16049
|
|
||||||
},
|
|
||||||
"normal_integration_candidate": null,
|
|
||||||
"source_on_main": false,
|
|
||||||
"remaining_conditions": [
|
|
||||||
"Actual separate whole CODE1 review must pass with no critical/high/medium finding",
|
|
||||||
"Normal exact latest-main integration candidate, input-equality qualification, final verification and ledger",
|
|
||||||
"Whole original P13-02 normal construction/recorder/natural triggers/approved quantities/VIP/UI/assets/Windows and all original conditions remain unaccepted"
|
|
||||||
],
|
|
||||||
"evidence": [
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_AGGREGATE_READONLY_VERIFICATION.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-full-composed-readonly-verification-a7e3069.json",
|
|
||||||
"bytes": 562,
|
|
||||||
"sha256": "3a8be9f92c76d14dc1c9f6d387fad8e939d0d333a6f8d5903b53b8fc44ef584b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_SUFFIX_INPUT.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-full-continuation-a7/controller-input.json",
|
|
||||||
"bytes": 1401,
|
|
||||||
"sha256": "81c3dcfdd092fde977c158482310f164a727a73dabea698e18807eeb585d4937"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_SUFFIX_ENDED.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-full-continuation-a7/controller-ended.json",
|
|
||||||
"bytes": 277,
|
|
||||||
"sha256": "b0759724f65175e01822b94ee731b3b9574c5098b82ce931e73e087fc5a89c65"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_CONTINUATION_CONTROLS.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-full-continuation-a7/CONTINUATION_STORAGE_CONTROLS.json",
|
|
||||||
"bytes": 1846,
|
|
||||||
"sha256": "96f47033ef95614426cb8646f7a4fbfedcb5af6bd95a0ab1e54a802d3eed77a6"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"next_formal_original_unit": "P04-01 pending existing real-owner D05 choices; no duplicate request or fabricated approval"
|
|
||||||
}
|
|
||||||
-10226
File diff suppressed because it is too large
Load Diff
-4945
File diff suppressed because it is too large
Load Diff
-209
@@ -1,209 +0,0 @@
|
|||||||
{
|
|
||||||
"scripts/special/peeping_room_service.gd.uid": {
|
|
||||||
"owner": "scripts/special/peeping_room_service.gd",
|
|
||||||
"owner_sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531",
|
|
||||||
"file_type": "regular",
|
|
||||||
"bytes": 20,
|
|
||||||
"raw_bytes": [
|
|
||||||
117,
|
|
||||||
105,
|
|
||||||
100,
|
|
||||||
58,
|
|
||||||
47,
|
|
||||||
47,
|
|
||||||
98,
|
|
||||||
105,
|
|
||||||
51,
|
|
||||||
54,
|
|
||||||
102,
|
|
||||||
118,
|
|
||||||
112,
|
|
||||||
49,
|
|
||||||
106,
|
|
||||||
105,
|
|
||||||
105,
|
|
||||||
105,
|
|
||||||
118,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"sha256": "3f045afc3c140886c70ec8494d6dcb012e6da645e8a3ff3c6488442ce63a9353",
|
|
||||||
"text": "uid://bi36fvp1jiiiv\n"
|
|
||||||
},
|
|
||||||
"tests/special/peeping_room_fixture.gd.uid": {
|
|
||||||
"owner": "tests/special/peeping_room_fixture.gd",
|
|
||||||
"owner_sha256": "0243b1d35e1fdd8aa085894a0ce1e5cd1a189e5c98fcb859f81b70ae75b98bed",
|
|
||||||
"file_type": "regular",
|
|
||||||
"bytes": 20,
|
|
||||||
"raw_bytes": [
|
|
||||||
117,
|
|
||||||
105,
|
|
||||||
100,
|
|
||||||
58,
|
|
||||||
47,
|
|
||||||
47,
|
|
||||||
98,
|
|
||||||
48,
|
|
||||||
99,
|
|
||||||
51,
|
|
||||||
111,
|
|
||||||
117,
|
|
||||||
117,
|
|
||||||
113,
|
|
||||||
52,
|
|
||||||
50,
|
|
||||||
121,
|
|
||||||
99,
|
|
||||||
103,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"sha256": "a74e5ef6d8959826919a648e8b5d82e96d1c73ff22cd6c1f216be8b5c4060a8a",
|
|
||||||
"text": "uid://b0c3ouuq42ycg\n"
|
|
||||||
},
|
|
||||||
"tests/special/test_peeping_room_evidence.gd.uid": {
|
|
||||||
"owner": "tests/special/test_peeping_room_evidence.gd",
|
|
||||||
"owner_sha256": "390e0032d14de9a8875ced163a922341ce655744200d78b4ffa776d42c4f8c2a",
|
|
||||||
"file_type": "regular",
|
|
||||||
"bytes": 20,
|
|
||||||
"raw_bytes": [
|
|
||||||
117,
|
|
||||||
105,
|
|
||||||
100,
|
|
||||||
58,
|
|
||||||
47,
|
|
||||||
47,
|
|
||||||
100,
|
|
||||||
102,
|
|
||||||
116,
|
|
||||||
115,
|
|
||||||
107,
|
|
||||||
121,
|
|
||||||
49,
|
|
||||||
51,
|
|
||||||
112,
|
|
||||||
101,
|
|
||||||
48,
|
|
||||||
117,
|
|
||||||
106,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"sha256": "26bbc1435bcda963b5866327b887096f798b1629c7984768c85bfb6175648ec5",
|
|
||||||
"text": "uid://dftsky13pe0uj\n"
|
|
||||||
},
|
|
||||||
"tests/special/test_peeping_room_geometry.gd.uid": {
|
|
||||||
"owner": "tests/special/test_peeping_room_geometry.gd",
|
|
||||||
"owner_sha256": "103d85f83e1e97a8637892504264275eef23f172eeec56c94e5c022d81bf6945",
|
|
||||||
"file_type": "regular",
|
|
||||||
"bytes": 19,
|
|
||||||
"raw_bytes": [
|
|
||||||
117,
|
|
||||||
105,
|
|
||||||
100,
|
|
||||||
58,
|
|
||||||
47,
|
|
||||||
47,
|
|
||||||
52,
|
|
||||||
114,
|
|
||||||
52,
|
|
||||||
48,
|
|
||||||
102,
|
|
||||||
49,
|
|
||||||
107,
|
|
||||||
112,
|
|
||||||
106,
|
|
||||||
109,
|
|
||||||
118,
|
|
||||||
106,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"sha256": "391b78806bc0bf759f00c778cb25dfaa97d47f6e309c3b302412c38123c5440c",
|
|
||||||
"text": "uid://4r40f1kpjmvj\n"
|
|
||||||
},
|
|
||||||
"tests/special/test_peeping_room_reference.gd.uid": {
|
|
||||||
"owner": "tests/special/test_peeping_room_reference.gd",
|
|
||||||
"owner_sha256": "188b00a60f7aefda69dc4973f1de9c14447a0d4bcdd1257a2eabe7c4782e4caf",
|
|
||||||
"file_type": "regular",
|
|
||||||
"bytes": 20,
|
|
||||||
"raw_bytes": [
|
|
||||||
117,
|
|
||||||
105,
|
|
||||||
100,
|
|
||||||
58,
|
|
||||||
47,
|
|
||||||
47,
|
|
||||||
99,
|
|
||||||
110,
|
|
||||||
110,
|
|
||||||
111,
|
|
||||||
110,
|
|
||||||
53,
|
|
||||||
119,
|
|
||||||
111,
|
|
||||||
117,
|
|
||||||
102,
|
|
||||||
117,
|
|
||||||
114,
|
|
||||||
112,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"sha256": "db8bfa98b7943dba15858ccaa6681bc430efd43f40f57de99117dc19c51ac417",
|
|
||||||
"text": "uid://cnnon5woufurp\n"
|
|
||||||
},
|
|
||||||
"tests/special/test_peeping_room_runtime.gd.uid": {
|
|
||||||
"owner": "tests/special/test_peeping_room_runtime.gd",
|
|
||||||
"owner_sha256": "924efd34414c12a325a1b700f799aef0396de9f15441fd88a3608292ff221657",
|
|
||||||
"file_type": "regular",
|
|
||||||
"bytes": 19,
|
|
||||||
"raw_bytes": [
|
|
||||||
117,
|
|
||||||
105,
|
|
||||||
100,
|
|
||||||
58,
|
|
||||||
47,
|
|
||||||
47,
|
|
||||||
52,
|
|
||||||
110,
|
|
||||||
53,
|
|
||||||
119,
|
|
||||||
101,
|
|
||||||
108,
|
|
||||||
113,
|
|
||||||
102,
|
|
||||||
104,
|
|
||||||
100,
|
|
||||||
113,
|
|
||||||
103,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"sha256": "b742bb8e4077f111e0f7b4d9039261a06fe6deaad8ea308ba3b89c7b5a4a9069",
|
|
||||||
"text": "uid://4n5welqfhdqg\n"
|
|
||||||
},
|
|
||||||
"tests/special/test_peeping_room_save.gd.uid": {
|
|
||||||
"owner": "tests/special/test_peeping_room_save.gd",
|
|
||||||
"owner_sha256": "ba0e7644277477c1821135cae6d6fd533651799c6f9bd8c43ccf45e63b96c63c",
|
|
||||||
"file_type": "regular",
|
|
||||||
"bytes": 19,
|
|
||||||
"raw_bytes": [
|
|
||||||
117,
|
|
||||||
105,
|
|
||||||
100,
|
|
||||||
58,
|
|
||||||
47,
|
|
||||||
47,
|
|
||||||
56,
|
|
||||||
117,
|
|
||||||
121,
|
|
||||||
116,
|
|
||||||
109,
|
|
||||||
112,
|
|
||||||
106,
|
|
||||||
117,
|
|
||||||
112,
|
|
||||||
56,
|
|
||||||
113,
|
|
||||||
52,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"sha256": "005561b37df9051e618d4714b2a91a82f4a48ec63c841cdf27c251bcd2865505",
|
|
||||||
"text": "uid://8uytmpjup8q4\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"S": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"argv": [
|
|
||||||
"/Users/korizatou114/Antigravity/\u74b0\u5883\u69cb\u7bc9/agent-control/.venv/bin/python",
|
|
||||||
"-B",
|
|
||||||
"tests/special/test_p13_uid_policy.py"
|
|
||||||
],
|
|
||||||
"started_unix_ns": 1792225317277353000,
|
|
||||||
"ended_unix_ns": 1792225317417668000,
|
|
||||||
"exit_code": 0,
|
|
||||||
"stdout_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
||||||
"stderr_sha256": "c8904f75939074499eaa0d8a5add9f1fd5007a4e4e5e75cc9b1ce324d8f4b69c"
|
|
||||||
}
|
|
||||||
-5
@@ -1,5 +0,0 @@
|
|||||||
.......
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
Ran 7 tests in 0.053s
|
|
||||||
|
|
||||||
OK
|
|
||||||
-88
@@ -1,88 +0,0 @@
|
|||||||
{
|
|
||||||
"at_jst": "2026-10-17T17:28:02.473746+09:00",
|
|
||||||
"plan_id": "P13-02",
|
|
||||||
"batch": "P13-02-CODE1",
|
|
||||||
"original_packages": 30,
|
|
||||||
"original_units": 88,
|
|
||||||
"formally_completed": 14,
|
|
||||||
"new_credit": 0,
|
|
||||||
"S": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"source_backup_branch": "codex/p13-02-reference",
|
|
||||||
"source_on_main": false,
|
|
||||||
"normal_integration_candidate": null,
|
|
||||||
"runner_state_after_registered_validation": "review_pending",
|
|
||||||
"repairs": 4,
|
|
||||||
"max_repairs": null,
|
|
||||||
"implementation_models": "Astra selected by Opus for coupled save schema; Sol selected by Opus for UID policy and exact queue-event oracle corrections",
|
|
||||||
"actual_narrow": {
|
|
||||||
"suites": 15,
|
|
||||||
"checks": 863,
|
|
||||||
"parse_files": 329,
|
|
||||||
"phases": 17,
|
|
||||||
"actual_PIDs": [
|
|
||||||
63523,
|
|
||||||
63619,
|
|
||||||
63653,
|
|
||||||
63684,
|
|
||||||
63709,
|
|
||||||
63723,
|
|
||||||
63751,
|
|
||||||
63773,
|
|
||||||
63789,
|
|
||||||
63815,
|
|
||||||
63830,
|
|
||||||
63854,
|
|
||||||
63870,
|
|
||||||
63896,
|
|
||||||
63919,
|
|
||||||
63933,
|
|
||||||
63993
|
|
||||||
],
|
|
||||||
"passed": true,
|
|
||||||
"all_owned_engines_ended": true,
|
|
||||||
"guard_errors": [],
|
|
||||||
"cleanup_errors": [],
|
|
||||||
"finite_UID_set": 7,
|
|
||||||
"game_body_changed_by_latest_fix": false
|
|
||||||
},
|
|
||||||
"test_oracle_correction": "Direct rejected placement full typed Runtime unchanged; queued placement keeps world/economy/room/non-event IDs unchanged and verifies exactly1 COMMAND_FAILED domain-event ID/cause receipt. No blanket normalization or event suppression.",
|
|
||||||
"current_next_gate": "Full standard regression with finite native UID metadata extension must preserve all standard generated-report/audio/diagnostic/process/profile/source/marker gates; actual Opus plan requested before collection, formal independent review then ordinary integration/final remain.",
|
|
||||||
"whole_original_unit": "not accepted; pending ordinary construction/recorder/natural collection triggers/approved values/VIP/UI/content/Windows and all P13 conditions unchanged",
|
|
||||||
"P04_priority": "Next formal closure P04-01, existing D05 questions pending, no repeated questions or fake approval",
|
|
||||||
"previous_failures_retained": [
|
|
||||||
"p13-reference-native-e930a1d-import-failed",
|
|
||||||
"p13-reference-native-uid-corrected-27fc5f0-runtime-failed"
|
|
||||||
],
|
|
||||||
"evidence": [
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_NATIVE_ENDED.json",
|
|
||||||
"actual_original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native-uid-corrected/runner-ended.json",
|
|
||||||
"bytes": 469751,
|
|
||||||
"sha256": "4694cc13c0e0c309adf1f5c3c3885fc2d54efa8dc8ec63319ce016e48d2d66a5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_NATIVE_INPUT.json",
|
|
||||||
"actual_original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native-uid-corrected/runner-input.json",
|
|
||||||
"bytes": 320481,
|
|
||||||
"sha256": "c899b3463fdc8925a98f5dd288eea5cca1d41b3591bc17d29394ec90da0b1094"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_RETAINED_UIDS.json",
|
|
||||||
"actual_original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native-uid-corrected/accepted-uids.json",
|
|
||||||
"bytes": 4198,
|
|
||||||
"sha256": "6a6987d53b93387aaa0f8cae268c96eb4bf326fa4599eea4e837af00384e3c38"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_STATIC_UID_CONTROLS.json",
|
|
||||||
"actual_original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/audit-support/p13-root-native-a7e3069/static-uid-controls.json",
|
|
||||||
"bytes": 493,
|
|
||||||
"sha256": "d9f4acac3e7f0ed869ece76bc5ef3e9dbe96314e893f1d7a2081a39d97b66053"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_STATIC_UID_STDERR.log",
|
|
||||||
"actual_original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/audit-support/p13-root-native-a7e3069/static-uid-controls.stderr.log",
|
|
||||||
"bytes": 105,
|
|
||||||
"sha256": "c8904f75939074499eaa0d8a5add9f1fd5007a4e4e5e75cc9b1ce324d8f4b69c"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
-252
@@ -1,252 +0,0 @@
|
|||||||
{
|
|
||||||
"phase": "import",
|
|
||||||
"test": null,
|
|
||||||
"passed": false,
|
|
||||||
"failed": true,
|
|
||||||
"validation_error": null,
|
|
||||||
"profile_startup_name": "TheTree-PCK-tests-974717b708984f0d81f24d8164fe7bc3-standard-startup-import",
|
|
||||||
"private_project_sha256": "f825875e910e090ce57fc0527f34b55386a77123c1784d6916718113139a3673",
|
|
||||||
"private_project_fields": 2,
|
|
||||||
"source_sha256": null,
|
|
||||||
"command": [
|
|
||||||
"/Applications/Godot.app/Contents/MacOS/Godot",
|
|
||||||
"--headless",
|
|
||||||
"--path",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/stage",
|
|
||||||
"--editor",
|
|
||||||
"--import",
|
|
||||||
"--quit",
|
|
||||||
"--verbose",
|
|
||||||
"--log-file",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log"
|
|
||||||
],
|
|
||||||
"logical_script": null,
|
|
||||||
"starter_sha256": null,
|
|
||||||
"controlled_environment": {},
|
|
||||||
"native_process": {
|
|
||||||
"argv": [
|
|
||||||
"/Applications/Godot.app/Contents/MacOS/Godot",
|
|
||||||
"--headless",
|
|
||||||
"--path",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/stage",
|
|
||||||
"--editor",
|
|
||||||
"--import",
|
|
||||||
"--quit",
|
|
||||||
"--verbose",
|
|
||||||
"--log-file",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log"
|
|
||||||
],
|
|
||||||
"pid": 55035,
|
|
||||||
"started_utc": "2026-10-17T08:05:39.153436+00:00",
|
|
||||||
"ended_utc": "2026-10-17T08:05:54.328314+00:00",
|
|
||||||
"wall_seconds": 15.174453041981906,
|
|
||||||
"exit_code": 0,
|
|
||||||
"helper_exit_code": 0,
|
|
||||||
"timed_out": false,
|
|
||||||
"stdout_sha256": "a7044e250290690749e344039a98595963550e89777a727da0532dd975c95778",
|
|
||||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
||||||
"error_lines": [],
|
|
||||||
"owned_popen_ended": true,
|
|
||||||
"old_helper_engine_ended": true,
|
|
||||||
"start_receipt_written": true,
|
|
||||||
"end_receipt_written": true,
|
|
||||||
"lifecycle_error": null,
|
|
||||||
"old_helper_lifecycle_error": null,
|
|
||||||
"actual_start_binding": {
|
|
||||||
"scope": "isolated diagnostic owned child",
|
|
||||||
"event": "ENGINE_STARTED",
|
|
||||||
"actual_pid": 55035,
|
|
||||||
"owner_pid": 53623,
|
|
||||||
"command": [
|
|
||||||
"/Applications/Godot.app/Contents/MacOS/Godot",
|
|
||||||
"--headless",
|
|
||||||
"--path",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/stage",
|
|
||||||
"--editor",
|
|
||||||
"--import",
|
|
||||||
"--quit",
|
|
||||||
"--verbose",
|
|
||||||
"--log-file",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log"
|
|
||||||
],
|
|
||||||
"monotonic_ns": 2836045348628125,
|
|
||||||
"pid": 55035,
|
|
||||||
"argv": [
|
|
||||||
"/Applications/Godot.app/Contents/MacOS/Godot",
|
|
||||||
"--headless",
|
|
||||||
"--path",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/stage",
|
|
||||||
"--editor",
|
|
||||||
"--import",
|
|
||||||
"--quit",
|
|
||||||
"--verbose",
|
|
||||||
"--log-file",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log"
|
|
||||||
],
|
|
||||||
"started_utc": "2026-10-17T08:05:39.153436+00:00",
|
|
||||||
"current_process_identity": {
|
|
||||||
"pid": 55035,
|
|
||||||
"ppid": 53623,
|
|
||||||
"pgid": 55035,
|
|
||||||
"args": "/Applications/Godot.app/Contents/MacOS/Godot --headless --path /Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/stage --editor --import --quit --verbose --log-file /Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log"
|
|
||||||
},
|
|
||||||
"live_identity_exact": true,
|
|
||||||
"tracked_child_ended_before_initial_probe": false,
|
|
||||||
"signal_scope": "tracked Popen child only; no external group signal"
|
|
||||||
},
|
|
||||||
"actual_end_binding": {
|
|
||||||
"scope": "isolated diagnostic owned child",
|
|
||||||
"event": "ENGINE_ENDED",
|
|
||||||
"actual_pid": 55035,
|
|
||||||
"owner_pid": 53623,
|
|
||||||
"command": [
|
|
||||||
"/Applications/Godot.app/Contents/MacOS/Godot",
|
|
||||||
"--headless",
|
|
||||||
"--path",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/stage",
|
|
||||||
"--editor",
|
|
||||||
"--import",
|
|
||||||
"--quit",
|
|
||||||
"--verbose",
|
|
||||||
"--log-file",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log"
|
|
||||||
],
|
|
||||||
"monotonic_ns": 2836060496050750,
|
|
||||||
"exit_code": 0,
|
|
||||||
"actual_process_exit_code": 0,
|
|
||||||
"engine_ended": true,
|
|
||||||
"timed_out": false,
|
|
||||||
"lifecycle_error": null,
|
|
||||||
"start_receipt_written": true,
|
|
||||||
"pid": 55035,
|
|
||||||
"argv": [
|
|
||||||
"/Applications/Godot.app/Contents/MacOS/Godot",
|
|
||||||
"--headless",
|
|
||||||
"--path",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/stage",
|
|
||||||
"--editor",
|
|
||||||
"--import",
|
|
||||||
"--quit",
|
|
||||||
"--verbose",
|
|
||||||
"--log-file",
|
|
||||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log"
|
|
||||||
],
|
|
||||||
"ended_utc": "2026-10-17T08:05:54.320361+00:00",
|
|
||||||
"signal_scope": "tracked Popen child only; no external group signal"
|
|
||||||
},
|
|
||||||
"strict_native_diagnostics": {
|
|
||||||
"errors": [],
|
|
||||||
"banner_count": 1,
|
|
||||||
"known_unicode_diagnostic_count": 0,
|
|
||||||
"unrecognized_unicode_diagnostic_count": 0,
|
|
||||||
"exit_leak_diagnostic_lines": []
|
|
||||||
},
|
|
||||||
"external_process_or_group_signals": 0,
|
|
||||||
"owned_child_process_helper_sha256": "c007e712c281573254faa1233c2ac92e100ab87393256a6dc096b35283e43037",
|
|
||||||
"adapter_owned_cleanup": {
|
|
||||||
"owned_child_created": true,
|
|
||||||
"engine_ended": true,
|
|
||||||
"actual_process_exit_code": 0,
|
|
||||||
"attempts": [
|
|
||||||
{
|
|
||||||
"attempt": 1,
|
|
||||||
"kill_attempted": false,
|
|
||||||
"wait_timeout_seconds": 5,
|
|
||||||
"wait_completed": true,
|
|
||||||
"errors": [],
|
|
||||||
"poll_before": 0,
|
|
||||||
"wait_returned_code": 0,
|
|
||||||
"poll_after": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"errors": []
|
|
||||||
},
|
|
||||||
"adapter_error": null,
|
|
||||||
"old_helper_bytes_preserved": true,
|
|
||||||
"helper_wait_None_maps_to_actual_timeout_seconds": 5,
|
|
||||||
"explicit_helper_wait_timeouts_preserved": true,
|
|
||||||
"additional_cleanup_wait_timeout_seconds": 5,
|
|
||||||
"additional_cleanup_max_attempts": 3
|
|
||||||
},
|
|
||||||
"outer_actual_capture": {
|
|
||||||
"actual_captured_pids": [
|
|
||||||
55035
|
|
||||||
],
|
|
||||||
"cleanup": [
|
|
||||||
{
|
|
||||||
"pid": 55035,
|
|
||||||
"cleanup": {
|
|
||||||
"owned_child_created": true,
|
|
||||||
"engine_ended": true,
|
|
||||||
"actual_process_exit_code": 0,
|
|
||||||
"attempts": [
|
|
||||||
{
|
|
||||||
"attempt": 1,
|
|
||||||
"kill_attempted": false,
|
|
||||||
"wait_timeout_seconds": 5,
|
|
||||||
"wait_completed": true,
|
|
||||||
"errors": [],
|
|
||||||
"poll_before": 0,
|
|
||||||
"wait_returned_code": 0,
|
|
||||||
"poll_after": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"errors": []
|
|
||||||
},
|
|
||||||
"outer_cleanup_errors": [],
|
|
||||||
"engine_ended": true,
|
|
||||||
"outer_maximum_helper_invocations": 3,
|
|
||||||
"helper_maximum_waits": 3,
|
|
||||||
"per_wait_timeout_seconds": 5,
|
|
||||||
"foreign_process_or_group_signals": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"adapter_exception": null,
|
|
||||||
"all_captured_ended": true,
|
|
||||||
"outer_cleanup_errors": [],
|
|
||||||
"foreign_process_or_group_signals": 0,
|
|
||||||
"all_cleanup_before_outer_receipt": true,
|
|
||||||
"outer_receipt_written": true,
|
|
||||||
"outer_receipt_error": null,
|
|
||||||
"passed": true
|
|
||||||
},
|
|
||||||
"actual_pid": 55035,
|
|
||||||
"engine_ended": true,
|
|
||||||
"exit_code": 0,
|
|
||||||
"log": "import/combined-raw.log",
|
|
||||||
"log_sha256": "a7044e250290690749e344039a98595963550e89777a727da0532dd975c95778",
|
|
||||||
"raw_native_log": {
|
|
||||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import/engine-native.log",
|
|
||||||
"bytes": 119669,
|
|
||||||
"sha256": "9e66d1295be17e1bfa9052e78e06e7cf9bfee7fe5624ea97226529209404b8ed"
|
|
||||||
},
|
|
||||||
"finite_original_diagnostic_review": {
|
|
||||||
"verified": true,
|
|
||||||
"original_NUL_fixture_contract_applied": false,
|
|
||||||
"producer_source_sha256": null,
|
|
||||||
"actual_transport_counts": {
|
|
||||||
"stdout": 0,
|
|
||||||
"stderr": 0,
|
|
||||||
"native_file": 0
|
|
||||||
},
|
|
||||||
"actual_complete_diagnostic_sequences": {
|
|
||||||
"stdout": [],
|
|
||||||
"stderr": [],
|
|
||||||
"native_file": []
|
|
||||||
},
|
|
||||||
"unknown_or_error_or_leak_lines": {
|
|
||||||
"stdout": [],
|
|
||||||
"stderr": [],
|
|
||||||
"native_file": []
|
|
||||||
},
|
|
||||||
"raw_lines_deleted_or_rewritten": 0,
|
|
||||||
"contract_sha256": "22fd41c59eb13e0af397984bed418870c55fa8942524c377490a90a2aca8dedd",
|
|
||||||
"allowed_e31_error_lines": []
|
|
||||||
},
|
|
||||||
"whole_startup_profile_after": {
|
|
||||||
"path": "/Users/korizatou114/Library/Application Support/TheTree-PCK-tests-974717b708984f0d81f24d8164fe7bc3-standard-startup-import",
|
|
||||||
"files": {},
|
|
||||||
"fresh_before_engine": true
|
|
||||||
},
|
|
||||||
"guard_error": "AssertionError: complete source/UID/generated report set"
|
|
||||||
}
|
|
||||||
-3868
File diff suppressed because it is too large
Load Diff
-4944
File diff suppressed because it is too large
Load Diff
-7
File diff suppressed because one or more lines are too long
-10
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"task_id": "P13-02-CODE1",
|
|
||||||
"commit": "1e8d4ea88876865a72547ff0edf43ed5b0e74c7e",
|
|
||||||
"status": "submitted",
|
|
||||||
"summary": "許可範囲内で非描写サービス、Runtime・保存連携、5試験、専用検証スクリプト、マーカー・説明書を追加。Python構文とマーカーSHA整合を確認。エンジン・試験・Runner操作・git書込みは未実施。正式検証と独立レビュー待ちで、P13受入への加算はありません。",
|
|
||||||
"acceptance_ids": [
|
|
||||||
"P13-02-CODE1"
|
|
||||||
],
|
|
||||||
"findings": []
|
|
||||||
}
|
|
||||||
-85
@@ -1,85 +0,0 @@
|
|||||||
{
|
|
||||||
"at_jst": "2026-10-17T17:09:16.053627+09:00",
|
|
||||||
"plan_id": "P13-02",
|
|
||||||
"batch": "P13-02-CODE1",
|
|
||||||
"original_packages": 30,
|
|
||||||
"original_units": 88,
|
|
||||||
"formally_completed": 14,
|
|
||||||
"new_credit": 0,
|
|
||||||
"source_submitted": "e930a1dedff7ab4c4a94d274a2e0c55fc2b95829",
|
|
||||||
"source_backup_branch": "codex/p13-02-reference-e930a1d",
|
|
||||||
"normal_integration_candidate": null,
|
|
||||||
"source_on_main": false,
|
|
||||||
"worker_model": "gpt-6-astra",
|
|
||||||
"model_selection": "actual Opus19f00667 after examining coupled14/15 save paths; earlier Sol was proposal only",
|
|
||||||
"repairs_before_current_correction": 2,
|
|
||||||
"max_repairs": null,
|
|
||||||
"worker_run": "b3af838ff79b4f3fafe7b68040a89079",
|
|
||||||
"worker_terminal": "submitted",
|
|
||||||
"source_change_summary": "12 files/1015 additions, service plus bounded Runtime/save/5suite/harness wiring; no mandatory numbers or normal palette invented",
|
|
||||||
"native": {
|
|
||||||
"import_actual_pid": 55035,
|
|
||||||
"engine_ended": true,
|
|
||||||
"exit_code": 0,
|
|
||||||
"diagnostic_errors": 0,
|
|
||||||
"accepted": false,
|
|
||||||
"guard_failure": "exactly7 native-generated UID sidecars undeclared in complete source/UID/generated set",
|
|
||||||
"suite_count": 0,
|
|
||||||
"all15_suites_unexecuted": true,
|
|
||||||
"all329_parse_unexecuted": true,
|
|
||||||
"default_player_changed": false,
|
|
||||||
"cleanup_errors": []
|
|
||||||
},
|
|
||||||
"next": "actual Opus decision for precise UID artifact handling; do not waive source/UID/process/profile guard or rerun full regression now",
|
|
||||||
"P04_priority": "Next original unit to close remains P04-01; owner D05 answers pending, this batch is independent work",
|
|
||||||
"required_remaining": [
|
|
||||||
"UID correction then exact narrow/impact verification with strict raw evidence",
|
|
||||||
"separate actual Opus independent code/evidence review",
|
|
||||||
"required final exact-source full regression, normal integration/final and ledger update for backend batch",
|
|
||||||
"whole original P13-02 normal build/production/content/roles/approved D04/D05/D08 values/VIP/UI/Windows and all original conditions remain unaccepted"
|
|
||||||
],
|
|
||||||
"manifest": [
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_OPUS_MODEL_AND_BRIEF.json",
|
|
||||||
"original": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p13-02-reference/runs/19f00667226d42dd8e9b3a4ae99aaa68/result.json",
|
|
||||||
"sha256": "1afa4b721f45c10cabeb10830db1c8b064d29c55000c3c6fbf5802ec0474c533",
|
|
||||||
"bytes": 11457
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_WORKER_RESULT.json",
|
|
||||||
"original": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p13-02-reference/runs/b3af838ff79b4f3fafe7b68040a89079/result.json",
|
|
||||||
"sha256": "e38129543ab8796c51b6f1c56fba7417a6f7efe8d4cff338d1a0b074bbf23dd1",
|
|
||||||
"bytes": 538
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_IMPORT_RECEIPT.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/import-receipt.json",
|
|
||||||
"sha256": "cfa6b72b59f8df394eb22adfe1e73babbca31fb0c2a9caed9190dcc80b52d8f1",
|
|
||||||
"bytes": 9333
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_NATIVE_ENDED.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/runner-ended.json",
|
|
||||||
"sha256": "9f13934d7844e4ceba72e87a7c5dc88e7e2ebdea5de1c556c5f19d90092917c3",
|
|
||||||
"bytes": 167969
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ACTUAL_NATIVE_INPUT.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-reference-native/runner-input.json",
|
|
||||||
"sha256": "6018a3d83835317a46aee69188d5f3ca0e01977212e36b030a751894cb3284dc",
|
|
||||||
"bytes": 320355
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "ROOT_REVIEW_CHECKLIST.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/coordinator-start-20261017/ROOT_REVIEW_CHECKLIST.json",
|
|
||||||
"sha256": "32079bede7a4da3defabbdc4fca7eaf96a03ffc12344cfd7631c2d5c5e22e7c7",
|
|
||||||
"bytes": 1440
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "EXACT_FAILURE_FACTS.json",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/P13-02-CODE1-implement/build/owner-handoff/native-import-failure/ROOT_EXACT_FAILURE_FACTS.json",
|
|
||||||
"sha256": "a7c906d0df05003be005e8d7160ae8c104dbdb00388bd57b87696f1dd425de86",
|
|
||||||
"bytes": 1782
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
-54
@@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
"S": "e930a1dedff7ab4c4a94d274a2e0c55fc2b95829",
|
|
||||||
"actual_engine_pid": 55035,
|
|
||||||
"exit_code": 0,
|
|
||||||
"owned_engine_ended": true,
|
|
||||||
"diagnostic_errors": 0,
|
|
||||||
"actual_suites": 0,
|
|
||||||
"new_stage_files": [
|
|
||||||
{
|
|
||||||
"path": "tests/special/peeping_room_fixture.gd.uid",
|
|
||||||
"sha256": "a74e5ef6d8959826919a648e8b5d82e96d1c73ff22cd6c1f216be8b5c4060a8a",
|
|
||||||
"bytes": 20,
|
|
||||||
"text": "uid://b0c3ouuq42ycg\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "tests/special/test_peeping_room_runtime.gd.uid",
|
|
||||||
"sha256": "f7276000bd3b4c3429c72612f791ca2ed6bb04dde1de8e278cb1a055ae4ce743",
|
|
||||||
"bytes": 20,
|
|
||||||
"text": "uid://dkc1kiqioypih\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "tests/special/test_peeping_room_save.gd.uid",
|
|
||||||
"sha256": "005561b37df9051e618d4714b2a91a82f4a48ec63c841cdf27c251bcd2865505",
|
|
||||||
"bytes": 19,
|
|
||||||
"text": "uid://8uytmpjup8q4\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "tests/special/test_peeping_room_geometry.gd.uid",
|
|
||||||
"sha256": "391b78806bc0bf759f00c778cb25dfaa97d47f6e309c3b302412c38123c5440c",
|
|
||||||
"bytes": 19,
|
|
||||||
"text": "uid://4r40f1kpjmvj\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "tests/special/test_peeping_room_evidence.gd.uid",
|
|
||||||
"sha256": "26bbc1435bcda963b5866327b887096f798b1629c7984768c85bfb6175648ec5",
|
|
||||||
"bytes": 20,
|
|
||||||
"text": "uid://dftsky13pe0uj\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "tests/special/test_peeping_room_reference.gd.uid",
|
|
||||||
"sha256": "db8bfa98b7943dba15858ccaa6681bc430efd43f40f57de99117dc19c51ac417",
|
|
||||||
"bytes": 20,
|
|
||||||
"text": "uid://cnnon5woufurp\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "scripts/special/peeping_room_service.gd.uid",
|
|
||||||
"sha256": "3f045afc3c140886c70ec8494d6dcb012e6da645e8a3ff3c6488442ce63a9353",
|
|
||||||
"bytes": 20,
|
|
||||||
"text": "uid://bi36fvp1jiiiv\n"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"guards_not_waived": true,
|
|
||||||
"whole_acceptance": false
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"scope": "Root-derived review checklist within the immutable original P13-02 state/reference/save conditions. Not extra product rules, test results, or implementation directions.",
|
|
||||||
"created_unix_ns": 1792223589246621000,
|
|
||||||
"checks": [
|
|
||||||
"Retain prior evidence identities/history after target loss and explicit relink; a new target does not turn old evidence into a different event or silently discard it. Check roundtrip after this combined history.",
|
|
||||||
"Relink may ignore only the same room own occupancy, never another room or corridor conflict. A rebuilt different facility ID cannot silently revive the link.",
|
|
||||||
"Ordinary production commands cannot reach CONTROLLED_FIXTURE entry points or bypass missing build/recorder approvals; rejection leaves whole typed Runtime unchanged.",
|
|
||||||
"Optional section absence is valid only for truly empty state; orphan world occupancy or owned IDs cannot be accepted by dropping the section. Other existing exact schema key allowlists remain strict.",
|
|
||||||
"Failed section restore or later-system failure restores original whole Runtime including clock, ID generator, commands, facilities, ledger and new service references; var_to_bytes evidence, no JSON normalization.",
|
|
||||||
"Source/marker/policy/engine/input/environment identities and actual owned process endings cover the final tested version; local test numbers never substitute whole-unit acceptance."
|
|
||||||
],
|
|
||||||
"formal_credit": 0
|
|
||||||
}
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"archive_sha256": "f962d3622f5da562c3c07c4afed84bf4f1042a2470f555c16148d450e70453ff",
|
|
||||||
"drive_archive_id": "1F6MYrZ7begmlNaZkjMOlJT5y9uMcSVwM",
|
|
||||||
"drive_restore_kit_id": "1eT98KWt71v62IGhxyBSjmf4FEoTvFMxA",
|
|
||||||
"views": [
|
|
||||||
{
|
|
||||||
"original": "/Users/korizatou114/Library/Application Support/TheTree-PCK-tests-cb0e908014ed4be48b1cc74787337f66-standard-runtime-057",
|
|
||||||
"files": 2792,
|
|
||||||
"logical_bytes": 1839108706,
|
|
||||||
"verified_all_bytes_before_retirement": true,
|
|
||||||
"restore_view": "original",
|
|
||||||
"absent_after": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/P13-02-CODE1/build/p13-full-controller/run/profiles/057/runtime",
|
|
||||||
"files": 1535,
|
|
||||||
"logical_bytes": 861302992,
|
|
||||||
"verified_all_bytes_before_retirement": true,
|
|
||||||
"restore_view": "failed-copy",
|
|
||||||
"absent_after": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"free_before": 894099456,
|
|
||||||
"free_after": 2749599744,
|
|
||||||
"time_ns": 1792229099545221000,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"receipt_bytes_unmodified": true,
|
|
||||||
"actual_free_gain_bytes": 1855500288
|
|
||||||
}
|
|
||||||
-69
@@ -1,69 +0,0 @@
|
|||||||
{
|
|
||||||
"at_jst": "2026-10-17T18:34:28.900674+09:00",
|
|
||||||
"plan_id": "P13-02",
|
|
||||||
"batch": "P13-02-CODE1",
|
|
||||||
"S": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"original_packages": 30,
|
|
||||||
"original_units": 88,
|
|
||||||
"formally_completed": 14,
|
|
||||||
"new_credit": 0,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"failure": "ENOSPC while copying ended native5374check P08 migration runtime profile; incomplete original runner-ended preserved",
|
|
||||||
"causal_measurements": {
|
|
||||||
"single_runtime_profile_files": 2792,
|
|
||||||
"single_runtime_logical_bytes": 1839108706,
|
|
||||||
"partial_duplicate_whole_files": 1534,
|
|
||||||
"partial_duplicate_zero_byte_fragment": 1
|
|
||||||
},
|
|
||||||
"recovery": "Exact full archive plus original partial-copy view and fragment retained; every member SHA verified locally, remote complete archives fetched and streamed SHA verified before retiring only verified uncompressed profiles. No test log or acceptance data erased.",
|
|
||||||
"archives": [
|
|
||||||
{
|
|
||||||
"drive_id": "1F6MYrZ7begmlNaZkjMOlJT5y9uMcSVwM",
|
|
||||||
"url": "https://drive.google.com/file/d/1F6MYrZ7begmlNaZkjMOlJT5y9uMcSVwM/view",
|
|
||||||
"purpose": "current057 full profile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"drive_id": "1eT98KWt71v62IGhxyBSjmf4FEoTvFMxA",
|
|
||||||
"url": "https://drive.google.com/file/d/1eT98KWt71v62IGhxyBSjmf4FEoTvFMxA/view",
|
|
||||||
"purpose": "current057 restore kit with exact original and failed-copy views"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"drive_id": "1_HFt31YEAs6ak7Z2BiX9xOCQJkYBjovE",
|
|
||||||
"url": "https://drive.google.com/file/d/1_HFt31YEAs6ak7Z2BiX9xOCQJkYBjovE/view",
|
|
||||||
"purpose": "previous ended P23 full179 runtime profile, full restore metadata embedded"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"drive_id": "1tR_3rlst7AshVskaVxG6JFvQxF5OP5ow",
|
|
||||||
"url": "https://drive.google.com/file/d/1tR_3rlst7AshVskaVxG6JFvQxF5OP5ow/view",
|
|
||||||
"purpose": "older ended P08 phase profile, full restore metadata embedded; failed whole attempt remains failed"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"proof_records": {
|
|
||||||
"DRIVE_FULL_ARCHIVE_READBACK.json": {
|
|
||||||
"bytes": 221,
|
|
||||||
"sha256": "36a59d70bb6b67b20c89a26bc5bc1bae3e16f1e4cdc34faf8690cb8d47f4ea55",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/storage-profile-recovery-20261017/DRIVE_FULL_ARCHIVE_READBACK.json"
|
|
||||||
},
|
|
||||||
"DRIVE_RESTORE_KIT_READBACK.json": {
|
|
||||||
"bytes": 219,
|
|
||||||
"sha256": "29119b49b58bdaed54b672bab4629fd17f56c33b5cb6961ce2061f222a0897e3",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/storage-profile-recovery-20261017/DRIVE_RESTORE_KIT_READBACK.json"
|
|
||||||
},
|
|
||||||
"057-ARCHIVAL-RECOVERY.json": {
|
|
||||||
"bytes": 1110,
|
|
||||||
"sha256": "220aa68ceb8195b1ac3358118b4ea652750cafc4a421b9f277026ccfadb76722",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/storage-profile-recovery-20261017/057-ARCHIVAL-RECOVERY.json"
|
|
||||||
},
|
|
||||||
"PREVIOUS_P23_PROFILE057_DRIVE_AND_RETIREMENT.json": {
|
|
||||||
"bytes": 785,
|
|
||||||
"sha256": "6633575fcf6cba529d72c3fc652fffc082128114e20cdf9f0fd0a223ff5d9c8e",
|
|
||||||
"original": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/storage-profile-recovery-20261017/PREVIOUS_P23_PROFILE057_DRIVE_AND_RETIREMENT.json"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"current_free_bytes": 4107698176,
|
|
||||||
"next_full_scope": "Import and329parse plus original58 suites qualified; remaining126 require unchanged native per-phase gates, exact input equality, all cross-segment checks, separate actual Opus review, normal integration/final. No restart of accepted native phases.",
|
|
||||||
"admission_required_bytes": 3467374666,
|
|
||||||
"P04_next_formal_unit": "P04-01 pending actual owner D05 choices, no fake approval",
|
|
||||||
"whole_original_acceptance": false,
|
|
||||||
"later_archival_result": "Additional1.838GB logical old profile preserved remotely with full readback SHA. Immediate measured free gain153612288B; logical size is not claimed as physical space recovered."
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"drive_id": "1F6MYrZ7begmlNaZkjMOlJT5y9uMcSVwM",
|
|
||||||
"bytes": 97976496,
|
|
||||||
"sha256": "f962d3622f5da562c3c07c4afed84bf4f1042a2470f555c16148d450e70453ff",
|
|
||||||
"full_remote_readback": true,
|
|
||||||
"time_ns": 1792229035052351000
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"drive_id": "1eT98KWt71v62IGhxyBSjmf4FEoTvFMxA",
|
|
||||||
"bytes": 216139,
|
|
||||||
"sha256": "8517b61a253141a76e3bde5bab81f3971ca91989b37b2c89e95a5ee42c010cda",
|
|
||||||
"full_remote_readback": true,
|
|
||||||
"time_ns": 1792229078775515000
|
|
||||||
}
|
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"drive_id": "1tR_3rlst7AshVskaVxG6JFvQxF5OP5ow",
|
|
||||||
"remote_bytes": 98084260,
|
|
||||||
"remote_sha256": "79879544b1351706d96e072f77a5b893aced99204c3c8fa83c216279b2cef011",
|
|
||||||
"full_remote_readback": true,
|
|
||||||
"all_original_bytes_verified_before_retirement": true,
|
|
||||||
"original": "/Users/korizatou114/Library/Application Support/TheTree-PCK-tests-4c87cfdfbfff41fd85a9686027d4b109-standard-runtime-057",
|
|
||||||
"files": 2792,
|
|
||||||
"archive": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/storage-profile-recovery-20261017/p08-older-ended-profile057-lossless.tar.gz",
|
|
||||||
"archive_contains_full_manifest": true,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"phase_passed_and_ended": true,
|
|
||||||
"time_ns": 1792230632135468000,
|
|
||||||
"free_before": 3985821696,
|
|
||||||
"original_absent": true,
|
|
||||||
"free_after": 4139433984,
|
|
||||||
"actual_free_gain": 153612288
|
|
||||||
}
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"drive_id": "1_HFt31YEAs6ak7Z2BiX9xOCQJkYBjovE",
|
|
||||||
"remote_bytes": 98141942,
|
|
||||||
"remote_sha256": "0cdfb0eb3dc7b5bced24f209bd024436db5450926dae74885d658bcdcf407ed5",
|
|
||||||
"full_remote_readback": true,
|
|
||||||
"all_original_bytes_verified_before_retirement": true,
|
|
||||||
"original": "/Users/korizatou114/Library/Application Support/TheTree-PCK-tests-4572ef90efe94bc59f24b8e3d80452d0-standard-runtime-057",
|
|
||||||
"files": 2792,
|
|
||||||
"archive": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/.runtime/storage-profile-recovery-20261017/p23-previous-full179-profile057-lossless.tar.gz",
|
|
||||||
"archive_contains_full_manifest": true,
|
|
||||||
"time_ns": 1792229606376983000,
|
|
||||||
"free_before": 2652545024,
|
|
||||||
"original_absent": true,
|
|
||||||
"free_after": 4500942848,
|
|
||||||
"actual_free_gain": 1848397824
|
|
||||||
}
|
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
"facility_value_contracts_validation.json": "bf490a9ca585c48fc318e76c4a069ef244827d828d46e6415399f7710590dd16",
|
"facility_value_contracts_validation.json": "bf490a9ca585c48fc318e76c4a069ef244827d828d46e6415399f7710590dd16",
|
||||||
"performance_audit.json": "0b630b15a392c3e0366f1362bfe4ddacb968f915f54549f82e4d6fa315384762",
|
"performance_audit.json": "0b630b15a392c3e0366f1362bfe4ddacb968f915f54549f82e4d6fa315384762",
|
||||||
"progress_contract.json": "ccbdfce8c8365d5c13f59531955708834cce45acd0e136561c95295dfdb5df77",
|
"progress_contract.json": "ccbdfce8c8365d5c13f59531955708834cce45acd0e136561c95295dfdb5df77",
|
||||||
"progress_snapshot.json": "9e8fab3cd49f2b7c70dde88c0adba71dda7fcee27384aff5fd11f11333577476",
|
"progress_snapshot.json": "d929905fac7089ad359154fdaa9f4d65e323becf7a6b46c8cadd2ba6d1719a9c",
|
||||||
"progress_validator_guard_checks.json": "72ee513fcf1cad85c24bfd0a4b472f425f6acf117928ece0f6b41e29018da627",
|
"progress_validator_guard_checks.json": "72ee513fcf1cad85c24bfd0a4b472f425f6acf117928ece0f6b41e29018da627",
|
||||||
"progress_validator_guard_checks.r01.json": "14c26adffa5a1938241db4912e50ea54b660641ee6fee2e412d467dce14d0519",
|
"progress_validator_guard_checks.r01.json": "14c26adffa5a1938241db4912e50ea54b660641ee6fee2e412d467dce14d0519",
|
||||||
"requirement_coverage.json": "03b10e4da367579db502d0671a6e0dda36fd385111c6f1c0084acaff7605f593",
|
"requirement_coverage.json": "03b10e4da367579db502d0671a6e0dda36fd385111c6f1c0084acaff7605f593",
|
||||||
@@ -254,6 +254,6 @@
|
|||||||
"validate_facility_value_contracts.py": "91640e2a76cd6cc9186f7b85c0bf379b24b6cac0d48962815235ee628e7ae43e",
|
"validate_facility_value_contracts.py": "91640e2a76cd6cc9186f7b85c0bf379b24b6cac0d48962815235ee628e7ae43e",
|
||||||
"validate_plan.py": "23678227d9b3c556f1bd903f4b5b3147c4a82ce5085e10055481026803451b80",
|
"validate_plan.py": "23678227d9b3c556f1bd903f4b5b3147c4a82ce5085e10055481026803451b80",
|
||||||
"validator_update_checks.json": "f997d0f3de2cea29550840b1d5cb23647d64f81329de46758551e2b6c8fecc27",
|
"validator_update_checks.json": "f997d0f3de2cea29550840b1d5cb23647d64f81329de46758551e2b6c8fecc27",
|
||||||
"work_packages.json": "7ba154a369a9aec73bcf2d315309d094e4be5bb85f978d29fc9114d3a1569aa9"
|
"work_packages.json": "cd70846e0701396a3492cbab95aed9a3272cb108a08f9920b9c28e46c21e7361"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,8 +157,8 @@
|
|||||||
},
|
},
|
||||||
"current_delivery_state_counts": {
|
"current_delivery_state_counts": {
|
||||||
"completed": 14,
|
"completed": 14,
|
||||||
"in_progress": 24,
|
"in_progress": 23,
|
||||||
"planned": 50
|
"planned": 51
|
||||||
},
|
},
|
||||||
"completed_current_deliveries": [
|
"completed_current_deliveries": [
|
||||||
"P00-01",
|
"P00-01",
|
||||||
@@ -10422,52 +10422,5 @@
|
|||||||
"source": "fe44f550750acbf5c510346e7cacbea2ccbdd184",
|
"source": "fe44f550750acbf5c510346e7cacbea2ccbdd184",
|
||||||
"original_unit_credit_added": 0,
|
"original_unit_credit_added": 0,
|
||||||
"all8_accepted": false
|
"all8_accepted": false
|
||||||
},
|
|
||||||
"current_p13_02_backend_local_progress": {
|
|
||||||
"observed_at_jst": "2026-10-17T17:28:02.473746+09:00",
|
|
||||||
"source": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"evidence": "docs/plans/original-completion-2026-10-02/execution/p13-02/root-a7e3069-local-20261017/CURRENT_ACCEPTANCE_STATUS.json",
|
|
||||||
"source_adopted_on_main": false,
|
|
||||||
"whole_original_accepted": false,
|
|
||||||
"new_credit": 0,
|
|
||||||
"local_suites": 15,
|
|
||||||
"local_checks": 863,
|
|
||||||
"full_regression": false,
|
|
||||||
"formal_independent_review": false,
|
|
||||||
"prior_delivery_counts_before_P13_started": {
|
|
||||||
"completed": 14,
|
|
||||||
"in_progress": 23,
|
|
||||||
"planned": 51
|
|
||||||
},
|
|
||||||
"scope": "Corrects planned→in_progress only; no formal completion or source adoption",
|
|
||||||
"full_scope_native": {
|
|
||||||
"actual_suites": 184,
|
|
||||||
"missing_marker_paths": [],
|
|
||||||
"remaining_unexecuted_tests": [],
|
|
||||||
"available_marker_checks": 21903,
|
|
||||||
"actual_all_roster_checks": 21903,
|
|
||||||
"strict_accepted_checks": 21903,
|
|
||||||
"verified": true,
|
|
||||||
"composed": true,
|
|
||||||
"original_full_attempt_passed": false,
|
|
||||||
"whole_original_acceptance": false,
|
|
||||||
"parse_checks": 329,
|
|
||||||
"setup_phases": 2,
|
|
||||||
"owned_ended": 186,
|
|
||||||
"tested_source": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"engines_started": 0,
|
|
||||||
"verifier_sha256": "d00bf46bfcc0e0bb197edd284a3ae14610ca710507831e18e071a79461946e8a"
|
|
||||||
},
|
|
||||||
"latest_full_status": "docs/plans/original-completion-2026-10-02/execution/p13-02/root-a7e3069-full-20261017/CURRENT_ACCEPTANCE_STATUS.json",
|
|
||||||
"formal_review": {
|
|
||||||
"state": "actual provider running",
|
|
||||||
"exec_session": 96001,
|
|
||||||
"run_id": "ead8e74b9683404d8cf3d97bca118726",
|
|
||||||
"pid": 17285,
|
|
||||||
"model": "claude-opus-5-5",
|
|
||||||
"frozen_checkout": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p13-02-reference/P13-02-CODE1-review-e6fc1237",
|
|
||||||
"material_files": 16049
|
|
||||||
},
|
|
||||||
"formal_credit": 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8032,36 +8032,16 @@
|
|||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
||||||
"sha256": "988d6e18a49372549863cd433432c2852c962fa64b138e490361c023e80249dc",
|
"sha256": "988d6e18a49372549863cd433432c2852c962fa64b138e490361c023e80249dc",
|
||||||
"scope": "Actual Opus-selected bounded implementation contract preparation; no tests or whole acceptance credit"
|
"scope": "Actual Opus-selected bounded implementation contract preparation; no tests or whole acceptance credit"
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/root-e930a1d-native-import-20261017/CURRENT_ACCEPTANCE_STATUS.json",
|
|
||||||
"sha256": "87122b4256cafac78f5fe0efe3253f5d59bbda5e8bfdf727c177bb354050207c",
|
|
||||||
"scope": "Actual submitted backend and failed owned import guard evidence; no passing suites or formal credit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/root-a7e3069-local-20261017/CURRENT_ACCEPTANCE_STATUS.json",
|
|
||||||
"sha256": "6635dfeaa73fe69f3395e8d03bc9ae5f8506a04259e8682917a3cf11b0f8575a",
|
|
||||||
"scope": "Actual15/863 local and329 parse with all17 owned engines ended and exact UID policy; no whole-original acceptance or credit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p13-02/root-a7e3069-full-20261017/CURRENT_ACCEPTANCE_STATUS.json",
|
|
||||||
"sha256": "bb945dac151519f15b46f48656dd4132870a5301bf5c00a81b32592b78ff7f2a",
|
|
||||||
"scope": "Actual qualified composed184/21903/329parse/186ended; original failed full not overwritten; formal independent review and integration/final pending, original credit0"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"progress_summary": "実提出a7e3069で局所15/863・登録validation合格、全184スイート21903チェック/329構文/実所有186PID終了を全元ガード付きで再照合。ENOSPC終了の元全回帰は失敗のまま保存し、正確58スイートと実続行126の合成証明を明示、証跡は全量可逆圧縮・Drive読戻SHA照合。通常独立Opusレビュー工程を起動済み、通常integration/finalは未了。原P13全条件の未承認値・自然営業・VIP/完成素材/Windows等は残り、原14/88から加算0。次の正式原成果はP04-01、既存D05回答待ち。",
|
"progress_summary": "実Opus e65d48f5がP04回答に依存しない実装対象として選定。現mainにない背面配置/対象喪失/証拠ID重複防止/保存機構をRuntimeへ接続するCODE1契約を準備。担当sol指定。未承認建設値・記録係/自然収集契機・VIP未定義・D05/カメラUI等は捏造せず残す。通常建設/自然営業/全原条件は未受入、正式14/88で加算0。",
|
||||||
"current_summary": "実提出a7e3069で局所15/863・登録validation合格、全184スイート21903チェック/329構文/実所有186PID終了を全元ガード付きで再照合。ENOSPC終了の元全回帰は失敗のまま保存し、正確58スイートと実続行126の合成証明を明示、証跡は全量可逆圧縮・Drive読戻SHA照合。通常独立Opusレビュー工程を起動済み、通常integration/finalは未了。原P13全条件の未承認値・自然営業・VIP/完成素材/Windows等は残り、原14/88から加算0。次の正式原成果はP04-01、既存D05回答待ち。",
|
"current_summary": "実Opus e65d48f5がP04回答に依存しない実装対象として選定。現mainにない背面配置/対象喪失/証拠ID重複防止/保存機構をRuntimeへ接続するCODE1契約を準備。担当sol指定。未承認建設値・記録係/自然収集契機・VIP未定義・D05/カメラUI等は捏造せず残す。通常建設/自然営業/全原条件は未受入、正式14/88で加算0。",
|
||||||
"updated_at_jst": "2026-10-17T18:59:44.626679+09:00",
|
"updated_at_jst": "2026-10-17T16:38:25.025337+09:00",
|
||||||
"current_execution": "docs/plans/original-completion-2026-10-02/execution/p13-02/root-a7e3069-full-20261017/CURRENT_ACCEPTANCE_STATUS.json",
|
"current_execution": "docs/plans/original-completion-2026-10-02/execution/p13-02/CODE1_TASK_SPEC.json",
|
||||||
"remaining_gaps": [
|
"remaining_gaps": [
|
||||||
"Actual separate whole CODE1 review must pass with no critical/high/medium finding",
|
"CODE1実装・必要な局所/影響検証・独立レビュー・通常統合finalは未実行。登録機構は元成果の全条件/通常Runtime/画面/保存受入を代替しない。",
|
||||||
"Normal exact latest-main integration candidate, input-equality qualification, final verification and ledger",
|
"未承認建設/維持/収集数値・記録係条件、VIP施設、自然収集トリガ、D05取引規則、P19/P24接続と完成資産、原P13-02全条件の受入を残す。"
|
||||||
"Whole original P13-02 normal construction/recorder/natural triggers/approved quantities/VIP/UI/assets/Windows and all original conditions remain unaccepted"
|
]
|
||||||
],
|
|
||||||
"submitted_commit": "a7e3069b167511b3194242b3403fbcc35244a526",
|
|
||||||
"normal_integration_candidate": null,
|
|
||||||
"worker_model": "gpt-6-astra",
|
|
||||||
"model_selected_by_actual_opus": "19f00667226d42dd8e9b3a4ae99aaa68"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "P13-03",
|
"id": "P13-03",
|
||||||
|
|||||||
@@ -1048,6 +1048,13 @@ static func _snapshot_package_format(snapshot: Dictionary) -> int:
|
|||||||
if not runtime_data is Dictionary: return FORMAT_VERSION # no owned Runtime authority
|
if not runtime_data is Dictionary: return FORMAT_VERSION # no owned Runtime authority
|
||||||
var version: Variant = runtime_data.get(&"runtime_schema_version", 1)
|
var version: Variant = runtime_data.get(&"runtime_schema_version", 1)
|
||||||
if typeof(version) != TYPE_INT: return -1
|
if typeof(version) != TYPE_INT: return -1
|
||||||
|
if runtime_data.has(&"special_peeping_rooms"):
|
||||||
|
var section_clock: Variant = snapshot.get(&"clock")
|
||||||
|
if not section_clock is Dictionary or typeof(section_clock.get(&"absolute_minute")) != TYPE_INT: return -1
|
||||||
|
if not preload("res://scripts/special/peeping_room_service.gd").valid_runtime_section(runtime_data, section_clock[&"absolute_minute"]): return -1
|
||||||
|
# Keep PurchaseQuotePlansV2's exact original allowlist and all format rules.
|
||||||
|
runtime_data = runtime_data.duplicate()
|
||||||
|
runtime_data.erase(&"special_peeping_rooms")
|
||||||
if version >= 1 and version <= 14:
|
if version >= 1 and version <= 14:
|
||||||
return -1 if PurchaseQuoteV2.has_history(runtime_data) else FORMAT_VERSION
|
return -1 if PurchaseQuoteV2.has_history(runtime_data) else FORMAT_VERSION
|
||||||
if version != 15: return -1
|
if version != 15: return -1
|
||||||
|
|||||||
@@ -0,0 +1,271 @@
|
|||||||
|
class_name PeepingRoomService
|
||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
## Non-graphic state/reference machinery; production definitions remain pending.
|
||||||
|
const SECTION_VERSION := 1
|
||||||
|
const ALLOWED_TARGETS := [&"public_bath", &"adult_private_room"]
|
||||||
|
const OCCUPANCY_KIND := &"special_peeping_room"
|
||||||
|
const ID_PREFIX := &"peeping_room"
|
||||||
|
const ROOM_KEYS := [&"room_id", &"origin", &"footprint", &"cells", &"target_instance_id", &"target_definition_id", &"target_history", &"link_state", &"stopped", &"stop_reason"]
|
||||||
|
const EVIDENCE_KEYS := [&"evidence_id", &"room_id", &"target_instance_id", &"source_event_key", &"minute"]
|
||||||
|
|
||||||
|
var _rooms: Dictionary = {}
|
||||||
|
var _evidence: Dictionary = {}
|
||||||
|
var _world: WorldService
|
||||||
|
var _facilities: FacilityService
|
||||||
|
var _construction: ConstructionService
|
||||||
|
var _path: PathService
|
||||||
|
var _ids: StableIdGenerator
|
||||||
|
|
||||||
|
func configure(world: WorldService, facilities: FacilityService, construction: ConstructionService, path: PathService, ids: StableIdGenerator) -> void:
|
||||||
|
_world = world
|
||||||
|
_facilities = facilities
|
||||||
|
_construction = construction
|
||||||
|
_path = path
|
||||||
|
_ids = ids
|
||||||
|
|
||||||
|
static func result(reason: StringName = &"OK") -> Dictionary:
|
||||||
|
return {&"ok": reason == &"OK", &"reason": reason}
|
||||||
|
|
||||||
|
func is_empty() -> bool:
|
||||||
|
return _rooms.is_empty() and _evidence.is_empty()
|
||||||
|
|
||||||
|
func get_room(room_id: StringName) -> Dictionary:
|
||||||
|
return (_rooms.get(room_id, {}) as Dictionary).duplicate(true)
|
||||||
|
|
||||||
|
## Pure validation. own_room is supplied internally only for explicit relink/restore.
|
||||||
|
func validate_placement(origin: Vector3i, footprint: Vector2i = Vector2i(2, 1), target_id: StringName = &"", own_room: StringName = &"") -> Dictionary:
|
||||||
|
if origin.z != WorldService.LAYER_BACK: return result(&"WRONG_LAYER")
|
||||||
|
if footprint != Vector2i(2, 1): return result(&"WRONG_FOOTPRINT")
|
||||||
|
if target_id == &"vip_suite": return result(&"PENDING_P10_01")
|
||||||
|
var cells := _world.cells_for_footprint(origin, footprint)
|
||||||
|
var targets: Array[StringName] = []
|
||||||
|
var missing := false
|
||||||
|
for cell: Vector3i in cells:
|
||||||
|
if not _world.is_in_bounds(cell): return result(&"OUT_OF_BOUNDS")
|
||||||
|
if cell.y < 0 and not _world.is_excavated(cell): return result(&"NOT_EXCAVATED")
|
||||||
|
var front := Vector3i(cell.x, cell.y, WorldService.LAYER_FRONT)
|
||||||
|
if _world.get_occupant_kind(front) == &"construction": return result(&"TARGET_INCOMPLETE")
|
||||||
|
var occupant := _world.get_occupant(front)
|
||||||
|
if occupant.is_empty(): missing = true
|
||||||
|
elif occupant not in targets: targets.append(occupant)
|
||||||
|
if targets.size() > 1: return result(&"MULTIPLE_TARGETS")
|
||||||
|
if missing: return result(&"TARGET_MISSING" if targets.is_empty() else &"PARTIAL_TARGET")
|
||||||
|
var resolved_id := targets[0]
|
||||||
|
if not target_id.is_empty() and target_id != resolved_id: return result(&"TARGET_MISMATCH")
|
||||||
|
var target := _facilities.get_instance(resolved_id)
|
||||||
|
if target == null: return result(&"TARGET_UNKNOWN")
|
||||||
|
if target.definition_id not in ALLOWED_TARGETS: return result(&"TARGET_NOT_ALLOWED")
|
||||||
|
if target.origin.z != WorldService.LAYER_FRONT: return result(&"TARGET_WRONG_LAYER")
|
||||||
|
var built := _construction.get_facility(resolved_id)
|
||||||
|
if built.is_empty(): return result(&"TARGET_INCOMPLETE")
|
||||||
|
if built.get(&"definition_id") != target.definition_id: return result(&"TARGET_MISMATCH")
|
||||||
|
for cell: Vector3i in cells:
|
||||||
|
var front := Vector3i(cell.x, cell.y, WorldService.LAYER_FRONT)
|
||||||
|
if front not in target.occupied_cells or front not in built[&"occupied_cells"]: return result(&"PARTIAL_TARGET")
|
||||||
|
# Reject cutting an existing corridor; never construct an implicit bypass.
|
||||||
|
if _world.is_walkable(cell) or _path.has_cell(cell): return result(&"CORRIDOR_CONFLICT")
|
||||||
|
var occupancy := _world.validate_occupancy(cells)
|
||||||
|
if not occupancy[&"ok"]:
|
||||||
|
if own_room.is_empty() or _world.get_entity_cells(own_room) != cells or _world.get_entity_kind(own_room) != OCCUPANCY_KIND:
|
||||||
|
return result(&"BACK_OCCUPIED")
|
||||||
|
var report := result()
|
||||||
|
report.merge({&"cells": cells, &"target_instance_id": resolved_id, &"target_definition_id": target.definition_id})
|
||||||
|
return report
|
||||||
|
|
||||||
|
## CONTROLLED_FIXTURE: tests only. No Runtime executor or palette calls this.
|
||||||
|
func controlled_fixture_place(origin: Vector3i, target_id: StringName = &"") -> Dictionary:
|
||||||
|
var report := validate_placement(origin, Vector2i(2, 1), target_id)
|
||||||
|
if not report[&"ok"]: return report
|
||||||
|
var room_id := _ids.next_id(ID_PREFIX)
|
||||||
|
if room_id.is_empty(): return result(&"ID_EXHAUSTED")
|
||||||
|
if not _world.occupy(room_id, report[&"cells"], OCCUPANCY_KIND): return result(&"BACK_OCCUPIED")
|
||||||
|
_rooms[room_id] = {&"room_id": room_id, &"origin": origin, &"footprint": Vector2i(2, 1),
|
||||||
|
&"cells": report[&"cells"].duplicate(), &"target_instance_id": report[&"target_instance_id"],
|
||||||
|
&"target_definition_id": report[&"target_definition_id"],
|
||||||
|
&"target_history": [report[&"target_instance_id"]], &"link_state": &"LINKED",
|
||||||
|
&"stopped": true, &"stop_reason": &"CONTROLLED_FIXTURE"}
|
||||||
|
report[&"room_id"] = room_id
|
||||||
|
return report
|
||||||
|
|
||||||
|
func target_removed(target_id: StringName) -> void:
|
||||||
|
for room: Dictionary in _rooms.values():
|
||||||
|
if room[&"target_instance_id"] == target_id:
|
||||||
|
room[&"link_state"] = &"TARGET_LOST"
|
||||||
|
room[&"stopped"] = true
|
||||||
|
room[&"stop_reason"] = &"TARGET_LOST"
|
||||||
|
|
||||||
|
func detect_target_loss() -> void:
|
||||||
|
for room: Dictionary in _rooms.values():
|
||||||
|
if room[&"link_state"] == &"TARGET_LOST": continue
|
||||||
|
if not _target_still_present(room): target_removed(room[&"target_instance_id"])
|
||||||
|
|
||||||
|
func _target_still_present(room: Dictionary) -> bool:
|
||||||
|
var target := _facilities.get_instance(room[&"target_instance_id"])
|
||||||
|
if target == null or target.definition_id != room[&"target_definition_id"]: return false
|
||||||
|
for cell: Vector3i in room[&"cells"]:
|
||||||
|
if _world.get_occupant(Vector3i(cell.x, cell.y, WorldService.LAYER_FRONT)) != target.instance_id: return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
func relink(room_id: StringName, target_id: StringName) -> Dictionary:
|
||||||
|
if not _rooms.has(room_id): return result(&"ROOM_MISSING")
|
||||||
|
if target_id.is_empty(): return result(&"TARGET_MISSING")
|
||||||
|
var room: Dictionary = _rooms[room_id]
|
||||||
|
var report := validate_placement(room[&"origin"], room[&"footprint"], target_id, room_id)
|
||||||
|
if not report[&"ok"]: return report
|
||||||
|
room[&"target_instance_id"] = target_id
|
||||||
|
room[&"target_definition_id"] = report[&"target_definition_id"]
|
||||||
|
if target_id not in room[&"target_history"]: room[&"target_history"].append(target_id)
|
||||||
|
room[&"link_state"] = &"LINKED"
|
||||||
|
room[&"stopped"] = true
|
||||||
|
room[&"stop_reason"] = &"RELINKED_PENDING_RESUME"
|
||||||
|
return result()
|
||||||
|
|
||||||
|
func _collection_precondition(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:
|
||||||
|
if String(source_event_key).strip_edges().is_empty(): return result(&"SOURCE_EVENT_KEY_REQUIRED")
|
||||||
|
if minute < 0: return result(&"INVALID_MINUTE")
|
||||||
|
if not _rooms.has(room_id): return result(&"ROOM_MISSING")
|
||||||
|
detect_target_loss()
|
||||||
|
var room: Dictionary = _rooms[room_id]
|
||||||
|
# Required precedence: stopped, power, closed, construction, lost target.
|
||||||
|
if room[&"stopped"]: return result(&"STOPPED")
|
||||||
|
var target := _facilities.get_instance(room[&"target_instance_id"])
|
||||||
|
if target != null:
|
||||||
|
if not target.power_available: return result(&"NO_POWER")
|
||||||
|
if not target.operator_open or not target.is_within_opening_hours(minute): return result(&"CLOSED")
|
||||||
|
if _construction.get_facility(target.instance_id).is_empty(): return result(&"UNDER_CONSTRUCTION")
|
||||||
|
if room[&"link_state"] == &"TARGET_LOST" or target == null: return result(&"TARGET_LOST")
|
||||||
|
return result()
|
||||||
|
|
||||||
|
func record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:
|
||||||
|
var report := _collection_precondition(room_id, source_event_key, minute)
|
||||||
|
return report if not report[&"ok"] else result(&"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16")
|
||||||
|
|
||||||
|
## CONTROLLED_FIXTURE: explicit test state, never a production resume command.
|
||||||
|
func controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:
|
||||||
|
if not _rooms.has(room_id): return false
|
||||||
|
detect_target_loss()
|
||||||
|
var room: Dictionary = _rooms[room_id]
|
||||||
|
if not stopped and room[&"link_state"] == &"TARGET_LOST": return false
|
||||||
|
room[&"stopped"] = stopped
|
||||||
|
room[&"stop_reason"] = &"CONTROLLED_FIXTURE" if stopped else &""
|
||||||
|
return true
|
||||||
|
|
||||||
|
## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.
|
||||||
|
func controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:
|
||||||
|
var report := _collection_precondition(room_id, source_event_key, minute)
|
||||||
|
if not report[&"ok"]: return report
|
||||||
|
var target_id: StringName = _rooms[room_id][&"target_instance_id"]
|
||||||
|
var evidence_id := _evidence_id(room_id, target_id, source_event_key)
|
||||||
|
var duplicated := _evidence.has(evidence_id)
|
||||||
|
if not duplicated:
|
||||||
|
_evidence[evidence_id] = {&"evidence_id": evidence_id, &"room_id": room_id,
|
||||||
|
&"target_instance_id": target_id, &"source_event_key": source_event_key, &"minute": minute}
|
||||||
|
return {&"ok": true, &"reason": &"OK", &"evidence_id": evidence_id, &"duplicated": duplicated}
|
||||||
|
|
||||||
|
static func _evidence_id(room_id: StringName, target_id: StringName, event_key: StringName) -> StringName:
|
||||||
|
# Length-prefixed UTF-8 hex is injective; delimiters in input cannot alias.
|
||||||
|
var pieces: Array[String] = []
|
||||||
|
for value: StringName in [room_id, target_id, event_key]:
|
||||||
|
var bytes := String(value).to_utf8_buffer()
|
||||||
|
pieces.append("%d:%s" % [bytes.size(), bytes.hex_encode()])
|
||||||
|
return StringName("peeping_evidence:" + ":".join(pieces))
|
||||||
|
|
||||||
|
func create_snapshot() -> Dictionary:
|
||||||
|
var rooms: Array[Dictionary] = []
|
||||||
|
var evidence: Array[Dictionary] = []
|
||||||
|
var keys := _rooms.keys()
|
||||||
|
keys.sort()
|
||||||
|
for key: StringName in keys: rooms.append(_rooms[key].duplicate(true))
|
||||||
|
keys = _evidence.keys()
|
||||||
|
keys.sort()
|
||||||
|
for key: StringName in keys: evidence.append(_evidence[key].duplicate(true))
|
||||||
|
return {&"version": SECTION_VERSION, &"rooms": rooms, &"evidence": evidence}
|
||||||
|
|
||||||
|
static func _exact(value: Variant, keys: Array) -> bool:
|
||||||
|
if not value is Dictionary or value.size() != keys.size(): return false
|
||||||
|
for key: Variant in value:
|
||||||
|
if typeof(key) != TYPE_STRING_NAME or key not in keys: return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
## Save format 15 has a fixed purchase-key allowlist outside this task's scope.
|
||||||
|
## Validate this independent section before passing only the original keys to it.
|
||||||
|
static func valid_runtime_section(data: Dictionary, minute: int) -> bool:
|
||||||
|
if not data.get(&"special_peeping_rooms") is Dictionary: return false
|
||||||
|
for key: Variant in data:
|
||||||
|
if key == &"special_peeping_rooms" and typeof(key) != TYPE_STRING_NAME: return false
|
||||||
|
for key: StringName in [&"world", &"path", &"facilities", &"construction", &"id_generator"]:
|
||||||
|
if not data.get(key) is Dictionary: return false
|
||||||
|
var world := WorldService.new()
|
||||||
|
var path := PathService.new()
|
||||||
|
var facilities := FacilityService.new()
|
||||||
|
var ids := StableIdGenerator.new()
|
||||||
|
if not world.restore_snapshot(data[&"world"]) or not path.restore_snapshot(data[&"path"]) or not facilities.restore_snapshot(data[&"facilities"]) or not ids.restore_snapshot(data[&"id_generator"]): return false
|
||||||
|
var construction := ConstructionService.new(world)
|
||||||
|
if not construction.restore_snapshot(data[&"construction"]): return false
|
||||||
|
var service := PeepingRoomService.new()
|
||||||
|
service.configure(world, facilities, construction, path, ids)
|
||||||
|
return service.restore_section(data[&"special_peeping_rooms"], minute)
|
||||||
|
|
||||||
|
## Staged restore validates both directions of world ownership before committing.
|
||||||
|
func restore_section(section: Variant, minute: int) -> bool:
|
||||||
|
var rooms: Dictionary = {}
|
||||||
|
var evidence: Dictionary = {}
|
||||||
|
if section != null:
|
||||||
|
if not _exact(section, [&"version", &"rooms", &"evidence"]): return false
|
||||||
|
if typeof(section[&"version"]) != TYPE_INT or section[&"version"] != SECTION_VERSION: return false
|
||||||
|
if not section[&"rooms"] is Array or not section[&"evidence"] is Array: return false
|
||||||
|
if section[&"rooms"].is_empty(): return false # absence represents empty state
|
||||||
|
var known: Array = _facilities.create_snapshot()[&"known_instance_ids"]
|
||||||
|
for raw: Variant in section[&"rooms"]:
|
||||||
|
if not _exact(raw, ROOM_KEYS): return false
|
||||||
|
for key: StringName in [&"room_id", &"target_instance_id", &"target_definition_id", &"link_state", &"stop_reason"]:
|
||||||
|
if typeof(raw[key]) != TYPE_STRING_NAME: return false
|
||||||
|
var room_id: StringName = raw[&"room_id"]
|
||||||
|
var suffix := String(room_id).trim_prefix("peeping_room.")
|
||||||
|
if suffix.length() != 12 or not suffix.is_valid_int() or int(suffix) <= 0 or String(room_id) != "peeping_room.%012d" % int(suffix): return false
|
||||||
|
if int(suffix) > _ids.get_counter(ID_PREFIX) or rooms.has(room_id): return false
|
||||||
|
if typeof(raw[&"origin"]) != TYPE_VECTOR3I or typeof(raw[&"footprint"]) != TYPE_VECTOR2I: return false
|
||||||
|
if raw[&"origin"].z != WorldService.LAYER_BACK or raw[&"footprint"] != Vector2i(2, 1): return false
|
||||||
|
var cells := _world.cells_for_footprint(raw[&"origin"], raw[&"footprint"])
|
||||||
|
if not raw[&"cells"] is Array or raw[&"cells"] != cells: return false
|
||||||
|
for cell: Variant in raw[&"cells"]:
|
||||||
|
if typeof(cell) != TYPE_VECTOR3I: return false
|
||||||
|
if _world.get_entity_cells(room_id) != cells or _world.get_entity_kind(room_id) != OCCUPANCY_KIND: return false
|
||||||
|
for cell: Vector3i in cells:
|
||||||
|
if _world.is_walkable(cell) or _path.has_cell(cell): return false
|
||||||
|
if raw[&"target_definition_id"] not in ALLOWED_TARGETS: return false
|
||||||
|
if typeof(raw[&"stopped"]) != TYPE_BOOL or not raw[&"target_history"] is Array: return false
|
||||||
|
var history := {}
|
||||||
|
for target: Variant in raw[&"target_history"]:
|
||||||
|
if typeof(target) != TYPE_STRING_NAME or String(target) not in known or history.has(target): return false
|
||||||
|
history[target] = true
|
||||||
|
if not history.has(raw[&"target_instance_id"]): return false
|
||||||
|
var current_target := _facilities.get_instance(raw[&"target_instance_id"])
|
||||||
|
if current_target != null and current_target.definition_id != raw[&"target_definition_id"]: return false
|
||||||
|
if raw[&"link_state"] == &"TARGET_LOST":
|
||||||
|
if not raw[&"stopped"] or raw[&"stop_reason"] != &"TARGET_LOST" or _target_still_present(raw): return false
|
||||||
|
elif raw[&"link_state"] == &"LINKED":
|
||||||
|
if not validate_placement(raw[&"origin"], raw[&"footprint"], raw[&"target_instance_id"], room_id)[&"ok"]: return false
|
||||||
|
if _facilities.get_instance(raw[&"target_instance_id"]).definition_id != raw[&"target_definition_id"]: return false
|
||||||
|
if raw[&"stopped"]:
|
||||||
|
if raw[&"stop_reason"] not in [&"CONTROLLED_FIXTURE", &"RELINKED_PENDING_RESUME"]: return false
|
||||||
|
elif raw[&"stop_reason"] != &"": return false
|
||||||
|
else: return false
|
||||||
|
rooms[room_id] = raw.duplicate(true)
|
||||||
|
for raw: Variant in section[&"evidence"]:
|
||||||
|
if not _exact(raw, EVIDENCE_KEYS): return false
|
||||||
|
for key: StringName in [&"evidence_id", &"room_id", &"target_instance_id", &"source_event_key"]:
|
||||||
|
if typeof(raw[key]) != TYPE_STRING_NAME or raw[key].is_empty(): return false
|
||||||
|
if String(raw[&"source_event_key"]).strip_edges().is_empty(): return false
|
||||||
|
if typeof(raw[&"minute"]) != TYPE_INT or raw[&"minute"] < 0 or raw[&"minute"] > minute: return false
|
||||||
|
if not rooms.has(raw[&"room_id"]) or raw[&"target_instance_id"] not in rooms[raw[&"room_id"]][&"target_history"]: return false
|
||||||
|
var expected := _evidence_id(raw[&"room_id"], raw[&"target_instance_id"], raw[&"source_event_key"])
|
||||||
|
if expected != raw[&"evidence_id"] or evidence.has(expected): return false
|
||||||
|
evidence[expected] = raw.duplicate(true)
|
||||||
|
for occupied: Dictionary in _world.create_snapshot()[&"occupancies"]:
|
||||||
|
if occupied[&"kind"] == OCCUPANCY_KIND or String(occupied[&"entity_id"]).begins_with("peeping_room."):
|
||||||
|
if not rooms.has(occupied[&"entity_id"]): return false
|
||||||
|
_rooms = rooms
|
||||||
|
_evidence = evidence
|
||||||
|
return true
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
extends SceneTree
|
||||||
|
|
||||||
|
## CONTROLLED_FIXTURE. No production placement, recorder or eligibility claim.
|
||||||
|
const Rooms := preload("res://scripts/special/peeping_room_service.gd")
|
||||||
|
var checks := 0
|
||||||
|
var failures := 0
|
||||||
|
var fixtures: Array[Dictionary] = []
|
||||||
|
|
||||||
|
func _initialize() -> void:
|
||||||
|
call_deferred("_run")
|
||||||
|
|
||||||
|
func expect(ok: bool, label: String) -> void:
|
||||||
|
checks += 1
|
||||||
|
if not ok:
|
||||||
|
failures += 1
|
||||||
|
push_error(label)
|
||||||
|
|
||||||
|
func fixture(build_bath := true) -> Dictionary:
|
||||||
|
var clock: Variant = load("res://autoload/game_clock.gd").new()
|
||||||
|
var state: Variant = load("res://autoload/game_state.gd").new()
|
||||||
|
var runtime: Variant = load("res://autoload/simulation_runtime.gd").new()
|
||||||
|
clock.reset(1, 6, 0)
|
||||||
|
state.reset()
|
||||||
|
expect(runtime.initialize(clock, state, 1302)[&"valid"], "CONTROLLED_FIXTURE real Runtime initializes")
|
||||||
|
clock.set_paused(true)
|
||||||
|
runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
|
||||||
|
var f := {&"clock": clock, &"state": state, &"runtime": runtime, &"target": &"", &"origin": Vector3i(-6, 1, 1)}
|
||||||
|
fixtures.append(f)
|
||||||
|
if build_bath:
|
||||||
|
var built: CommandResult = runtime.submit_command(&"build_facility", {&"definition_id": &"public_bath", &"origin": Vector3i(-6, 0, 0)})
|
||||||
|
expect(built.is_success(), "real paid public bath construction")
|
||||||
|
clock.advance_minutes(runtime.definition_registry.get_facility(&"public_bath").build_minutes)
|
||||||
|
for target: FacilityInstance in runtime.facility_service.get_instances():
|
||||||
|
if target.definition_id == &"public_bath": f[&"target"] = target.instance_id
|
||||||
|
expect(not f[&"target"].is_empty(), "completed FRONT target has real stable identity")
|
||||||
|
return f
|
||||||
|
|
||||||
|
func place(f: Dictionary, origin: Variant = null) -> StringName:
|
||||||
|
var report: Dictionary = f[&"runtime"].peeping_room_service.controlled_fixture_place(f[&"origin"] if origin == null else origin)
|
||||||
|
expect(report[&"ok"], "CONTROLLED_FIXTURE only room placement: " + String(report[&"reason"]))
|
||||||
|
return report.get(&"room_id", &"")
|
||||||
|
|
||||||
|
func enable_fixture(f: Dictionary, room: StringName) -> void:
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
expect(runtime.peeping_room_service.controlled_fixture_set_stopped(room, false), "CONTROLLED_FIXTURE explicitly enables ledger exercise")
|
||||||
|
expect(runtime.facility_service.set_operational_status(f[&"target"], {&"power_available": true, &"operator_open": true}, f[&"clock"].absolute_minute).is_success(), "CONTROLLED_FIXTURE target conditions")
|
||||||
|
|
||||||
|
func rejects_atomically(runtime: Variant, snapshot: Dictionary) -> bool:
|
||||||
|
var before := var_to_bytes(runtime.create_snapshot())
|
||||||
|
return not runtime.restore_snapshot(snapshot) and before == var_to_bytes(runtime.create_snapshot())
|
||||||
|
|
||||||
|
func finish(label: String) -> void:
|
||||||
|
for f: Dictionary in fixtures:
|
||||||
|
f[&"runtime"].free()
|
||||||
|
f[&"clock"].free()
|
||||||
|
f[&"state"].free()
|
||||||
|
fixtures.clear()
|
||||||
|
print("%s: %d checks, %d failures" % [label, checks, failures])
|
||||||
|
quit(1 if failures else 0)
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
"""Static UID policy cases; no engine, native worker or regression invocation."""
|
||||||
|
import importlib.util
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
sys.dont_write_bytecode = True
|
||||||
|
TOOLS = Path(__file__).resolve().parents[2] / 'tools'
|
||||||
|
sys.path.insert(0, str(TOOLS))
|
||||||
|
spec = importlib.util.spec_from_file_location('p13_uid_policy', TOOLS / 'run_p13_reference_tests.py')
|
||||||
|
runner = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(runner)
|
||||||
|
|
||||||
|
|
||||||
|
class UIDPolicyTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.tmp = tempfile.TemporaryDirectory()
|
||||||
|
self.addCleanup(self.tmp.cleanup)
|
||||||
|
self.stage = Path(self.tmp.name)
|
||||||
|
self.owner = 'tests/special/example.gd'
|
||||||
|
self.other = 'scripts/special/peeping_room_service.gd'
|
||||||
|
for name in (self.owner, self.other):
|
||||||
|
self.write(name, b'extends RefCounted\n')
|
||||||
|
self.write('project.godot', b'[application]\n')
|
||||||
|
self.write('scripts/existing.gd.uid', b'uid://existing\n')
|
||||||
|
self.source = runner.shared.inventory(self.stage, stage=True)
|
||||||
|
self.plan = runner.uid_plan(self.source)
|
||||||
|
self.write(self.owner + '.uid', b'uid://first\n')
|
||||||
|
self.write(self.other + '.uid', b'uid://second\n')
|
||||||
|
|
||||||
|
def write(self, name, raw):
|
||||||
|
path = self.stage / name
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_bytes(raw)
|
||||||
|
|
||||||
|
def snapshot(self):
|
||||||
|
return runner.uid_snapshot(self.stage, self.source, self.plan)
|
||||||
|
|
||||||
|
def test_accept_and_owner_seal(self):
|
||||||
|
accepted = self.snapshot()
|
||||||
|
self.assertEqual(set(accepted), {self.owner + '.uid', self.other + '.uid'})
|
||||||
|
pin = accepted[self.owner + '.uid']
|
||||||
|
self.assertEqual(pin['raw_bytes'], list(b'uid://first\n'))
|
||||||
|
self.assertEqual(pin['text'], 'uid://first\n')
|
||||||
|
self.assertEqual(pin['owner_sha256'], self.source[self.owner]['sha256'])
|
||||||
|
self.assertEqual(pin['sha256'], runner.shared.sha(self.stage / (self.owner + '.uid')))
|
||||||
|
|
||||||
|
def test_unknown_and_extra(self):
|
||||||
|
for name in ('scripts/unknown.gd.uid', 'extra.txt'):
|
||||||
|
with self.subTest(name=name):
|
||||||
|
self.write(name, b'uid://extra\n')
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.snapshot()
|
||||||
|
(self.stage / name).unlink()
|
||||||
|
|
||||||
|
def test_missing(self):
|
||||||
|
(self.stage / (self.owner + '.uid')).unlink()
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.snapshot()
|
||||||
|
|
||||||
|
def test_malformed(self):
|
||||||
|
for raw in (b'uid://UPPER\n', b'uid://first', b'uid://first\nextra',
|
||||||
|
b'uid://12345678901234\n', b'uid://\n', b'uid://first\r\n'):
|
||||||
|
with self.subTest(raw=raw):
|
||||||
|
self.write(self.owner + '.uid', raw)
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.snapshot()
|
||||||
|
|
||||||
|
def test_duplicate_and_existing_collision(self):
|
||||||
|
for raw in (b'uid://second\n', b'uid://existing\n'):
|
||||||
|
with self.subTest(raw=raw):
|
||||||
|
self.write(self.owner + '.uid', raw)
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.snapshot()
|
||||||
|
|
||||||
|
def test_modified_original(self):
|
||||||
|
for name in (self.owner, 'project.godot', 'scripts/existing.gd.uid'):
|
||||||
|
with self.subTest(name=name):
|
||||||
|
path = self.stage / name
|
||||||
|
original = path.read_bytes()
|
||||||
|
path.write_bytes(original + b'tamper')
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.snapshot()
|
||||||
|
path.write_bytes(original)
|
||||||
|
|
||||||
|
def test_symlink(self):
|
||||||
|
path = self.stage / (self.owner + '.uid')
|
||||||
|
path.unlink()
|
||||||
|
path.symlink_to(self.stage / (self.other + '.uid'))
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.snapshot()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
extends "res://tests/special/peeping_room_fixture.gd"
|
||||||
|
|
||||||
|
func _run() -> void:
|
||||||
|
var f := fixture()
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
var room := place(f)
|
||||||
|
var other := place(f, Vector3i(-4, 1, 1))
|
||||||
|
var service: Variant = runtime.peeping_room_service
|
||||||
|
var minute: int = f[&"clock"].absolute_minute
|
||||||
|
expect(service.record_evidence(room, &"", minute)[&"reason"] == &"SOURCE_EVENT_KEY_REQUIRED", "named source key required first")
|
||||||
|
expect(service.controlled_fixture_record_evidence(room, &"fixture.event", minute)[&"reason"] == &"STOPPED", "initial stopped state rejects even fixture ledger")
|
||||||
|
enable_fixture(f, room)
|
||||||
|
enable_fixture(f, other)
|
||||||
|
var target: FacilityInstance = runtime.facility_service.get_instance(f[&"target"])
|
||||||
|
target.power_available = false
|
||||||
|
target.operator_open = false
|
||||||
|
expect(service.record_evidence(room, &"fixture.event", minute)[&"reason"] == &"NO_POWER", "power rejection precedes closed")
|
||||||
|
target.power_available = true
|
||||||
|
expect(service.record_evidence(room, &"fixture.event", minute)[&"reason"] == &"CLOSED", "closed target rejects")
|
||||||
|
target.operator_open = true
|
||||||
|
# CONTROLLED_FIXTURE temporarily omit construction authority, leaving live target.
|
||||||
|
var empty_construction := ConstructionService.new(runtime.world_service)
|
||||||
|
service.configure(runtime.world_service, runtime.facility_service, empty_construction, runtime.path_service, runtime.id_generator)
|
||||||
|
expect(service.record_evidence(room, &"fixture.event", minute)[&"reason"] == &"UNDER_CONSTRUCTION", "uncompleted construction authority rejects collection")
|
||||||
|
service.configure(runtime.world_service, runtime.facility_service, runtime.construction_service, runtime.path_service, runtime.id_generator)
|
||||||
|
var before := var_to_bytes(service.create_snapshot())
|
||||||
|
expect(service.record_evidence(room, &"fixture.event", minute)[&"reason"] == &"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16", "production collection never invents eligibility")
|
||||||
|
expect(before == var_to_bytes(service.create_snapshot()), "production collection leaves ledger unchanged")
|
||||||
|
var first: Dictionary = service.controlled_fixture_record_evidence(room, &"fixture.event", minute)
|
||||||
|
var replay: Dictionary = service.controlled_fixture_record_evidence(room, &"fixture.event", minute + 1)
|
||||||
|
expect(first[&"ok"] and not first[&"duplicated"] and replay[&"duplicated"] and replay[&"evidence_id"] == first[&"evidence_id"], "tuple replay returns exactly one stable ID")
|
||||||
|
var second: Dictionary = service.controlled_fixture_record_evidence(other, &"fixture.event", minute)
|
||||||
|
var third: Dictionary = service.controlled_fixture_record_evidence(room, &"fixture:event:日本語", minute)
|
||||||
|
expect(second[&"evidence_id"] != first[&"evidence_id"] and third[&"evidence_id"] != first[&"evidence_id"], "different room/key distinct, delimiter and UTF-8 input supported")
|
||||||
|
expect(service.create_snapshot()[&"evidence"].size() == 3, "replay adds no ledger record")
|
||||||
|
var snapshot: Dictionary = runtime.create_snapshot()
|
||||||
|
expect(runtime.restore_snapshot(snapshot), "active fixture evidence restores")
|
||||||
|
var restored: Dictionary = runtime.peeping_room_service.controlled_fixture_record_evidence(room, &"fixture.event", minute)
|
||||||
|
expect(restored[&"duplicated"] and restored[&"evidence_id"] == first[&"evidence_id"], "evidence stable across restore")
|
||||||
|
finish("Peeping room evidence")
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
extends "res://tests/special/peeping_room_fixture.gd"
|
||||||
|
|
||||||
|
func _run() -> void:
|
||||||
|
var f := fixture()
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
var service: Variant = runtime.peeping_room_service
|
||||||
|
var origin: Vector3i = f[&"origin"]
|
||||||
|
var before := var_to_bytes(runtime.create_snapshot())
|
||||||
|
expect(service.validate_placement(origin)[&"ok"], "public bath entirely behind one completed FRONT target")
|
||||||
|
expect(service.validate_placement(Vector3i(-6, 1, 0))[&"reason"] == &"WRONG_LAYER", "FRONT room rejected")
|
||||||
|
expect(service.validate_placement(origin, Vector2i(1, 2))[&"reason"] == &"WRONG_FOOTPRINT", "rotated footprint rejected")
|
||||||
|
expect(service.validate_placement(origin, Vector2i(2, 1), &"vip_suite")[&"reason"] == &"PENDING_P10_01", "VIP unavailable, never substituted")
|
||||||
|
expect(service.validate_placement(Vector3i(-1, 1, 1))[&"reason"] == &"PARTIAL_TARGET", "partial target rejected")
|
||||||
|
expect(service.validate_placement(Vector3i(8, 1, 1))[&"reason"] == &"TARGET_MISSING", "missing target rejected")
|
||||||
|
expect(service.validate_placement(origin, Vector2i(2, 1), &"missing")[&"reason"] == &"TARGET_MISMATCH", "named reference must match FRONT occupant")
|
||||||
|
expect(before == var_to_bytes(runtime.create_snapshot()), "geometry validation is pure across whole Runtime")
|
||||||
|
# Complete real second bath; the 2x1 footprint at the boundary spans targets.
|
||||||
|
expect(runtime.submit_command(&"build_facility", {&"definition_id": &"public_bath", &"origin": Vector3i(0, 0, 0)}).is_success(), "second paid target starts")
|
||||||
|
expect(service.validate_placement(Vector3i(0, 1, 1))[&"reason"] == &"TARGET_INCOMPLETE", "construction reservation is not a completed target")
|
||||||
|
f[&"clock"].advance_minutes(runtime.definition_registry.get_facility(&"public_bath").build_minutes)
|
||||||
|
expect(service.validate_placement(Vector3i(-1, 1, 1))[&"reason"] == &"MULTIPLE_TARGETS", "multiple FRONT target footprints rejected")
|
||||||
|
# A real path joining both sides through the proposed footprint must survive.
|
||||||
|
for x in range(-7, -3): runtime.world_service.set_walkable(Vector3i(x, 1, 1), true)
|
||||||
|
expect(runtime.rebuild_path_graph_from_world(), "CONTROLLED_FIXTURE corridor graph rebuild")
|
||||||
|
var path_before: Array = runtime.path_service.find_path(Vector3i(-7, 1, 1), Vector3i(-4, 1, 1))
|
||||||
|
expect(not path_before.is_empty(), "proposed footprint lies across a connected corridor")
|
||||||
|
expect(service.validate_placement(origin)[&"reason"] == &"CORRIDOR_CONFLICT", "would disconnect BACK corridor: reject with no bypass")
|
||||||
|
expect(runtime.path_service.find_path(Vector3i(-7, 1, 1), Vector3i(-4, 1, 1)) == path_before, "rejected cut preserves route")
|
||||||
|
for x in range(-7, -3): runtime.world_service.set_walkable(Vector3i(x, 1, 1), false)
|
||||||
|
expect(service.validate_placement(origin)[&"reason"] == &"CORRIDOR_CONFLICT", "stale path authority also rejects conflict")
|
||||||
|
expect(runtime.rebuild_path_graph_from_world(), "corridor fixture removed explicitly")
|
||||||
|
var room := place(f)
|
||||||
|
expect(service.validate_placement(origin)[&"reason"] == &"BACK_OCCUPIED", "dedicated room occupancy blocks overlap")
|
||||||
|
expect(runtime.world_service.get_entity_kind(room) == Rooms.OCCUPANCY_KIND, "dedicated cross-reference occupancy kind")
|
||||||
|
_private_geometry()
|
||||||
|
finish("Peeping room geometry")
|
||||||
|
|
||||||
|
func _private_geometry() -> void:
|
||||||
|
var f := fixture(false)
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
# CONTROLLED_FIXTURE underground geometry only: no unlock/normal palette claim.
|
||||||
|
var bounds: Dictionary = runtime.world_service.get_bounds()
|
||||||
|
bounds[&"min_y"] = -1
|
||||||
|
expect(runtime.world_service.expand_bounds(bounds), "CONTROLLED_FIXTURE underground bounds")
|
||||||
|
var definition: FacilityDefinition = runtime.definition_registry.get_facility(&"adult_private_room")
|
||||||
|
for x in range(2):
|
||||||
|
var cell := Vector3i(x, -1, 0)
|
||||||
|
runtime.world_service.set_excavated(cell, true)
|
||||||
|
runtime.world_service.set_support(cell, definition.weight_per_cell, true)
|
||||||
|
var started: CommandResult = runtime.construction_service.start_construction(definition, Vector3i(0, -1, 0))
|
||||||
|
expect(started.is_success(), "CONTROLLED_FIXTURE paid real adult_private_room definition")
|
||||||
|
f[&"clock"].advance_minutes(definition.build_minutes)
|
||||||
|
var service: Variant = runtime.peeping_room_service
|
||||||
|
expect(service.validate_placement(Vector3i(0, -1, 1))[&"ok"], "adult_private_room valid completed geometry")
|
||||||
|
var target_id: StringName = runtime.world_service.get_occupant(Vector3i(0, -1, 0))
|
||||||
|
var target: FacilityInstance = runtime.facility_service.get_instance(target_id)
|
||||||
|
if target != null:
|
||||||
|
target.definition_id = &"vip_private_salon"
|
||||||
|
expect(service.validate_placement(Vector3i(0, -1, 1))[&"reason"] == &"TARGET_NOT_ALLOWED", "salon is not VIP suite substitute")
|
||||||
|
target.definition_id = &"adult_private_room"
|
||||||
|
runtime.facility_service.unregister_instance(target_id)
|
||||||
|
expect(service.validate_placement(Vector3i(0, -1, 1))[&"reason"] == &"TARGET_UNKNOWN", "world occupant without actual FacilityService target rejected")
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
extends "res://tests/special/peeping_room_fixture.gd"
|
||||||
|
|
||||||
|
func _run() -> void:
|
||||||
|
var f := fixture()
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
var room := place(f)
|
||||||
|
enable_fixture(f, room)
|
||||||
|
var old_target: StringName = f[&"target"]
|
||||||
|
var old_evidence: Dictionary = runtime.peeping_room_service.controlled_fixture_record_evidence(room, &"fixture.event", f[&"clock"].absolute_minute)
|
||||||
|
expect(old_evidence[&"ok"], "fixture evidence before removal")
|
||||||
|
expect(runtime.submit_command(&"demolish_facility", {&"instance_id": old_target}).is_success(), "real Runtime demolition")
|
||||||
|
var lost: Dictionary = runtime.peeping_room_service.get_room(room)
|
||||||
|
expect(lost[&"link_state"] == &"TARGET_LOST" and lost[&"stopped"], "target removal immediately marks lost and stopped")
|
||||||
|
expect(runtime.peeping_room_service.record_evidence(room, &"fixture.after_loss", f[&"clock"].absolute_minute)[&"reason"] == &"STOPPED", "collection rejected after loss with prescribed stopped precedence")
|
||||||
|
expect(not runtime.peeping_room_service.controlled_fixture_set_stopped(room, false), "lost target cannot resume even through fixture")
|
||||||
|
var lost_snapshot: Dictionary = runtime.create_snapshot()
|
||||||
|
expect(runtime.restore_snapshot(lost_snapshot), "lost reference roundtrip retains historical identity")
|
||||||
|
expect(var_to_bytes(lost_snapshot) == var_to_bytes(runtime.create_snapshot()), "lost snapshot exact typed roundtrip")
|
||||||
|
expect(runtime.submit_command(&"build_facility", {&"definition_id": &"public_bath", &"origin": Vector3i(-6, 0, 0)}).is_success(), "rebuild at same geometry starts")
|
||||||
|
f[&"clock"].advance_minutes(runtime.definition_registry.get_facility(&"public_bath").build_minutes)
|
||||||
|
var new_target: StringName = runtime.world_service.get_occupant(Vector3i(-6, 0, 0))
|
||||||
|
expect(new_target != old_target, "rebuild receives different target identity")
|
||||||
|
expect(runtime.peeping_room_service.get_room(room)[&"target_instance_id"] == old_target, "no implicit relink on geometry reuse")
|
||||||
|
var rejected: CommandResult = runtime.submit_command(&"peeping_room_relink", {&"room_id": room, &"target_instance_id": old_target})
|
||||||
|
expect(not rejected.is_success(), "explicit old target relink rejected")
|
||||||
|
expect(runtime.submit_command(&"peeping_room_relink", {&"room_id": room, &"target_instance_id": new_target}).is_success(), "explicit new target full validation")
|
||||||
|
var linked: Dictionary = runtime.peeping_room_service.get_room(room)
|
||||||
|
expect(linked[&"stopped"] and linked[&"stop_reason"] == &"RELINKED_PENDING_RESUME", "explicit relink never auto resumes")
|
||||||
|
f[&"target"] = new_target
|
||||||
|
enable_fixture(f, room)
|
||||||
|
var new_evidence: Dictionary = runtime.peeping_room_service.controlled_fixture_record_evidence(room, &"fixture.event", f[&"clock"].absolute_minute)
|
||||||
|
expect(new_evidence[&"ok"] and new_evidence[&"evidence_id"] != old_evidence.get(&"evidence_id"), "same room/event on different target never aliases")
|
||||||
|
var linked_snapshot: Dictionary = runtime.create_snapshot()
|
||||||
|
expect(runtime.restore_snapshot(linked_snapshot) and var_to_bytes(linked_snapshot) == var_to_bytes(runtime.create_snapshot()), "relinked ledger keeps both historical target bindings")
|
||||||
|
expect(runtime.facility_service.unregister_instance(new_target).is_success(), "equivalent FacilityService removal path")
|
||||||
|
expect(runtime.peeping_room_service.get_room(room)[&"link_state"] == &"TARGET_LOST", "unregister signal also invalidates target")
|
||||||
|
finish("Peeping room reference")
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
extends "res://tests/special/peeping_room_fixture.gd"
|
||||||
|
|
||||||
|
func _run() -> void:
|
||||||
|
var f := fixture()
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
# Direct executor invocation distinguishes read-only domain state from queue receipts.
|
||||||
|
var validation := SimulationCommand.new()
|
||||||
|
validation.command_type = &"peeping_room_validate"
|
||||||
|
validation.payload = {&"origin": f[&"origin"]}
|
||||||
|
var before := var_to_bytes(runtime.create_snapshot())
|
||||||
|
expect(runtime._execute_peeping_room(validation).is_success(), "read-only validator executor")
|
||||||
|
expect(before == var_to_bytes(runtime.create_snapshot()), "validator changes no whole Runtime bytes")
|
||||||
|
var public_validation: CommandResult = runtime.submit_command(&"peeping_room_validate", validation.payload)
|
||||||
|
expect(public_validation.is_success(), "registered validation command runs through real queue")
|
||||||
|
var placement := SimulationCommand.new()
|
||||||
|
placement.command_type = &"peeping_room_place"
|
||||||
|
placement.payload = validation.payload.duplicate(true)
|
||||||
|
var placement_before := var_to_bytes(runtime.create_snapshot())
|
||||||
|
var direct_unavailable: CommandResult = runtime._execute_peeping_room(placement)
|
||||||
|
expect(not direct_unavailable.is_success() and direct_unavailable.details[&"reason"] == &"BUILD_DEFINITION_PENDING_D04", "direct production placement unavailable with precise reason")
|
||||||
|
expect(placement_before == var_to_bytes(runtime.create_snapshot()), "direct placement adds no room, occupancy, cost or ID in whole typed Runtime")
|
||||||
|
var domain_before := var_to_bytes([runtime.world_service.create_snapshot(), runtime.economy_service.create_snapshot(), runtime.peeping_room_service.create_snapshot()])
|
||||||
|
var ids_before: Dictionary = runtime.id_generator.create_snapshot()
|
||||||
|
var counters_before: Dictionary = ids_before["counters"]
|
||||||
|
var event_counter_before: int = counters_before.get("domain_event", 0)
|
||||||
|
var event_ids_before := {}
|
||||||
|
for event: SimulationDomainEvent in runtime.domain_events.recent_events():
|
||||||
|
event_ids_before[event.event_id] = true
|
||||||
|
var unavailable: CommandResult = runtime.submit_command(&"peeping_room_place", validation.payload)
|
||||||
|
expect(not unavailable.is_success() and unavailable.details[&"reason"] == &"BUILD_DEFINITION_PENDING_D04", "production placement unavailable with precise reason")
|
||||||
|
expect(domain_before == var_to_bytes([runtime.world_service.create_snapshot(), runtime.economy_service.create_snapshot(), runtime.peeping_room_service.create_snapshot()]), "queued placement adds no room, occupancy or cost")
|
||||||
|
var ids_after: Dictionary = runtime.id_generator.create_snapshot()
|
||||||
|
var counters_after: Dictionary = ids_after["counters"]
|
||||||
|
expect(ids_before["version"] == ids_after["version"], "queued placement preserves ID generator version")
|
||||||
|
for prefix: Variant in counters_before:
|
||||||
|
if prefix != "domain_event":
|
||||||
|
expect(counters_after.has(prefix) and counters_after.get(prefix) == counters_before[prefix], "queued placement consumes no non-event ID or removes prefix: %s" % prefix)
|
||||||
|
for prefix: Variant in counters_after:
|
||||||
|
if prefix != "domain_event":
|
||||||
|
expect(counters_before.has(prefix), "queued placement adds no non-event ID prefix: %s" % prefix)
|
||||||
|
expect(counters_after.has("domain_event") and counters_after["domain_event"] == event_counter_before + 1, "queued placement allocates exactly one normal receipt event ID")
|
||||||
|
var new_events: Array[SimulationDomainEvent] = []
|
||||||
|
for event: SimulationDomainEvent in runtime.domain_events.recent_events():
|
||||||
|
if not event_ids_before.has(event.event_id):
|
||||||
|
new_events.append(event)
|
||||||
|
expect(new_events.size() == 1, "queued placement publishes exactly one new receipt event")
|
||||||
|
if new_events.size() == 1:
|
||||||
|
var receipt: SimulationDomainEvent = new_events[0]
|
||||||
|
expect(receipt.event_id == StringName("domain_event.%012d" % (event_counter_before + 1)), "placement receipt uses the next domain event ID")
|
||||||
|
expect(receipt.event_type == &"COMMAND_FAILED", "unavailable placement receipt is COMMAND_FAILED")
|
||||||
|
expect(receipt.causation_command_id == unavailable.command_id, "placement receipt causation matches rejected command")
|
||||||
|
var room := place(f)
|
||||||
|
enable_fixture(f, room)
|
||||||
|
var blocked: CommandResult = runtime.submit_command(&"peeping_room_record_evidence", {&"room_id": room, &"source_event_key": &"fixture.command"})
|
||||||
|
expect(not blocked.is_success() and blocked.details[&"reason"] == &"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16", "registered evidence command cannot reach ledger")
|
||||||
|
var missing: CommandResult = runtime.submit_command(&"peeping_room_record_evidence", {&"room_id": room})
|
||||||
|
expect(not missing.is_success() and missing.details[&"reason"] == &"SOURCE_EVENT_KEY_REQUIRED", "public command requires named key")
|
||||||
|
var malformed: CommandResult = runtime.submit_command(&"peeping_room_validate", {&"origin": [0, 1, 1]})
|
||||||
|
expect(not malformed.is_success() and malformed.details[&"reason"] == &"INVALID_PAYLOAD", "wrong payload type safely rejected")
|
||||||
|
expect(runtime.peeping_room_service.create_snapshot()[&"evidence"].is_empty(), "commands cannot inject arbitrary content events")
|
||||||
|
var fixture_command: CommandResult = runtime.submit_command(&"controlled_fixture_place", validation.payload)
|
||||||
|
expect(not fixture_command.is_success(), "no fixture command registration")
|
||||||
|
_mimi_format(f)
|
||||||
|
finish("Peeping room runtime")
|
||||||
|
|
||||||
|
func _mimi_format(f: Dictionary) -> void:
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
const Quote := preload("res://scripts/supply/supply_purchase_quote_v2.gd")
|
||||||
|
expect(runtime.submit_command(&"build_facility", {&"definition_id": &"warehouse", &"origin": Vector3i(2, 0, 1)}).is_success(), "paid warehouse for independent existing MIMI format path")
|
||||||
|
f[&"clock"].advance_minutes(runtime.definition_registry.get_facility(&"warehouse").build_minutes)
|
||||||
|
var warehouse: StringName = &""
|
||||||
|
for facility: FacilityInstance in runtime.facility_service.get_instances():
|
||||||
|
if facility.definition_id == &"warehouse": warehouse = facility.instance_id
|
||||||
|
expect(not warehouse.is_empty(), "completed real warehouse")
|
||||||
|
var mimi := StaffRuntime.new().configure(Quote.MIMI, &"porter", {&"employment_kind": StaffRuntime.EmploymentKind.UNIQUE})
|
||||||
|
expect(runtime.staff_service.register_staff(mimi).is_success(), "CONTROLLED_FIXTURE existing MIMI unique registration, no natural join claim")
|
||||||
|
expect(runtime.submit_command(&"set_staff_work_assignment", {&"staff_id": Quote.MIMI, &"facility_id": warehouse, &"template_id": &"NIGHT"}).is_success(), "existing persistent MIMI assignment")
|
||||||
|
expect(runtime.submit_command(&"purchase_supplies", {&"warehouse_id": warehouse, &"item_id": SupplyCatalog.RAW_FOOD, &"quantity": 1}).is_success(), "existing real v2 paid purchase")
|
||||||
|
var snapshot: Dictionary = runtime.create_snapshot()
|
||||||
|
expect(snapshot[&"systems"][&"runtime"][&"runtime_schema_version"] == 15 and snapshot[&"systems"][&"runtime"].has(&"special_peeping_rooms"), "v2 purchase history and special section coexist")
|
||||||
|
expect(runtime.restore_snapshot(snapshot) and var_to_bytes(snapshot) == var_to_bytes(runtime.create_snapshot()), "v15 optional section exact typed restore")
|
||||||
|
var directory := "user://tests/p13_reference_mimi_%d" % OS.get_process_id()
|
||||||
|
expect(SaveService.save_snapshot(directory, snapshot)[&"ok"], "physical v15 save accepts validated extension without loosening purchase allowlist")
|
||||||
|
var loaded := SaveService.load_snapshot(directory)
|
||||||
|
expect(loaded[&"ok"], "physical MIMI section save loads")
|
||||||
|
if loaded[&"ok"]:
|
||||||
|
expect(loaded[&"manifest"]["format_version"] == 2 and loaded[&"manifest"]["runtime_schema_version"] == 15, "format2 manifest still exactly15")
|
||||||
|
expect(runtime.restore_snapshot(loaded[&"snapshot"]), "MIMI package restore reaches same staged section validator")
|
||||||
|
var bad := snapshot.duplicate(true)
|
||||||
|
bad[&"systems"][&"runtime"][&"special_peeping_rooms"][&"version"] = 2
|
||||||
|
expect(not SaveService.save_snapshot(directory + "_bad", bad)[&"ok"], "save-format adapter rejects malformed optional section")
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
extends "res://tests/special/peeping_room_fixture.gd"
|
||||||
|
|
||||||
|
func _run() -> void:
|
||||||
|
var f := fixture()
|
||||||
|
var runtime: Variant = f[&"runtime"]
|
||||||
|
var empty: Dictionary = runtime.create_snapshot()
|
||||||
|
expect(not empty[&"systems"][&"runtime"].has(&"special_peeping_rooms"), "empty service does not alter existing snapshot keys")
|
||||||
|
expect(runtime.restore_snapshot(empty) and var_to_bytes(empty) == var_to_bytes(runtime.create_snapshot()), "pre-extension v14 absence exact roundtrip")
|
||||||
|
var legacy := empty.duplicate(true)
|
||||||
|
legacy[&"systems"][&"runtime"][&"runtime_schema_version"] = 13
|
||||||
|
legacy[&"systems"][&"runtime"].erase(&"auto_purchase_plans")
|
||||||
|
expect(runtime.restore_snapshot(legacy) and runtime.peeping_room_service.is_empty(), "genuine v13 absent section migrates empty")
|
||||||
|
expect(runtime.restore_snapshot(empty), "restore canonical baseline before controlled room")
|
||||||
|
var room := place(f)
|
||||||
|
enable_fixture(f, room)
|
||||||
|
expect(runtime.peeping_room_service.controlled_fixture_record_evidence(room, &"fixture.save", f[&"clock"].absolute_minute)[&"ok"], "controlled evidence before mid-state save")
|
||||||
|
expect(runtime.submit_command(&"peeping_room_relink", {&"room_id": room, &"target_instance_id": f[&"target"]}, &"player", room, 0, f[&"clock"].absolute_minute + 1).is_success(), "future explicit relink remains pending at checkpoint")
|
||||||
|
var snapshot: Dictionary = runtime.create_snapshot()
|
||||||
|
expect(snapshot[&"systems"][&"runtime"][&"runtime_schema_version"] == 14, "extension never bumps Runtime version")
|
||||||
|
expect(runtime.restore_snapshot(snapshot) and var_to_bytes(snapshot) == var_to_bytes(runtime.create_snapshot()), "exact typed room/evidence whole Runtime roundtrip")
|
||||||
|
var directory := "user://tests/p13_reference_save_%d" % OS.get_process_id()
|
||||||
|
var saved := SaveService.save_snapshot(directory, snapshot)
|
||||||
|
expect(saved[&"ok"], "actual SaveService writes section in format 1")
|
||||||
|
var loaded := SaveService.load_snapshot(directory)
|
||||||
|
expect(loaded[&"ok"], "actual SaveService reads section")
|
||||||
|
if loaded[&"ok"]:
|
||||||
|
expect(loaded[&"manifest"]["format_version"] == 1, "existing format mapping unchanged")
|
||||||
|
expect(runtime.restore_snapshot(loaded[&"snapshot"]), "loaded physical package reaches Runtime validation")
|
||||||
|
expect(var_to_bytes(snapshot) == var_to_bytes(runtime.create_snapshot()), "physical save retains all typed fields")
|
||||||
|
for mutation in range(18):
|
||||||
|
var bad := snapshot.duplicate(true)
|
||||||
|
var data: Dictionary = bad[&"systems"][&"runtime"]
|
||||||
|
var section: Dictionary = data[&"special_peeping_rooms"]
|
||||||
|
match mutation:
|
||||||
|
0: data.erase(&"special_peeping_rooms")
|
||||||
|
1: data[&"special_peeping_rooms"] = null
|
||||||
|
2: section[&"version"] = 2
|
||||||
|
3: section[&"version"] = 1.0
|
||||||
|
4: section[&"unknown"] = true
|
||||||
|
5: section.erase(&"evidence")
|
||||||
|
6: section[&"rooms"].append(section[&"rooms"][0].duplicate(true))
|
||||||
|
7: section[&"evidence"].append(section[&"evidence"][0].duplicate(true))
|
||||||
|
8: section[&"rooms"][0][&"target_instance_id"] = &"missing.target"
|
||||||
|
9: section[&"rooms"][0][&"target_definition_id"] = &"adult_private_room"
|
||||||
|
10: section[&"rooms"][0][&"origin"] = Vector3i(8, 1, 1)
|
||||||
|
11: section[&"rooms"][0][&"stopped"] = 1
|
||||||
|
12: section[&"evidence"][0][&"room_id"] = &"peeping_room.999999999999"
|
||||||
|
13: section[&"evidence"][0][&"source_event_key"] = &"aliased.event"
|
||||||
|
14: section[&"evidence"][0][&"minute"] = f[&"clock"].absolute_minute + 1
|
||||||
|
15: data[&"id_generator"]["counters"]["peeping_room"] = 0
|
||||||
|
16:
|
||||||
|
section.erase(&"version")
|
||||||
|
section["version"] = 1
|
||||||
|
17:
|
||||||
|
section[&"rooms"][0][&"link_state"] = &"TARGET_LOST"
|
||||||
|
section[&"rooms"][0][&"stopped"] = true
|
||||||
|
section[&"rooms"][0][&"stop_reason"] = &"TARGET_LOST"
|
||||||
|
expect(rejects_atomically(runtime, bad), "malformed/current missing/reference/duplicate rejection atomic case %d" % mutation)
|
||||||
|
var orphan := empty.duplicate(true)
|
||||||
|
orphan[&"systems"][&"runtime"][&"world"] = snapshot[&"systems"][&"runtime"][&"world"].duplicate(true)
|
||||||
|
expect(rejects_atomically(runtime, orphan), "world-owned room without any section rejects atomically")
|
||||||
|
var removed_world := snapshot.duplicate(true)
|
||||||
|
removed_world[&"systems"][&"runtime"][&"world"] = empty[&"systems"][&"runtime"][&"world"].duplicate(true)
|
||||||
|
expect(rejects_atomically(runtime, removed_world), "section-owned room without world occupancy rejects atomically")
|
||||||
|
expect(runtime.restore_snapshot(empty) and runtime.peeping_room_service.is_empty(), "absent legacy section clears previous nonempty service on valid load")
|
||||||
|
finish("Peeping room save")
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""P13 reference evidence: read-only verification by default; collection is Root-only."""
|
||||||
|
import argparse
|
||||||
|
import ast
|
||||||
|
import inspect
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import stat
|
||||||
|
import types
|
||||||
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.dont_write_bytecode = True
|
||||||
|
import run_all_tests as shared
|
||||||
|
|
||||||
|
PROTOCOL = 'guarded-p13-reference-v1'
|
||||||
|
CANONICAL_EVIDENCE = 'p13-reference-native-uid-corrected'
|
||||||
|
NEW_TESTS = [
|
||||||
|
'tests/special/test_peeping_room_geometry.gd',
|
||||||
|
'tests/special/test_peeping_room_reference.gd',
|
||||||
|
'tests/special/test_peeping_room_evidence.gd',
|
||||||
|
'tests/special/test_peeping_room_save.gd',
|
||||||
|
'tests/special/test_peeping_room_runtime.gd',
|
||||||
|
]
|
||||||
|
ROSTER = NEW_TESTS + [
|
||||||
|
'tests/s1/test_construction_service.gd',
|
||||||
|
'tests/s1/test_world_service.gd',
|
||||||
|
'tests/s1/test_path_service.gd',
|
||||||
|
'tests/s1/test_runtime_world_construction.gd',
|
||||||
|
'tests/supply/test_supply_save_migration.gd',
|
||||||
|
'tests/transport/test_transport_save.gd',
|
||||||
|
'tests/environment/test_runtime_weather.gd',
|
||||||
|
'tests/s6/test_runtime_snapshot_serialization.gd',
|
||||||
|
'tests/s6/test_runtime_save_lifecycle.gd',
|
||||||
|
'tests/supply/test_mimi_purchase_quote.gd',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def uid_plan(refs):
|
||||||
|
return {name + '.uid': {'owner': name, 'owner_sha256': pin['sha256'],
|
||||||
|
'file_type': 'regular'}
|
||||||
|
for name, pin in sorted(refs.items())
|
||||||
|
if name.endswith('.gd') and name + '.uid' not in refs
|
||||||
|
and (name.startswith('tests/special/')
|
||||||
|
or name == 'scripts/special/peeping_room_service.gd')}
|
||||||
|
|
||||||
|
|
||||||
|
def uid_snapshot(stage, source, plan):
|
||||||
|
"""Accept exactly the source inventory and finite native UID plan."""
|
||||||
|
actual = shared.inventory(stage, stage=True)
|
||||||
|
shared.require(set(actual) == set(source) | set(plan), 'exact source and planned UID set')
|
||||||
|
shared.require({n: actual[n] for n in source} == source, 'original source/settings unchanged')
|
||||||
|
seen = set()
|
||||||
|
for name in source:
|
||||||
|
if name.endswith('.uid'):
|
||||||
|
raw = (stage / name).read_bytes().rstrip(b'\r\n')
|
||||||
|
shared.require(raw not in seen, 'existing project UID collision')
|
||||||
|
seen.add(raw)
|
||||||
|
result = {}
|
||||||
|
for name, binding in plan.items():
|
||||||
|
path = stage / name
|
||||||
|
shared.require(stat.S_ISREG(path.lstat().st_mode) and not path.is_symlink()
|
||||||
|
and path.stat().st_nlink == 1, 'ordinary generated UID')
|
||||||
|
raw = path.read_bytes()
|
||||||
|
shared.require(re.fullmatch(rb'uid://[a-z0-9]{1,13}\n', raw) is not None,
|
||||||
|
'complete canonical UID bytes')
|
||||||
|
shared.require(raw.rstrip(b'\n') not in seen, 'generated UID collision')
|
||||||
|
seen.add(raw.rstrip(b'\n'))
|
||||||
|
shared.require(stat.S_ISREG((stage / binding['owner']).lstat().st_mode)
|
||||||
|
and shared.sha(stage / binding['owner']) == binding['owner_sha256'],
|
||||||
|
'UID owner content binding')
|
||||||
|
result[name] = dict(binding, bytes=len(raw), raw_bytes=list(raw),
|
||||||
|
sha256=shared.sha(path), text=raw.decode('ascii'))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def install_uid_policy(namespace):
|
||||||
|
"""Specialize private globals; shared and P18 functions remain untouched."""
|
||||||
|
original_collect, original_seal = namespace['collect'], namespace['seal']
|
||||||
|
state = {}
|
||||||
|
|
||||||
|
def reports(stage, expected, previous, requested):
|
||||||
|
shared.require(not requested and not previous, 'P13 has no generated reports')
|
||||||
|
snapshot = uid_snapshot(stage, state['source'], state['plan'])
|
||||||
|
if state['accepted'] is None:
|
||||||
|
shared.require(state['phase'] == 'import', 'UID generation only during import')
|
||||||
|
state['accepted'] = snapshot
|
||||||
|
expected.update({n: {'bytes': p['bytes'], 'sha256': p['sha256']}
|
||||||
|
for n, p in snapshot.items()})
|
||||||
|
shared.require(snapshot == state['accepted'], 'sealed UID bytes unchanged')
|
||||||
|
return shared.declared_reports(stage, expected, previous, requested)
|
||||||
|
|
||||||
|
phase_globals = dict(vars(shared), declared_reports=reports)
|
||||||
|
execute = types.FunctionType(shared.execute_phase.__code__, phase_globals)
|
||||||
|
|
||||||
|
def phase(*args):
|
||||||
|
stage, out, label = args[1:4]
|
||||||
|
state['phase'] = label
|
||||||
|
if label == 'import':
|
||||||
|
shared.require(shared.inventory(stage, stage=True) == state['source'],
|
||||||
|
'original stage before import')
|
||||||
|
before = {}
|
||||||
|
shared.write(out / 'uid-plan.json', state['plan'])
|
||||||
|
else:
|
||||||
|
before = uid_snapshot(stage, state['source'], state['plan'])
|
||||||
|
shared.require(before == state['accepted'], 'UID set before phase unchanged')
|
||||||
|
row = execute(*args)
|
||||||
|
after = uid_snapshot(stage, state['source'], state['plan'])
|
||||||
|
shared.require(after == state['accepted'], 'UID set after phase unchanged')
|
||||||
|
shared.write(out / (label + '-uids.json'), {'before': before, 'after': after})
|
||||||
|
return row
|
||||||
|
|
||||||
|
namespace['shared'] = types.SimpleNamespace(**dict(vars(shared), execute_phase=phase))
|
||||||
|
|
||||||
|
def collect(args, root, out, refs, *rest):
|
||||||
|
state.update(source=namespace['content_map'](refs), plan=uid_plan(refs), accepted=None)
|
||||||
|
return original_collect(args, root, out, refs, *rest)
|
||||||
|
|
||||||
|
def seal(out, refs, engine, contract_sha):
|
||||||
|
shared.write(out / 'accepted-uids.json', state['accepted'])
|
||||||
|
return original_seal(out, refs, engine, contract_sha)
|
||||||
|
|
||||||
|
def retained(stage, source, out):
|
||||||
|
plan = namespace['read_json'](out / 'uid-plan.json')
|
||||||
|
shared.require(plan == uid_plan(source), 'independently derived exact UID plan')
|
||||||
|
accepted = uid_snapshot(stage, source, plan)
|
||||||
|
shared.require(namespace['read_json'](out / 'accepted-uids.json') == accepted,
|
||||||
|
'retained raw UID bytes and owner bindings')
|
||||||
|
for label in ['import', 'parse'] + [str(i).zfill(3) for i in range(len(ROSTER))]:
|
||||||
|
shared.require(namespace['read_json'](out / (label + '-uids.json')) ==
|
||||||
|
{'before': {} if label == 'import' else accepted, 'after': accepted},
|
||||||
|
'all phase UID before/after seals')
|
||||||
|
return True
|
||||||
|
|
||||||
|
namespace.update(collect=collect, seal=seal, uid_retained=retained)
|
||||||
|
|
||||||
|
|
||||||
|
def protocol_core():
|
||||||
|
"""Reuse P18's complete guarded core without editing or copying its runner.
|
||||||
|
|
||||||
|
P18 predates configurable protocol/roster constants. Specialize its three
|
||||||
|
entry functions' identity literals and explicit roster cardinalities, plus
|
||||||
|
one retained-stage comparison for the finite UID policy. The local phase
|
||||||
|
adapter retains every original shared gate and seals its accepted sidecars.
|
||||||
|
Fail closed if an upstream function changes any of these adapter sites.
|
||||||
|
Both runner sources remain bound by the whole selected source map.
|
||||||
|
"""
|
||||||
|
core = shared.module('p13_p18_core', shared.HERE / 'run_p18_relationship_tests.py')
|
||||||
|
namespace = dict(vars(core), ROSTER=ROSTER, __file__=__file__)
|
||||||
|
replacements = {
|
||||||
|
'guarded-p18-v2': PROTOCOL,
|
||||||
|
'tools/run_p18_relationship_tests.py': 'tools/run_p13_reference_tests.py',
|
||||||
|
'exact seven unique tests': 'exact unique P13 roster',
|
||||||
|
'exact nine phases': 'exact P13 phase count',
|
||||||
|
'all nine captured engines': 'all P13 captured engines',
|
||||||
|
}
|
||||||
|
cardinalities = {
|
||||||
|
'len(set(ROSTER)) == 7': 'len(set(ROSTER)) == len(ROSTER)',
|
||||||
|
'len(phases) == 9': 'len(phases) == len(ROSTER) + 2',
|
||||||
|
"len(tests) == 7": 'len(tests) == len(ROSTER)',
|
||||||
|
}
|
||||||
|
|
||||||
|
class Specialize(ast.NodeTransformer):
|
||||||
|
def __init__(self):
|
||||||
|
self.identities = 0
|
||||||
|
self.counts = 0
|
||||||
|
self.summary = 0
|
||||||
|
|
||||||
|
def visit_Constant(self, node):
|
||||||
|
if isinstance(node.value, str) and node.value in replacements:
|
||||||
|
self.identities += 1
|
||||||
|
return ast.copy_location(ast.Constant(replacements[node.value]), node)
|
||||||
|
return node
|
||||||
|
|
||||||
|
def visit_Compare(self, node):
|
||||||
|
expression = ast.unparse(node)
|
||||||
|
if expression in cardinalities:
|
||||||
|
self.counts += 1
|
||||||
|
return ast.copy_location(ast.parse(cardinalities[expression], mode='eval').body, node)
|
||||||
|
return self.generic_visit(node)
|
||||||
|
|
||||||
|
def visit_Dict(self, node):
|
||||||
|
for index, key in enumerate(node.keys):
|
||||||
|
if isinstance(key, ast.Constant) and key.value == 'actual_suites':
|
||||||
|
shared.require(isinstance(node.values[index], ast.Constant)
|
||||||
|
and node.values[index].value == 7, 'upstream suite summary unchanged')
|
||||||
|
node.values[index] = ast.parse('len(ROSTER)', mode='eval').body
|
||||||
|
self.summary += 1
|
||||||
|
return self.generic_visit(node)
|
||||||
|
|
||||||
|
expected = {'collect': (2, 0, 0), 'seal': (1, 0, 0), 'verify': (6, 3, 1)}
|
||||||
|
for name, counts in expected.items():
|
||||||
|
adapter = Specialize()
|
||||||
|
tree = adapter.visit(ast.parse(inspect.getsource(getattr(core, name))))
|
||||||
|
shared.require((adapter.identities, adapter.counts, adapter.summary) == counts,
|
||||||
|
'unchanged upstream adaptation sites: ' + name)
|
||||||
|
if name == 'verify':
|
||||||
|
old = "shared.inventory(confined(out, 'stage'), stage=True) == source"
|
||||||
|
matches = [node for node in ast.walk(tree)
|
||||||
|
if isinstance(node, ast.Compare) and ast.unparse(node) == old]
|
||||||
|
shared.require(len(matches) == 1, 'unchanged retained-stage UID adapter site')
|
||||||
|
|
||||||
|
class Retained(ast.NodeTransformer):
|
||||||
|
def visit_Compare(self, node):
|
||||||
|
if ast.unparse(node) == old:
|
||||||
|
return ast.copy_location(ast.parse(
|
||||||
|
"uid_retained(confined(out, 'stage'), source, out)", mode='eval').body, node)
|
||||||
|
return self.generic_visit(node)
|
||||||
|
|
||||||
|
tree = Retained().visit(tree)
|
||||||
|
exec(compile(ast.fix_missing_locations(tree), str(shared.HERE / 'run_p18_relationship_tests.py'), 'exec'), namespace)
|
||||||
|
install_uid_policy(namespace)
|
||||||
|
return namespace
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv=None):
|
||||||
|
argv = list(sys.argv[1:] if argv is None else argv)
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__, allow_abbrev=False)
|
||||||
|
parser.add_argument('--output')
|
||||||
|
modes = parser.add_mutually_exclusive_group()
|
||||||
|
modes.add_argument('--collect', action='store_true', help='Root only; fresh native collection')
|
||||||
|
modes.add_argument('--prepare-only', action='store_true')
|
||||||
|
seen, index = set(), 0
|
||||||
|
while index < len(argv):
|
||||||
|
flag = argv[index]
|
||||||
|
shared.require(flag in ('--output', '--collect', '--prepare-only', '--help')
|
||||||
|
and flag not in seen, 'unknown, duplicate or malformed flag')
|
||||||
|
seen.add(flag)
|
||||||
|
if flag == '--output':
|
||||||
|
index += 1
|
||||||
|
shared.require(index < len(argv) and argv[index] and not argv[index].startswith('--'), 'output value required')
|
||||||
|
index += 1
|
||||||
|
args = parser.parse_args(argv)
|
||||||
|
shared.require(not args.collect or args.output is not None, 'Root collection requires explicit --output')
|
||||||
|
if args.output is None:
|
||||||
|
base = os.environ.get('BUILD_OUTPUT_DIR')
|
||||||
|
shared.require(bool(base) and Path(base).is_absolute(), 'absolute BUILD_OUTPUT_DIR required')
|
||||||
|
args.output = str(Path(base) / CANONICAL_EVIDENCE)
|
||||||
|
args.timeout = 1200 # unchanged guarded core timeout; not a product value
|
||||||
|
core = protocol_core()
|
||||||
|
root = shared.HERE.parent
|
||||||
|
out = core['plain_path'](args.output)
|
||||||
|
refs = shared.source_refs(root)
|
||||||
|
shared.require(len(set(ROSTER)) == len(ROSTER) and set(ROSTER).issubset(shared.roster(root)), 'complete unique discovered roster')
|
||||||
|
markers = shared.module('p13_exact_markers', shared.HERE / 'strict_test_markers.py')
|
||||||
|
contract_path = root / 'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json'
|
||||||
|
contract_sha = shared.sha(contract_path)
|
||||||
|
contracts = markers.load_contracts(contract_path)
|
||||||
|
shared.require(all(name in contracts for name in ROSTER), 'complete marker roster')
|
||||||
|
policy = shared.read(shared.SUPPORT / 'suite-policy.json')
|
||||||
|
shared.policy_coverage(ROSTER, refs, policy)
|
||||||
|
for test in ROSTER:
|
||||||
|
shared.phase_policy(test, Path(refs[test]['path']), policy['suite_policies'])
|
||||||
|
for test in NEW_TESTS:
|
||||||
|
shared.require(contracts[test]['source_sha256_at_schema_audit'] == refs[test]['sha256'], 'new strict source-hashed marker')
|
||||||
|
parse_paths = ['res://' + name for name in sorted(refs) if name.endswith('.gd')]
|
||||||
|
if args.prepare_only:
|
||||||
|
ancestor = out.parent
|
||||||
|
while not ancestor.exists():
|
||||||
|
ancestor = ancestor.parent
|
||||||
|
free = shutil.disk_usage(ancestor).free
|
||||||
|
size = sum(pin['bytes'] for pin in refs.values())
|
||||||
|
print(json.dumps(dict(protocol=PROTOCOL, roster=ROSTER, source_files=len(refs),
|
||||||
|
source_bytes=size, free_bytes=free, conservative_required_bytes=size + shared.MIN_SPACE,
|
||||||
|
capacity_available=free >= size + shared.MIN_SPACE, parse_paths=len(parse_paths),
|
||||||
|
future_native_phases=len(ROSTER) + 2, actual_checks=None, engines=0, stages=0,
|
||||||
|
formal_acceptance=False, original_unit_complete=False)))
|
||||||
|
return 0
|
||||||
|
if args.collect:
|
||||||
|
shared.require(not out.exists() and out.parent.is_dir(), 'fresh output with existing parent required')
|
||||||
|
shared.require(not out.is_relative_to(root), 'private collection outside source tree')
|
||||||
|
return core['collect'](args, root, out, refs, markers, contracts, policy, contract_path, contract_sha, parse_paths)
|
||||||
|
return core['verify'](out, refs, markers, contracts, policy, contract_sha, parse_paths)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
raise SystemExit(main())
|
||||||
|
except (AssertionError, OSError, ValueError, KeyError, TypeError) as error:
|
||||||
|
print(type(error).__name__ + ': ' + str(error), file=sys.stderr)
|
||||||
|
raise SystemExit(1)
|
||||||
Reference in New Issue
Block a user