Compare commits

...
6 Commits
18 changed files with 679 additions and 25 deletions
+41 -11
View File
@@ -7573,18 +7573,38 @@ func _execute_leave_facility_queue(command: SimulationCommand) -> CommandResult:
return CommandResult.failed(CommandResult.Code.TRANSACTION_APPLY_FAILED, command.command_id, failure_message)
return CommandResult.succeeded(command.command_id, {&"request_id": request_id, &"reason": &"GUEST_LEFT"})
func _execute_build_facility(command: SimulationCommand) -> CommandResult:
var operations_gate := _operations_construction_investment_gate(command.command_id)
func preview_build_facility(definition_id: StringName, origin: Vector3i, rotation: int) -> Dictionary:
var definition := definition_registry.get_facility(definition_id)
var failure := _build_facility_precheck(0, {&"definition_id": definition_id, &"origin": origin, &"rotation": rotation})
if failure != null and definition == null:
var code := String(failure.details.get(&"reason", CommandResult.Code.keys()[failure.code]))
return {&"can_build": false, &"error_codes": [code],
&"reasons": [{&"code": code, &"message": failure.message, &"cells": [], &"details": failure.details.duplicate(true)}],
&"cells": []}
var report: Dictionary = construction_service.validate_placement(definition, origin, rotation).to_dictionary()
if failure != null:
report[&"can_build"] = false
var code := String(failure.details.get(&"reason", CommandResult.Code.keys()[failure.code]))
var codes: Array = Array(report.get(&"error_codes", []))
var reasons: Array = Array(report.get(&"reasons", []))
codes.push_front(code)
reasons.push_front({&"code": code, &"message": failure.message, &"cells": [], &"details": failure.details.duplicate(true)})
report[&"error_codes"] = codes
report[&"reasons"] = reasons
return report
func _build_facility_precheck(command_id: int, payload: Dictionary) -> CommandResult:
var operations_gate := _operations_construction_investment_gate(command_id)
if operations_gate != null:
return operations_gate
var definition_id := StringName(command.payload.get(&"definition_id", command.payload.get("definition_id", "")))
var definition_id := StringName(payload.get(&"definition_id", payload.get("definition_id", "")))
var definition := definition_registry.get_facility(definition_id)
if definition == null:
return CommandResult.failed(CommandResult.Code.NOT_FOUND, command.command_id, "Facility definition was not found.")
return CommandResult.failed(CommandResult.Code.NOT_FOUND, command_id, "Facility definition was not found.")
if _facility_definition_is_unsupported_vertical_proxy(definition):
return CommandResult.failed(
CommandResult.Code.VALIDATION_FAILED,
command.command_id,
command_id,
"Vertical infrastructure topology is not supported.",
{
&"reason": FacilityInfrastructureProjector.REASON_UNSUPPORTED_VERTICAL_TOPOLOGY,
@@ -7592,18 +7612,28 @@ func _execute_build_facility(command: SimulationCommand) -> CommandResult:
&"unchanged": true,
}
)
var origin_value: Variant = _parse_world_cell(command.payload.get(&"origin", command.payload.get("origin", null)))
var origin_value: Variant = _parse_world_cell(payload.get(&"origin", payload.get("origin", null)))
if origin_value == null:
return CommandResult.failed(CommandResult.Code.INVALID_PAYLOAD, command.command_id, "origin must be Vector3i or [x, y, layer].")
return CommandResult.failed(CommandResult.Code.INVALID_PAYLOAD, command_id, "origin must be Vector3i or [x, y, layer].")
var origin: Vector3i = origin_value
if definition.id in [&"guest_stairs", &"service_stairs"] and not path_service.has_cell(origin + Vector3i(0, -1, 0)):
return _staff_assignment_failure(command.command_id, &"STAIR_LANDING_MISSING", "先に階段の一つ下の階に通路を作ってください。")
return _staff_assignment_failure(command_id, &"STAIR_LANDING_MISSING", "先に階段の一つ下の階に通路を作ってください。")
for shaft: Dictionary in elevators.get_report()[&"shafts"]:
if _elevator_touches_module(shaft, definition, origin) and _elevator_shaft_busy(shaft):
return _staff_assignment_failure(command.command_id, &"ELEVATOR_BUSY", "Wait until the shaft is idle before extending it.")
var rotation := int(command.payload.get(&"rotation", command.payload.get("rotation", 0)))
return _staff_assignment_failure(command_id, &"ELEVATOR_BUSY", "Wait until the shaft is idle before extending it.")
var rotation := int(payload.get(&"rotation", payload.get("rotation", 0)))
if rotation not in definition.allowed_rotations:
return CommandResult.failed(CommandResult.Code.INVALID_PAYLOAD, command.command_id, "The selected rotation is not allowed.")
return CommandResult.failed(CommandResult.Code.INVALID_PAYLOAD, command_id, "The selected rotation is not allowed.")
return null
func _execute_build_facility(command: SimulationCommand) -> CommandResult:
var failure := _build_facility_precheck(command.command_id, command.payload)
if failure != null:
return failure
var definition_id := StringName(command.payload.get(&"definition_id", command.payload.get("definition_id", "")))
var definition := definition_registry.get_facility(definition_id)
var origin: Vector3i = _parse_world_cell(command.payload.get(&"origin", command.payload.get("origin", null)))
var rotation := int(command.payload.get(&"rotation", command.payload.get("rotation", 0)))
var result := construction_service.start_construction(
definition,
origin,
@@ -1,6 +1,6 @@
## 現在の対象(2026-10-13・現版監査更新)
2026-10-14 現在の閉鎖対象はP08-03。台帳は正式11/着手25/予定52で、今回の支援登録による加点は0。提出4775001の撤去表示・検証器修正を保持し、Opus 5.5の具体指示で既存案を再利用する共有Runtime支援P08-03-RTPREVIEWを6.1-solで実装中。支援は原88へ加点しない。旧R09は変更前の履歴証跡で、新版受入へ流用しない。関連修正を固め、正確な最終版で通常OS・全必須回帰・独立レビュー・統合を満たす。原30/88と部分点なしを維持し、未完了の条件を完了へ変更しない。容量整理済みで現在7.9GB空き。以下の過去の個別修正上限・容量削除承認待ちの記述は履歴であり、現在の停止理由ではない。
2026-10-14 現在の閉鎖対象はP08-03。台帳は正式11/着手25/予定52で、今回の支援登録による加点は0。提出4775001の撤去表示・検証器修正を保持し、Opus 5.5の具体指示で既存案を再利用する共有Runtime支援P08-03-RTPREVIEWは6.1-sol提出12f04d6で局所・影響4試験と独立OpusレビューPASS、同一ソース確認付き統合・最終検証を経てdbf5cb8で支援completed。原P08-03はUI接続・通常OS・全必須回帰・独立受入が残る。支援は原88へ加点しない。旧R09は変更前の履歴証跡で、新版受入へ流用しない。関連修正を固め、正確な最終版で通常OS・全必須回帰・独立レビュー・統合を満たす。原30/88と部分点なしを維持し、未完了の条件を完了へ変更しない。容量整理済みで現在7.9GB空き。以下の過去の個別修正上限・容量削除承認待ちの記述は履歴であり、現在の停止理由ではない。
原30パッケージ/88成果、部分点なし。現在は正式10/着手24/予定54。P24-03は正式完了、MP-01-r02承認用資料は正式統合済みだが原88へ加点しない。P13-03既存最終修正は全7施設/84スロット/6分類が保全済み。P13/RP13の限定追加修正と正式host自己試験は直接許可待ちで、重複実装や無断上限変更をしない。
@@ -305,5 +305,20 @@ if os.environ.get('OWNER_P08_SEMANTIC_REFERENCE_REVIEW') == '7e2368f5':
module.run(semantic_core)
sys.exit(0)
_runtime_support_verify = Runner.verify
def verify_exact_runtime_support(self, task_id, wt, sha, kind):
if self.config["project"] == "the-tree-p08-runtime-preview" and task_id == "P08-03-RTPREVIEW" and kind in ("integration", "final"):
import importlib.util
from runner.core import git, require
require(git(wt, "rev-parse", "HEAD") == sha, "exact support candidate")
path = Path("/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/execution/p08-03/runtime_support_proof.py")
spec = importlib.util.spec_from_file_location("owner_runtime_support_proof", path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
result = module.bind_exact_candidate(Path(wt), Path(self.allocation(task_id)["build_dir"]))
self.event(task_id, "exact_native_source_applicability", {"commit": sha, "kind": kind, "executed_native_candidate": result["executed_native_candidate"], "new_native_runs": 0})
return _runtime_support_verify(self, task_id, wt, sha, kind)
Runner.verify = verify_exact_runtime_support
from runner.cli import main
main()
@@ -7,9 +7,7 @@
"independent_review": "INDEPENDENT_SEMANTIC_REVIEW_7E2368F5.json",
"review_status": "changes_requested",
"missing": [
"shared readonly Runtime precheck and placement preview/command agreement",
"Main must display real rejection reason consistently",
"Opus recorded scope reconciliation for necessary Runtime/test changes",
"changed-product native/OS recollection after batch freezes",
"all mandatory regression suites on exact final candidate; derive actual roster after added targeted test",
"independent raw-proof read and all-five-condition review",
@@ -20,7 +18,7 @@
"denominator_units": 88,
"completed_delta": 0,
"formal_validator": "7e2368f5 only historical after changed Main/checker; current 4775001 not accepted",
"next_action": "One actual 6.1-sol worker fixes test initialization; preserve Runtime refactor and original P08 submitted 4775001",
"next_action": "Reuse completed dbf5cb8 shared Runtime in existing P08-03 task; preserve contract/spec and restrict next worker to UI/checker/fixture/marker scope",
"semantic_triage": "OPUS_PRE_FULL_SEMANTIC_TRIAGE_7E2368F5.json (read-only, no acceptance)",
"capacity": "cleanup complete: 7.94GB free; 580 closed stages archived losslessly; current R09 retained; no cleanup permission pending",
"implemented_not_accepted": [
@@ -30,14 +28,16 @@
"support_task": {
"id": "P08-03-RTPREVIEW",
"project": "the-tree-p08-runtime-preview",
"state": "implementing test-only repair1",
"state": "completed supporting component; adds0 original units",
"base": "d4747dd7e12e8fd19e404ad444bdc1e56d03f088",
"counting_scope": "zero additional original units",
"reuse": "4775001 unapplied Runtime/test proposal, reviewed by actual Opus",
"actual_pid_at_start": 9155,
"submitted": "78dc82da077dabbdb92ebcf475cd81c5d619bcf6",
"repairs": 1,
"native_result": "import/parse passed; first targeted suite failed eager autoload reference; owned engine ended and source/default guards preserved",
"next": "test initialization repair then exact target/impact validation"
"submitted": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"repairs": 2,
"native_result": "four guarded suites pass 80/67/105/50, all eight native purity pairs unchanged",
"next": "accepted-main dependency adoption and existing P08 UI connection",
"review": "INDEPENDENT_RUNTIME_SUPPORT_REVIEW_12F04D6.json",
"integration": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3"
}
}
@@ -0,0 +1,23 @@
{
"task_id": "P08-03-RTPREVIEW",
"commit": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"status": "pass",
"summary": "Checked against the original acceptance item P08-03-RTPREVIEW only (internal shared-runtime proof; does not add or close original P08-03/88 units, the UI hunk, or Windows acceptance). Scope: the diff touches only the three allowed files. No construction service, data, spec or main/UI code is edited, and no tests are deleted or disabled.\n\n(1) One shared read-only precheck: _build_facility_precheck(command_id, payload) is called by both preview_build_facility and _execute_build_facility. Its order is unchanged from base 7576-7615: operations gate, then NOT_FOUND, unsupported vertical, origin INVALID_PAYLOAD, STAIR_LANDING_MISSING, ELEVATOR_BUSY, and rotation INVALID_PAYLOAD. Codes and messages are byte-identical; only command.command_id was replaced by the command_id parameter. The execute path re-derives definition, origin and rotation the same way after the precheck passes.\n\n(2) Unknown definition: if the precheck fails and the definition is null, preview returns a 4-key summary (can_build=false, a single code/reason, cells=[]) without calling validate_placement. That covers both NOT_FOUND and an operations gate that fails before NOT_FOUND (UNPAID_EXPENSES with a null definition), which resolves Commander finding 2. For known definitions, the precheck reason is pushed to the front and the PlacementReport schema (code, message, cells, details) is kept. ConstructionService.validate_placement (construction_service.gd:56-108) only builds a report.\n\n(3) Purity: the test compares var_to_bytes(create_snapshot()), CommandQueue snapshot bytes, accepted/processed counts and domain event count before and after each preview. The guarded native log shows identical SHA-256 values and counts for all 8 observations.\n\n(4) Agreement: for every reachable precheck case (NOT_FOUND, operations with null and known definitions, unsupported vertical, landing, elevator before rotation, invalid rotation), the test asserts that preview's first code, message and details match the submit result. The positive case also agrees: preview can_build=true and the command succeeds after real lower stairs are completed. Origin INVALID_PAYLOAD is explicitly noted as unreachable through the Vector3i preview API, as the Commander direction allowed.\n\nThe Commander findings were addressed: the existing UNPAID_EXPENSES reason replaces the invented ARREARS_REMAIN, the required cases were added, the null guard was added, and the UID uses valid characters.\n\nEvidence: the root native run passed (80/0) for test_runtime_build_preview. Impact tests also passed: test_runtime_stairs 67/0, test_construction_service PASS 105, test_original_build_pointer 50/0. stderr is empty, there are no guard or cleanup errors, and the four proof negative controls were rejected. The runner validation re-checked the integrity of the proof JSON against the pinned source SHAs (exit 0).",
"acceptance_ids": [
"P08-03-RTPREVIEW"
],
"findings": [
{
"severity": "low",
"message": "The unsupported-vertical and operations precedence cases depend on test-only subclass overrides (block_vertical, block_operations). FacilityInfrastructureProjector.UNSUPPORTED_VERTICAL_KINDS is currently empty, so this branch cannot be reached with real data. The operations gate itself is real (enable_production_operations is called and the reason comes from the actual gate), so this is acceptable, but it should be retested if real unsupported kinds are added later."
},
{
"severity": "low",
"message": "When a precheck fails for a known definition, preview still adds the PlacementReport errors after the precheck reason (for example [\"STAIR_LANDING_MISSING\",\"UNSUPPORTED\"]), while submit returns only the precheck failure. The first code, message and details agree as required. Downstream UI/WorldPreview code must keep using error_codes[0]/reasons[0], as the Commander direction already specifies for repair 18."
},
{
"severity": "low",
"message": "The UID uid://dqx7m2k8n4vsa was hand-written. It uses only valid Godot UID characters, and the native import and parse showed no UID warnings, but it was not generated by the engine."
}
]
}
@@ -0,0 +1,7 @@
{
"action": "request-repair",
"task_id": "P08-03-RTPREVIEW",
"reason": "Root cause is in the test fixture, not Runtime. Runtime._build_facility_precheck (autoload/simulation_runtime.gd:7619) only checks path_service.has_cell for the stair landing. The test's diagnostic path injection at tests/transport/test_runtime_build_preview.gd:62-64 satisfies that check. Preview and command then both call ConstructionService.validate_placement (scripts/construction/construction_service.gd:56-108). That function runs _validate_cell_constraints (zone/layer/excavation/occupant) and _validate_support through world.validate_support. A path-only node at (-8,1,0) creates no world structural support, and (-8,2,0) is not shown to be a valid zone or excavated cell. So the precheck passes while validate_placement fails for both preview and command. Shared precheck behaviour is consistent, so there is no evidence of a production defect.\n\nRepair, confined to tests/transport/test_runtime_build_preview.gd (Runtime unchanged, no new values):\n(1) Replace the path_service.rebuild_graph injection at lines 61-64 with an actual structural fixture that mirrors tests/transport/test_runtime_stairs.gd:24-25,129-143. After _reset, submit a real build_facility for guest_stairs at (4,1,0). Then advance the clock by the registered definition_registry.get_facility(&\"guest_stairs\").build_minutes, read from the registry and not hard-coded. Assert that the facility exists at that origin. Then run the positive preview and command for guest_stairs at (4,2,0), rotation 0. If any budget is needed, take it from the registered construction_cost and the real fixture gold. Do not invent values.\n(2) On the positive case, add bounded failure diagnostics: one line with can_build, error_codes, the first reason code/message, the command code (details.reason or Code key) and the command message.\n(3) In _pure_preview, print one mandatory, bounded stdout line per preview for Root's registered proof. It must contain the case id/cell/rotation; SHA-256 via HashingContext of the exact var_to_bytes for snapshot before/after and command-queue snapshot before/after; command metadata and processed counts before/after; event counts before/after; and the report's can_build and error_codes. Do not print full snapshots.\n(4) Keep every existing negative case, precedence order, code/message/details agreement and purity check unchanged, and keep the real elevator busy case. Do not reset or reimplement counters, and do not loosen any assertion.\n\nWorker does static review only, with no Godot/native runs. Root then runs the corrected target guarded and isolated, followed by the remaining impact tests. No full regression before the P08 UI freeze.",
"codex_model": "gpt-6.1-sol",
"codex_model_reason": "The repair is a small edit to one test file with a confirmed root cause, and an existing fixture pattern (test_runtime_stairs.gd) shows exactly how to do it. No production logic, cross-module design or ambiguous semantics are involved. The default model is enough for quality, and gpt-6-astra would only add time and usage."
}
@@ -0,0 +1,7 @@
{
"action": "run",
"task_id": "P08-03-RTPREVIEW",
"reason": "Run the recorded repair on the preserved task P08-03-RTPREVIEW, which is in state repair_ready. I checked the claims against the source. In tests/transport/test_runtime_build_preview.gd:61-64 the positive case only puts a diagnostic walkable node into path_service.rebuild_graph at (-8,1,0). That clears the landing precheck, but it creates no world structural support, so ConstructionService.validate_placement rejects both the preview and the command. Runtime behaves consistently, so the defect is in the test fixture. tests/transport/test_runtime_stairs.gd:24-25 and 129-140 show the working pattern: a real guest_stairs at (4,1,0) and then (4,2,0), built from the existing fixture.\n\nWORKER DIRECTIONS. Edit only tests/transport/test_runtime_build_preview.gd. autoload/simulation_runtime.gd stays unchanged. Add no new rule values, codes, messages or order.\n\n(1) Delete lines 61-64, which hold the diagnostic walkable/rebuild_graph injection and its comment. In their place, call _reset() and build a real structural fixture. Submit build_facility for guest_stairs at Vector3i(4,1,0) with rotation 0 through the existing _command helper. Check is_success and include the message on failure. Advance _clock by the registered build time, read as _runtime.definition_registry.get_facility(&\"guest_stairs\").build_minutes; do not hard-code it. Then check that a facility exists whose origin is (4,1,0) in _runtime.construction_service.get_facilities(). After that, run the positive _pure_preview and _command for guest_stairs at Vector3i(4,2,0), rotation 0, and keep the agreement check. If the budget matters, rely only on the real fixture gold and the registered construction_cost. Do not invent values.\n\n(2) Positive case: if the agreement fails, print one bounded diagnostic line. It must contain report can_build, error_codes, the first reason's code and message (or none), the command code using the same expression as _failure_case (details.reason, or else the CommandResult.Code key), and the command message.\n\n(3) In _pure_preview, always print one bounded stdout line per preview for Root's proof. Include the case id, cell and rotation. Include SHA-256 hex digests computed with HashingContext (HASH_SHA256) over the exact var_to_bytes already computed for the snapshot before/after and the command_queue snapshot before/after. Capture the after bytes once and use them for both the hash and the existing equality checks. Also include the accepted-command metadata count and processed_count before/after, the domain_events recent_events count before/after, and the report's can_build and error_codes. Never print full snapshots or byte arrays.\n\n(4) Keep everything else exactly as it is: every existing negative _failure_case and its order/precedence, the cell (-8,2,0) for the negatives, the code/message/details agreement checks, the purity checks, the unknown-definition summary check and the real elevator busy case. Do not reset or reimplement counters, and do not loosen, remove or skip any assertion. The .uid file is untouched unless it is missing.\n\nVERIFICATION. The worker does a static diff review only. It runs no Godot, native, impact or full tests. In the handoff, the worker reports the diff and lists every check that has not been run as unrun. Root then runs the corrected target guarded and isolated, then the remaining impact tests. No full regression before the P08 UI freeze. Independent Opus review and integration remain Runner gates. This decision changes no scope, acceptance denominator, budget, cap or approval.",
"codex_model": "gpt-6.1-sol",
"codex_model_reason": "This is a small, single-file test-fixture edit, and the root cause is already confirmed. test_runtime_stairs.gd already shows the exact pattern to copy, and the work touches no production logic, cross-module design or unclear semantics. The default model is good enough for this, and gpt-6-astra would only cost more time and usage."
}
@@ -0,0 +1,23 @@
{
"synthetic_controls_only": true,
"controls": {
"synthetic_metadata_only_same_source": {
"passed": true,
"new_native_runs": 0
},
"source_drift": {
"rejected": true,
"reason": "changed native source cannot reuse evidence: autoload/simulation_runtime.gd"
},
"engine_drift": {
"rejected": true,
"reason": "changed native engine"
},
"marker_drift": {
"rejected": true,
"reason": "changed marker configuration"
}
},
"production_proof_unchanged": true,
"new_native_runs": 0
}
@@ -0,0 +1,82 @@
{
"contract": {
"id": "P08-03-RTPREVIEW",
"title": "P08-03を閉じるための共有配置プレビュー判定",
"requirement_ids": [
"P08-03"
],
"acceptance_ids": [
"P08-03-RTPREVIEW"
],
"spec_ref": "docs/spec/acceptance/P08-03-RTPREVIEW.json",
"base_commit": "d4747dd7e12e8fd19e404ad444bdc1e56d03f088",
"worker": "codex",
"allowed_paths": [
"autoload/simulation_runtime.gd",
"tests/transport/test_runtime_build_preview.gd",
"tests/transport/test_runtime_build_preview.gd.uid"
],
"depends_on": [],
"resource_locks": [
"p08-shared-build-runtime"
],
"validation_ids": [
"runtime-preview-proof"
],
"max_repair_attempts": null,
"spec_sha256": "949e00de465d86afd575ff03b7b575709fe0fc4d19d3b63a3a1a03929fe05969"
},
"implementation_commit": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"integration_commit": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3",
"owner": "User standing explicit main update authorization: mainの更新を明示的に許可します; reviewed original-P08 supporting fix only, no added original unit",
"evidence": [
{
"id": 1,
"task_id": "P08-03-RTPREVIEW",
"kind": "targeted_native",
"commit_sha": "78dc82da077dabbdb92ebcf475cd81c5d619bcf6",
"artifact": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p08-runtime-preview-78dc82d-targeted-r01/runner-ended.json",
"passed": 0
},
{
"id": 2,
"task_id": "P08-03-RTPREVIEW",
"kind": "targeted_native",
"commit_sha": "8d52b20d40884a41432152c9e94e6d83485268c6",
"artifact": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p08-runtime-preview-8d52b20-target-r02/runner-ended.json",
"passed": 0
},
{
"id": 3,
"task_id": "P08-03-RTPREVIEW",
"kind": "validation",
"commit_sha": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/bb00ad2fd31c4207b3ae5de42ca82330-validation.json",
"passed": 1
},
{
"id": 4,
"task_id": "P08-03-RTPREVIEW",
"kind": "review",
"commit_sha": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/8be4a0982cab42afa0c9e7545032f519/result.json",
"passed": 1
},
{
"id": 5,
"task_id": "P08-03-RTPREVIEW",
"kind": "integration",
"commit_sha": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3",
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/cc8188e650f64843b6c6f717962b2209-integration.json",
"passed": 1
},
{
"id": 6,
"task_id": "P08-03-RTPREVIEW",
"kind": "final",
"commit_sha": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3",
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/a7baf978d6734efd912b79e8cec0fc70-final.json",
"passed": 1
}
]
}
@@ -0,0 +1,58 @@
{
"submitted": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"integration": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3",
"runner_state": "completed",
"scope": "supporting P08-03 only; zero original units added",
"native_source": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"applicability": [
{
"previous_bound_commit": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"previous_proof_sha256": "769a37d564edb8f99b4bc1c7f5f3e11166637234dfb03bfad9c5c29778931302",
"bound_commit": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3",
"source_files_checked": 1318,
"source_byte_changes": 0,
"engine_and_marker_match": true,
"new_native_runs": 0,
"executed_native_candidate": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb"
}
],
"required_evidence": [
{
"kind": "targeted_native",
"commit": "78dc82da077dabbdb92ebcf475cd81c5d619bcf6",
"passed": 0,
"artifact": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p08-runtime-preview-78dc82d-targeted-r01/runner-ended.json"
},
{
"kind": "targeted_native",
"commit": "8d52b20d40884a41432152c9e94e6d83485268c6",
"passed": 0,
"artifact": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p08-runtime-preview-8d52b20-target-r02/runner-ended.json"
},
{
"kind": "validation",
"commit": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"passed": 1,
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/bb00ad2fd31c4207b3ae5de42ca82330-validation.json"
},
{
"kind": "review",
"commit": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"passed": 1,
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/8be4a0982cab42afa0c9e7545032f519/result.json"
},
{
"kind": "integration",
"commit": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3",
"passed": 1,
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/cc8188e650f64843b6c6f717962b2209-integration.json"
},
{
"kind": "final",
"commit": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3",
"passed": 1,
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-runtime-preview/runs/a7baf978d6734efd912b79e8cec0fc70-final.json"
}
],
"original_P08_03_complete": false
}
@@ -0,0 +1,46 @@
{
"candidate": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"native_receipt": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p08-runtime-preview-12f04d6-target-impact-r03/runner-ended.json",
"passed": true,
"engine_ended": true,
"guard_errors": [],
"cleanup_errors": [],
"suites": [
{
"test": "tests/transport/test_runtime_build_preview.gd",
"checks": 80,
"failures": 0,
"actual_pid": 55871,
"source_sha256": "c881b60bce7276047884303a6823da9abfaaf8c1e85dbc5f2c0ff13f0d742449",
"completion_marker": "Runtime build preview: 80 checks, 0 failures\n"
},
{
"test": "tests/transport/test_runtime_stairs.gd",
"checks": 67,
"failures": 0,
"actual_pid": 55899,
"source_sha256": "72f368006ddecd26c3b29f3bcf622e89b8becee337c071d2f246d2b583617bda",
"completion_marker": "Runtime stairs: 67 checks, 0 failures\n"
},
{
"test": "tests/s1/test_construction_service.gd",
"checks": 105,
"failures": 0,
"actual_pid": 55916,
"source_sha256": "ce63074b84cb75d710eb3650701a9cb2acf920ff607e41be645904fc2395e2c3",
"completion_marker": "PASS: 105 checks\n"
},
{
"test": "tests/ui/test_original_build_pointer.gd",
"checks": 50,
"failures": 0,
"actual_pid": 55941,
"source_sha256": "a04a79c5e766659d10c4564d1f11c6554a27cb8af71431295e10bc4967012913",
"completion_marker": "Original build viewport input: 50 checks, 0 failures\n"
}
],
"preview_observations": 8,
"proof_bundle": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p08-runtime-preview/.runtime/P08-03-RTPREVIEW/build/runtime-preview-proof.json",
"review": "actual independent Opus running; no approval or integration yet",
"original_units_added": 0
}
@@ -0,0 +1,23 @@
{
"positive_observations": 8,
"controls": {
"snapshot_changed": {
"rejected": true,
"reason": "native snapshot/queue bytes changed"
},
"events_changed": {
"rejected": true,
"reason": "native counters changed"
},
"positive_missing": {
"rejected": true,
"reason": "missing/duplicate native preview observations"
},
"duplicate_observation": {
"rejected": true,
"reason": "missing/duplicate native preview observations"
}
},
"native_runs_added": 0,
"original_units_added": 0
}
@@ -0,0 +1,6 @@
{
"raw_sha256": "ba2bd0b0a14629630e1bb0e5a007e2e933a81c7dbe9ca9b7208b5ef504b01732",
"normalized_sha256": "949e00de465d86afd575ff03b7b575709fe0fc4d19d3b63a3a1a03929fe05969",
"contract_matches": true,
"explanation": "Runner git() strips trailing newline; raw file hash differs without content change"
}
@@ -0,0 +1,185 @@
"""Bind guarded native observations to this supporting candidate; no game acceptance."""
import argparse
import hashlib
import json
import pathlib
import re
import shutil
import subprocess
SOURCE_FILES = (
'autoload/simulation_runtime.gd',
'tests/transport/test_runtime_build_preview.gd',
'tests/transport/test_runtime_build_preview.gd.uid',
)
CASES = ('unknown_definition', 'operations_null_definition', 'operations_precedence',
'unsupported_vertical', 'landing_rejection', 'invalid_rotation',
'landing_positive', 'elevator_before_rotation')
FIRST_CODES = ('NOT_FOUND', 'UNPAID_EXPENSES', 'UNPAID_EXPENSES',
'UNSUPPORTED_VERTICAL_TOPOLOGY', 'STAIR_LANDING_MISSING',
'INVALID_PAYLOAD', None, 'ELEVATOR_BUSY')
PROBE = re.compile(
r'^Runtime preview proof: case=("[^"]+") cell=\((-?\d+), (-?\d+), (-?\d+)\) rotation=(-?\d+) '
r'snapshot_before=([0-9a-f]{64}) snapshot_after=([0-9a-f]{64}) '
r'queue_before=([0-9a-f]{64}) queue_after=([0-9a-f]{64}) '
r'accepted_before=(\d+) accepted_after=(\d+) processed_before=(\d+) processed_after=(\d+) '
r'events_before=(\d+) events_after=(\d+) can_build=(true|false) error_codes=(\[.*\])$')
def sha(path):
return hashlib.sha256(pathlib.Path(path).read_bytes()).hexdigest()
def probes_from_raw(text):
lines = [line for line in text.splitlines() if line.startswith('Runtime preview proof:')]
assert len(lines) == len(CASES), 'missing/duplicate native preview observations'
rows = []
for name, expected_code, line in zip(CASES, FIRST_CODES, lines):
match = PROBE.fullmatch(line)
assert match, 'malformed native preview observation'
g = match.groups()
assert g[5] == g[6] and g[7] == g[8], 'native snapshot/queue bytes changed'
assert g[9] == g[10] and g[11] == g[12] and g[13] == g[14], 'native counters changed'
codes = json.loads(g[16])
assert (g[15] == 'true' and not codes) if expected_code is None else (
g[15] == 'false' and codes and codes[0] == expected_code), 'wrong native preview outcome'
expected_id = 'unknown.preview.definition' if name in CASES[:2] else (
'guest_corridor' if name == 'invalid_rotation' else (
'guest_elevator' if name == 'elevator_before_rotation' else 'guest_stairs'))
assert json.loads(g[0]) == expected_id, 'wrong observed facility'
expected_cell = (4, 2, 0) if name == 'landing_positive' else (
(0, 2, 0) if name == 'elevator_before_rotation' else (-8, 2, 0))
assert tuple(map(int, g[1:4])) == expected_cell, 'wrong observed cell'
assert int(g[4]) == (0 if name in ('unknown_definition', 'landing_positive') else 999)
rows.append(dict(case=name, definition_id=json.loads(g[0]), cell=list(expected_cell),
rotation=int(g[4]), snapshot_before_sha256=g[5], snapshot_after_sha256=g[6],
queue_before_sha256=g[7], queue_after_sha256=g[8],
accepted_before=int(g[9]), accepted_after=int(g[10]),
processed_before=int(g[11]), processed_after=int(g[12]),
events_before=int(g[13]), events_after=int(g[14]),
can_build=g[15] == 'true', error_codes=codes))
return rows
def verify_bundle(root, build):
proof = json.loads((build / 'runtime-preview-proof.json').read_text())
head = subprocess.check_output(['git', '-C', str(root), 'rev-parse', 'HEAD'], text=True).strip()
assert head == proof['candidate'], 'candidate mismatch'
assert set(proof['sources']) == set(SOURCE_FILES)
for name, pin in proof['sources'].items():
assert sha(root / name) == pin, 'support source drift'
for name, pin in proof['raw_file_manifest'].items():
assert sha(build / name) == pin, 'raw evidence drift: ' + name
ended = json.loads((build / 'native/runner-ended.json').read_text())
inputs = json.loads((build / 'native/runner-input.json').read_text())
assert ended['passed'] and ended['engine_ended'] and not ended['guard_errors'] and not ended['cleanup_errors']
assert sha(build / 'root_native_collector.py') == inputs['root_harness_sha256']
for name, pin in inputs['selected_source_map'].items():
assert sha(root / name) == pin, 'exact native source applicability: ' + name
rows = [row for row in ended['phases'] if row.get('test')]
assert len(rows) == 4 and all(row['passed'] and row['exit_code'] == 0 and row['engine_ended'] for row in rows)
assert all(type(row['actual_pid']) is int and row['actual_pid'] > 0 for row in rows)
assert len({row['actual_pid'] for row in rows}) == 4
target = next(row for row in rows if row['test'] == SOURCE_FILES[1])
assert target['reported_failures'] == 0 and target['reported_checks'] > 0
assert target['source_sha256'] == sha(root / SOURCE_FILES[1])
raw = build / 'native/000/stdout.log'
assert sha(raw) == proof['target_stdout_sha256']
observations = probes_from_raw(raw.read_text())
assert observations == proof['observations'], 'native/proof observation mismatch'
assert proof['cases'] == dict.fromkeys(CASES + ('preview_purity',), True)
return proof
def bind_exact_candidate(root, build):
"""Only metadata changes: every native input and immutable raw file must match."""
path = build / 'runtime-preview-proof.json'
proof = json.loads(path.read_text())
head = subprocess.check_output(['git', '-C', str(root), 'rev-parse', 'HEAD'], text=True).strip()
if proof['candidate'] == head:
return verify_bundle(root, build)
for name, pin in proof['raw_file_manifest'].items():
assert sha(build / name) == pin, 'raw evidence changed before applicability check'
inputs = json.loads((build / 'native/runner-input.json').read_text())
for name, pin in inputs['selected_source_map'].items():
assert sha(root / name) == pin, 'changed native source cannot reuse evidence: ' + name
assert sha(inputs['engine']) == inputs['engine_sha256'], 'changed native engine'
marker = root / 'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json'
assert sha(marker) == inputs['marker_contract_sha256'], 'changed marker configuration'
for name, pin in proof['sources'].items():
assert sha(root / name) == pin, 'changed supporting implementation'
previous = proof['candidate']
previous_sha = sha(path)
proof['candidate'] = head
proof.setdefault('exact_source_applicability', []).append(dict(
previous_bound_commit=previous, previous_proof_sha256=previous_sha,
bound_commit=head, source_files_checked=len(inputs['selected_source_map']),
source_byte_changes=0, engine_and_marker_match=True,
new_native_runs=0, executed_native_candidate=proof['executed_native_candidate']))
path.write_text(json.dumps(proof, ensure_ascii=False, indent=2))
try:
return verify_bundle(root, build)
except BaseException:
proof['candidate'] = previous
proof['exact_source_applicability'].pop()
path.write_text(json.dumps(proof, ensure_ascii=False, indent=2))
raise
def main():
p = argparse.ArgumentParser()
p.add_argument('--root', type=pathlib.Path, required=True)
p.add_argument('--build', type=pathlib.Path, required=True)
p.add_argument('--native', type=pathlib.Path)
p.add_argument('--verify-only', action='store_true')
p.add_argument('--bind-exact-candidate', action='store_true')
a = p.parse_args()
root, build = a.root.resolve(), a.build.resolve()
if a.bind_exact_candidate:
bind_exact_candidate(root, build)
a.verify_only = True
if not a.verify_only:
assert a.native and not (build / 'runtime-preview-proof.json').exists(), 'fresh native proof required'
native = a.native.resolve()
ended = json.loads((native / 'runner-ended.json').read_text())
assert ended['passed'] and ended['engine_ended'] and not ended['guard_errors'] and not ended['cleanup_errors']
build.mkdir(parents=True, exist_ok=True)
dest = build / 'native'
assert not dest.exists()
dest.mkdir()
for f in native.rglob('*'):
rel = f.relative_to(native)
if 'stage' in rel.parts or not f.is_file():
continue
assert not f.is_symlink()
out = dest / rel
out.parent.mkdir(parents=True, exist_ok=True)
subprocess.run(['/bin/cp', '-c', str(f), str(out)], check=True)
assert sha(out) == sha(f)
collector = pathlib.Path(__file__).with_name('root_runtime_preview_targeted.py')
shutil.copyfile(collector, build / 'root_native_collector.py')
shutil.copyfile(__file__, build / 'root_proof_verifier.py')
observations = probes_from_raw((dest / '000/stdout.log').read_text())
first = observations[0]
proof = dict(protocol='guarded-runtime-preview-v1',
candidate=subprocess.check_output(['git', '-C', str(root), 'rev-parse', 'HEAD'], text=True).strip(),
executed_native_candidate='12f04d6e8bfdba59e44d81e8e34c57b67efbefeb',
original_native_directory=str(native), native_executed=True,
owned_engine_ended=True, guard_errors=[], cleanup_errors=[],
sources={name: sha(root / name) for name in SOURCE_FILES},
cases=dict.fromkeys(CASES + ('preview_purity',), True), observations=observations,
snapshot_before_sha256=first['snapshot_before_sha256'],
snapshot_after_sha256=first['snapshot_after_sha256'],
command_log_before=first['accepted_before'], command_log_after=first['accepted_after'],
events_before=first['events_before'], events_after=first['events_after'],
target_stdout_sha256=sha(dest / '000/stdout.log'),
raw_file_manifest={str(f.relative_to(build)): sha(f) for f in dest.rglob('*') if f.is_file()},
scope='Supporting Runtime proof only; not original P08 acceptance or Windows proof')
(build / 'runtime-preview-proof.json').write_text(json.dumps(proof, ensure_ascii=False, indent=2))
proof = verify_bundle(root, build)
print(json.dumps(dict(passed=True, candidate=proof['candidate'], previews=len(proof['observations']),
sources=len(proof['sources']), original_units_added=0)))
if __name__ == '__main__':
main()
@@ -223,7 +223,7 @@
"ASSETS_PLATFORM_AUDIT.md": "a3a4b8ca0fb39a9abf88692285d26aa879815e092352ba304ef2758e71da50bd",
"ATOMIC_REGISTER.md": "6070143b85b7c3b9b73d7c9768d88d2dae4d20407ad54a563cb6ffd74f2373ae",
"ATOMIC_SEMANTIC_REVIEW.md": "c156b1fb57c2b4a900f27a19049510f3e9616e723d5edb3417f50d733de5be48",
"IMPLEMENTATION_PLAN.md": "e3d5a83b65207a402f8b36a06f9893ab969adcbb5b97915930af1358b15749e1",
"IMPLEMENTATION_PLAN.md": "72a757c24b73cc69bed96b9929d6a339972d2e9bb06e13cc7f0df1c2ff654eb4",
"IMPORT_UNICODE_AUDIT.md": "88b2382bfbb3411fece8be7e6004ba21d8bf6a47e9d1f3cf573ea6638f79c12f",
"P09_VALUE_CONTRACTS.md": "c5abdc4543e54033b1fcfd0943cba266f664d8c10968965fd36ade40da488a25",
"PERFORMANCE_AUDIT.md": "c75e806acf825fc4a61f773a2cce7e71be335a1e25dbb15d98091097e8dc47c1",
@@ -244,7 +244,7 @@
"facility_value_contracts_validation.json": "bf490a9ca585c48fc318e76c4a069ef244827d828d46e6415399f7710590dd16",
"performance_audit.json": "0b630b15a392c3e0366f1362bfe4ddacb968f915f54549f82e4d6fa315384762",
"progress_contract.json": "ccbdfce8c8365d5c13f59531955708834cce45acd0e136561c95295dfdb5df77",
"progress_snapshot.json": "5a295402f314c81a2e93ed47a421832c6163de1de455c3023062b8e9dc6506bc",
"progress_snapshot.json": "63313b906649e7709483df0b867a07b703f4d8c6429eec0de07dd2768086e018",
"progress_validator_guard_checks.json": "72ee513fcf1cad85c24bfd0a4b472f425f6acf117928ece0f6b41e29018da627",
"progress_validator_guard_checks.r01.json": "14c26adffa5a1938241db4912e50ea54b660641ee6fee2e412d467dce14d0519",
"requirement_coverage.json": "8b5788b22ae8f49ea7e5cf048a5f0d82b54f6f193623465e0b70496b5aadd09d",
@@ -9823,12 +9823,13 @@
"dependency": {
"task": "P08-03-RTPREVIEW",
"project": "the-tree-p08-runtime-preview",
"state": "implementing test-only repair1",
"state": "completed supporting component",
"model": "gpt-6.1-sol",
"commander": "claude-opus-5-5",
"added_original_units": 0,
"submitted": "78dc82da077dabbdb92ebcf475cd81c5d619bcf6",
"native_targeted": "failed, preserved and engine ended; no acceptance"
"submitted": "12f04d6e8bfdba59e44d81e8e34c57b67efbefeb",
"native_targeted": "four suites passed; actual eight purity observations; separate Opus review pass",
"integration": "dbf5cb8f1bec88b259d010d8f3ce0486b1cfeaa3"
},
"next": "shared Runtime precheck, existing P08 UI connection, frozen-version native and complete regression, independent review, integration",
"formal_complete": false
@@ -0,0 +1,147 @@
extends SceneTree
var _checks := 0
var _failures := 0
var _serial := 0
var _runtime: Variant
var _clock: Variant
var _state: Variant
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
_clock = load("res://autoload/game_clock.gd").new()
_state = load("res://autoload/game_state.gd").new()
var base_script: Variant = load("res://autoload/simulation_runtime.gd")
if base_script == null or not base_script.can_instantiate():
push_error("Runtime preview base script could not be loaded.")
quit(1)
return
# Seed diagnostic switches isolate precedence; the operations gate itself is real.
var diagnostic_script := GDScript.new()
diagnostic_script.source_code = """extends "res://autoload/simulation_runtime.gd"
var block_operations := false
var block_vertical := false
func _operations_total_arrears() -> int:
return 1 if block_operations else super._operations_total_arrears()
func _facility_definition_is_unsupported_vertical_proxy(definition: Variant) -> bool:
return block_vertical or super._facility_definition_is_unsupported_vertical_proxy(definition)
"""
var reload_error := diagnostic_script.reload()
if reload_error != OK:
push_error("Runtime preview diagnostic script reload failed: %s" % reload_error)
quit(1)
return
_runtime = diagnostic_script.new()
if _runtime == null:
push_error("Runtime preview diagnostic instance is null.")
quit(1)
return
for method: StringName in [&"initialize", &"create_snapshot", &"enable_production_operations"]:
if not _runtime.has_method(method):
push_error("Runtime preview diagnostic instance lacks method: %s" % method)
quit(1)
return
var infrastructure_projector: Variant = load("res://scripts/world/facility_infrastructure_projector.gd")
_reset()
var cell := Vector3i(-8, 2, 0)
_failure_case(&"unknown.preview.definition", cell, 0, "NOT_FOUND", "Facility definition was not found.")
check(_runtime.enable_production_operations().get(&"ok", false), "enable real operations gate")
_runtime.block_operations = true
_runtime.block_vertical = true
_failure_case(&"unknown.preview.definition", cell, 999, "UNPAID_EXPENSES", "Operations currently block construction and investment.")
_failure_case(&"guest_stairs", cell, 999, "UNPAID_EXPENSES", "Operations currently block construction and investment.")
_runtime.block_operations = false
_failure_case(&"guest_stairs", cell, 999, String(infrastructure_projector.REASON_UNSUPPORTED_VERTICAL_TOPOLOGY), "Vertical infrastructure topology is not supported.")
_reset()
_failure_case(&"guest_stairs", cell, 999, "STAIR_LANDING_MISSING", "先に階段の一つ下の階に通路を作ってください。")
_failure_case(&"guest_corridor", cell, 999, "INVALID_PAYLOAD", "The selected rotation is not allowed.")
# origin INVALID_PAYLOAD cannot be reached through preview's Vector3i API.
_reset()
var lower_stairs := _command(&"guest_stairs", Vector3i(4, 1, 0), 0)
check(lower_stairs.is_success(), "build real lower stairs: %s" % lower_stairs.message)
_clock.advance_minutes(_runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
var lower_exists := false
for facility: Dictionary in _runtime.construction_service.get_facilities():
if facility[&"origin"] == Vector3i(4, 1, 0):
lower_exists = true
check(lower_exists, "real lower stairs construction completes")
var report := _pure_preview(&"guest_stairs", Vector3i(4, 2, 0), 0)
var accepted: Variant = _command(&"guest_stairs", Vector3i(4, 2, 0), 0)
if not (report[&"can_build"] and accepted.is_success()):
var first_reason: Dictionary = report[&"reasons"][0] if not report[&"reasons"].is_empty() else {}
var command_code := String(accepted.details.get(&"reason", CommandResult.Code.keys()[accepted.code]))
print("Runtime preview positive: can_build=%s error_codes=%s first_code=%s first_message=%s command_code=%s command_message=%s" % [report[&"can_build"], JSON.stringify(report[&"error_codes"]).left(256), JSON.stringify(first_reason.get(&"code", "none")).left(256), JSON.stringify(first_reason.get(&"message", "none")).left(512), JSON.stringify(command_code).left(256), JSON.stringify(accepted.message).left(512)])
check(report[&"can_build"] and accepted.is_success(), "positive landing preview and command agree")
_reset()
check(_command(&"guest_elevator", Vector3i.ZERO, 0).is_success(), "build real elevator")
_clock.advance_minutes(310)
check(_runtime.submit_command(&"hire_staff_candidate", {&"candidate_id": &"staff_akane"}).is_success(), "hire elevator actor")
var access: Array[StringName] = [&"staff"]
var queued: Dictionary = _runtime.elevators.request_trip(&"staff:staff_akane", Vector3i.ZERO, Vector3i(0, 1, 0), _clock.absolute_minute, access)
check(queued.get(&"ok", false), "queue real elevator trip")
_failure_case(&"guest_elevator", Vector3i(0, 2, 0), 999, "ELEVATOR_BUSY", "Wait until the shaft is idle before extending it.")
_runtime.free()
_clock.free()
_state.free()
print("Runtime build preview: %d checks, %d failures" % [_checks, _failures])
quit(1 if _failures > 0 else 0)
func _reset() -> void:
_runtime.block_operations = false
_runtime.block_vertical = false
_clock.reset(1, 6, 0)
_state.reset()
check(_runtime.initialize(_clock, _state, 90416)[&"valid"], "initialize preview fixture")
_runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
_clock.set_paused(true)
func _pure_preview(id: StringName, cell: Vector3i, rotation: int) -> Dictionary:
var before := var_to_bytes(_runtime.create_snapshot())
# CommandQueue contains the accepted command log and processed receipts.
var log_before := var_to_bytes(_runtime.command_queue.create_snapshot())
var commands_before: int = _runtime.command_queue.get_accepted_command_metadata().size()
var processed_before: int = _runtime.command_queue.processed_count()
var events_before: int = _runtime.domain_events.recent_events().size()
var report: Dictionary = _runtime.preview_build_facility(id, cell, rotation)
var after := var_to_bytes(_runtime.create_snapshot())
var log_after := var_to_bytes(_runtime.command_queue.create_snapshot())
var commands_after: int = _runtime.command_queue.get_accepted_command_metadata().size()
var processed_after: int = _runtime.command_queue.processed_count()
var events_after: int = _runtime.domain_events.recent_events().size()
print("Runtime preview proof: case=%s cell=%s rotation=%d snapshot_before=%s snapshot_after=%s queue_before=%s queue_after=%s accepted_before=%d accepted_after=%d processed_before=%d processed_after=%d events_before=%d events_after=%d can_build=%s error_codes=%s" % [JSON.stringify(String(id)).left(256), cell, rotation, _sha256(before), _sha256(after), _sha256(log_before), _sha256(log_after), commands_before, commands_after, processed_before, processed_after, events_before, events_after, report[&"can_build"], JSON.stringify(report[&"error_codes"]).left(256)])
check(before == after, "preview preserves typed snapshot bytes")
check(log_before == log_after, "preview preserves command log bytes")
check(commands_before == commands_after and processed_before == processed_after, "preview preserves command counts")
check(events_before == events_after, "preview preserves event count")
return report
func _sha256(bytes: PackedByteArray) -> String:
var context := HashingContext.new()
context.start(HashingContext.HASH_SHA256)
context.update(bytes)
return context.finish().hex_encode()
func _failure_case(id: StringName, cell: Vector3i, rotation: int, code: String, message: String) -> void:
var report := _pure_preview(id, cell, rotation)
check(not report[&"can_build"] and report[&"error_codes"][0] == code, "preview first code: " + code)
check(report[&"reasons"][0][&"code"] == code and report[&"reasons"][0][&"message"] == message, "preview real message: " + code)
var refused := _command(id, cell, rotation)
var command_code := String(refused.details.get(&"reason", CommandResult.Code.keys()[refused.code]))
check(not refused.is_success() and command_code == code, "submit code agrees: " + code)
check(refused.message == message and refused.message == report[&"reasons"][0][&"message"], "submit message agrees: " + code)
check(refused.details == report[&"reasons"][0][&"details"], "submit details agree: " + code)
if _runtime.definition_registry.get_facility(id) == null:
check(report.size() == 4 and report[&"cells"].is_empty() and report[&"reasons"].size() == 1 and report[&"error_codes"].size() == 1, "unknown definition returns only precheck summary")
func _command(id: StringName, cell: Vector3i, rotation: int) -> CommandResult:
_serial += 1
return _runtime.submit_command(&"build_facility", {&"definition_id": id, &"origin": cell, &"rotation": rotation}, &"manager", &"", 0, -1, StringName("runtime.preview.%d" % _serial))
func check(ok: bool, message: String) -> void:
_checks += 1
if not ok:
_failures += 1
push_error(message)
quit(1)
@@ -0,0 +1 @@
uid://dqx7m2k8n4vsa