Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf559632dd | ||
|
|
d1c7ce27d2 | ||
|
|
1545bd42d6 | ||
|
|
592809bfda | ||
|
|
bb34f443c4 | ||
|
|
e59206b9b2 | ||
|
|
6c7c724410 | ||
|
|
e196578c1a | ||
|
|
25b77f1d14 | ||
|
|
e4dc1efac0 | ||
|
|
af3df735c6 | ||
|
|
9919d66b94 | ||
|
|
4167edf68a |
+1
-1
@@ -14,4 +14,4 @@
|
||||
|
||||
OpusはP22-02を独立候補に選定した。提案中のCC0限定は原条件ではないため採用しない。自己制作/別許諾も実際の証拠があれば対象とし、未知の権利を推測で成立させない。614の全枠を同数の完成画像へ変換する案も採用しない。全Godotの新しい禁止は設けず、容量と必要な検証範囲で実行を管理する。
|
||||
|
||||
新しいimplementation taskをまだ登録/起動しない。既存成果と条件不足を確認せず、必ず失敗すると分かるgateや重複workerを作らない。次の具体作業は各利用枠のsource/rights/形式の選定契約を固め、実制作が必要な未達を同じ原条件のまま実装・受入へ進める。P13/RP13の追加回数/限定正式host試験は別の直接許可を待ち、勝手に転用しない。
|
||||
追補: 原P22-02を同じwork/acceptanceで登録し、実Opus run/Solで契約とchecker担当を起動済み。普通repair1/2でspec raw/strip照合の混同を訂正し、同じ担当が継続中。原成果の正式受入は0/1。既存成果と条件不足を確認せず、必ず失敗すると分かるgateや重複workerを作らない。次の具体作業は各利用枠のsource/rights/形式の選定契約を固め、実制作が必要な未達を同じ原条件のまま実装・受入へ進める。P13/RP13の追加回数/限定正式host試験は別の直接許可を待ち、勝手に転用しない。
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"task": "P22-02",
|
||||
"state": "implementing",
|
||||
"repairs_used": 3,
|
||||
"cap": 3,
|
||||
"actual_timeout_event": {
|
||||
"role": "implementer",
|
||||
"service": "codex",
|
||||
"argv": [
|
||||
"/Users/korizatou114/.local/bin/codex",
|
||||
"exec",
|
||||
"--json",
|
||||
"--ignore-user-config",
|
||||
"--ephemeral",
|
||||
"--sandbox",
|
||||
"danger-full-access",
|
||||
"-c",
|
||||
"approval_policy=\"never\"",
|
||||
"-c",
|
||||
"sqlite_home=\"/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/.runtime/P22-02/provider-46b637a900654cfc9e0b419ab541cc9a/sqlite\"",
|
||||
"-c",
|
||||
"log_dir=\"/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/.runtime/P22-02/provider-46b637a900654cfc9e0b419ab541cc9a/logs\"",
|
||||
"--output-schema",
|
||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/.runtime/P22-02/provider-46b637a900654cfc9e0b419ab541cc9a/result.schema.json",
|
||||
"--output-last-message",
|
||||
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/.runtime/P22-02/provider-46b637a900654cfc9e0b419ab541cc9a/answer.json",
|
||||
"-",
|
||||
"--model",
|
||||
"gpt-6.1-sol"
|
||||
],
|
||||
"cwd": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement",
|
||||
"effective_timeout_seconds": 1800,
|
||||
"project_policy_timeout_unchanged": 900,
|
||||
"repairs": 3,
|
||||
"global_policy_changed": false
|
||||
},
|
||||
"run": {
|
||||
"id": "6faa74aed45644b59ddd4c64e215b2f8",
|
||||
"role": "implementer",
|
||||
"service": "codex",
|
||||
"status": "running",
|
||||
"pid": 14816,
|
||||
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p22-02-contract/runs/6faa74aed45644b59ddd4c64e215b2f8"
|
||||
},
|
||||
"completion_claimed": false
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"task": "P22-02",
|
||||
"state": "blocked",
|
||||
"actual_worker_run": "a999bbd142334aa582f2d373ed625e78",
|
||||
"actual_exit": 124,
|
||||
"repairs": 2,
|
||||
"cap": 2,
|
||||
"active_process_or_job": false,
|
||||
"worker_result_received": false,
|
||||
"current_head": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"unsubmitted_manifest_sha256": "1a7af44b722ab110aca508512ea55c18a19ca72ffc75db0ac6f39ad839079ae0",
|
||||
"source_preserved": true,
|
||||
"normal_restart_performed": false,
|
||||
"root_tests_pass": 13,
|
||||
"cli_integrity_exit": 0,
|
||||
"cli_required_readiness_exit": 2,
|
||||
"pending_identities": 614,
|
||||
"prospective_guard_bytes": 487283,
|
||||
"final_committed_packet_verified": false,
|
||||
"human_permission_pending": "P22 task cap2→3, used2 kept, one implementer timeout1800 only",
|
||||
"global_goal_complete": false,
|
||||
"original_completed_units_added": 0
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"direct_human_reply": "P22-02の追加1回と限定timeout変更を許可する",
|
||||
"source_question_call": "call_99b2d7c5e9f3461eba0b8b0217c8b39b",
|
||||
"cap": 3,
|
||||
"retained_used": 2,
|
||||
"effective_implementer_timeout_seconds": 1800,
|
||||
"project_policy_timeout_unchanged": 900,
|
||||
"scope": "Only same P22-02 preserved finalization; no global or other role/task change",
|
||||
"before_contract": {
|
||||
"id": "P22-02",
|
||||
"title": "素材契約と権利(原条件全体、記録だけの完了代用なし)",
|
||||
"requirement_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"acceptance_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"spec_ref": "docs/spec/acceptance/P22-02.json",
|
||||
"base_commit": "10c62e1fa7b71576598583f434824b59816d4705",
|
||||
"worker": "codex",
|
||||
"allowed_paths": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/**",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"depends_on": [],
|
||||
"resource_locks": [
|
||||
"p22-asset-contracts-and-rights"
|
||||
],
|
||||
"validation_ids": [
|
||||
"p22-contract"
|
||||
],
|
||||
"max_repair_attempts": 2,
|
||||
"spec_sha256": "f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875"
|
||||
},
|
||||
"after_contract": {
|
||||
"id": "P22-02",
|
||||
"title": "素材契約と権利(原条件全体、記録だけの完了代用なし)",
|
||||
"requirement_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"acceptance_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"spec_ref": "docs/spec/acceptance/P22-02.json",
|
||||
"base_commit": "10c62e1fa7b71576598583f434824b59816d4705",
|
||||
"worker": "codex",
|
||||
"allowed_paths": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/**",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"depends_on": [],
|
||||
"resource_locks": [
|
||||
"p22-asset-contracts-and-rights"
|
||||
],
|
||||
"validation_ids": [
|
||||
"p22-contract"
|
||||
],
|
||||
"max_repair_attempts": 3,
|
||||
"spec_sha256": "f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875"
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
# P22-02保持成果の限定継続案(未承認・未適用)
|
||||
|
||||
Astraは900秒で実exit124終了。restartしていない。sourceは保持し、Root実13試験PASS、CLI整合性0/原ready2、全614/19、prospective全packet487283を確認。残件はASSET_CONTRACTS.mdとvalidation.jsonの古いmirror説明/packet472408/ledger453678等を現物へ同期し、正式応答・submitを得ること。差分案proposed-final-doc-metadata-sync.patchは2文書のみで、既存checker logicや原条件を緩めない。
|
||||
|
||||
許可対象案: P22-02だけ追加1回、個別cap2→3/使用済み2保持。同じworktree、保持されたASTRA code/13試験を再利用、全再実装なし。同じ一回のimplementer実行だけ有効timeout1800秒(project既定900/他task/commander/reviewerは不変)を信頼側のbounded coordinator引数で指定する。scopeを緩めず、actual argv/cwd/effective timeout/exit/logを記録する。provider-budget/並列/課金/API/原30・88/入力・仕様・権限・DB直接書換えはしない。
|
||||
|
||||
同じworkerで差分案/構文/既存13の影響確認、必ず実submitted応答。その後Rootはexact final commitから全packet<500000を測定し、記録整合性と原条件readyを別に検証。実P22の未制作/実利用/Creator/権利/数量/表示/聴感が未達ならoriginal受入不可を維持する。Rootの合格を正式reviewに代用しない。
|
||||
|
||||
SKILL.mdは修正回数/予算の無断拡大を禁止する。普通capは2/2使い切ったため、このtask-only追加一回とexecution timeout変更の直接許可が必要。提出応答を捏造してstateを戻す/RP13専用復旧をP22へ流用する/新規登録で回数回避することはしない。
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"original_plan_id": "P22-02",
|
||||
"original_unit_completed": false,
|
||||
"preservation_branch": "codex/p22-02-preserved-finalization-r05",
|
||||
"preserved_commit": "aad6284fb75d32a73d0a4c00a53e9660ce76aad8",
|
||||
"tree": "b56e0ddc03b705f8898387079f7bb636e3f0594d",
|
||||
"actual_packet_bytes": 491572,
|
||||
"packet_limit": 500000,
|
||||
"all_sources_included": true,
|
||||
"actual_worker_run": "6faa74aed45644b59ddd4c64e215b2f8",
|
||||
"worker_exit_code": 0,
|
||||
"worker_result_status": "blocked",
|
||||
"worker_result_preserved": true,
|
||||
"root_coordinator_reference_gap_resolved": true,
|
||||
"ordinary_submission_not_recovered": true,
|
||||
"new_provider_or_repair_not_started": true,
|
||||
"repairs_used": 3,
|
||||
"repair_cap": 3,
|
||||
"retained_code_same_sha": {
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json": true,
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py": true,
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py": true,
|
||||
"tools/check_p22_asset_contracts.py": true
|
||||
},
|
||||
"actual_root_tests": "13 passed, same unchanged code, diagnostic not formal original acceptance",
|
||||
"original_require_ready_exit_code": 2,
|
||||
"pending_exact_uses": 614,
|
||||
"selected_usable_count": 0,
|
||||
"independent_technical_review": {
|
||||
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p22-02-contract/runs/25eefc570e4540d9aacd05c9763233b1",
|
||||
"model": "claude-opus-5-5",
|
||||
"original_unit_accepted": false,
|
||||
"findings_by_severity": {
|
||||
"critical": 0,
|
||||
"high": 1,
|
||||
"medium": 5,
|
||||
"low": 3
|
||||
},
|
||||
"formal_acceptance_review": false
|
||||
},
|
||||
"product_main_adoption": false,
|
||||
"original_denominator": "30 packages / 88 delivery units; no partial points"
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"submitted_commit": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"source_scope": "diagnostic Root preflight, not formal acceptance or review",
|
||||
"syntax_passed": true,
|
||||
"checks": [
|
||||
{
|
||||
"id": "record-integrity",
|
||||
"exit_code": 0,
|
||||
"stdout": "{\"acceptance_claimed\": false, \"original_conditions\": {\"all_creator_and_rights_evidence_accepted\": false, \"all_exact_uses_selected_and_usable\": false, \"all_mandatory_unmade_and_disclosure_gaps_resolved\": false, \"all_naming_resolution_layout_replacement_references_accepted\": false, \"applicable_display_and_hearing_evidence\": false, \"independent_opus_review\": false, \"integration_and_final_original_30_88_acceptance\": false, \"root_static_and_meaningful_negative_validation\": false}, \"original_unit_ready\": false, \"pending_identity_count\": 614, \"record_integrity\": true}\n",
|
||||
"stderr": ""
|
||||
},
|
||||
{
|
||||
"id": "registered-exact",
|
||||
"exit_code": 2,
|
||||
"stdout": "",
|
||||
"stderr": "usage: check_p22_asset_contracts.py [-h] [--ledger LEDGER] [--require-ready]\ncheck_p22_asset_contracts.py: error: unrecognized arguments: --verify-only --accepted-input docs/spec/inputs/P22-02-accepted-usage.json\n"
|
||||
},
|
||||
{
|
||||
"id": "readiness-current",
|
||||
"exit_code": 2,
|
||||
"stdout": "{\"acceptance_claimed\": false, \"original_conditions\": {\"all_creator_and_rights_evidence_accepted\": false, \"all_exact_uses_selected_and_usable\": false, \"all_mandatory_unmade_and_disclosure_gaps_resolved\": false, \"all_naming_resolution_layout_replacement_references_accepted\": false, \"applicable_display_and_hearing_evidence\": false, \"independent_opus_review\": false, \"integration_and_final_original_30_88_acceptance\": false, \"root_static_and_meaningful_negative_validation\": false}, \"original_unit_ready\": false, \"pending_identity_count\": 614, \"record_integrity\": true}\n",
|
||||
"stderr": ""
|
||||
}
|
||||
],
|
||||
"exact_unchanged_reviewer_guard_bytes": 1350690,
|
||||
"guard_limit": 500000,
|
||||
"packet_fits": false,
|
||||
"source_names": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_SPEC_HASH_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"validation_source_names": [
|
||||
"docs/spec/inputs/P22-02-accepted-usage.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"known_readiness_source_defects": [
|
||||
"check requires selected_assets==[]",
|
||||
"check requires all original_conditions False before readiness uses all(original_conditions)",
|
||||
"ledger.current must equal frozen all-incomplete checkpoint, preventing actual evidence promotion"
|
||||
],
|
||||
"acceptance_claimed": false,
|
||||
"worker_source_changed": false
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"project": "the-tree-p22-02-contract",
|
||||
"task": "P22-02",
|
||||
"commit": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"method": "sys.settrace observes the actual unchanged Runner.packet locals; guard not bypassed",
|
||||
"control": "/private/tmp/the-tree-p24-02-control-r02",
|
||||
"packet_source_sha256": "34d0f62ec5b17b070a2d1ad4f58d06f3be7e9b6fb649ec86b366bc03b07c1329",
|
||||
"actual_guard_bytes": 1350690,
|
||||
"guard_limit": 500000,
|
||||
"fits": false,
|
||||
"actual_packet_result": "packetが大き過ぎます。タスクを小さく分割してください",
|
||||
"model_called": false,
|
||||
"task_state_changed": false,
|
||||
"body_file_sha256": "43ba3b71eda5f5cab5331d9a2632abe8ae24d6a28859d7cb57667ed19046e28a",
|
||||
"source_names": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_SPEC_HASH_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"validation_source_names": [
|
||||
"docs/spec/inputs/P22-02-accepted-usage.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"passed_validation_receipts_included": 0
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "run",
|
||||
"task_id": "P22-02",
|
||||
"reason": "P22-02 is in repair_ready. The owner explicitly approved raising the repair cap from 2 to 3, so this is repair 3 of 3. Direction for the one ordinary implementer run (timeout 1800s; the project and other roles stay at 900s): keep working in the same worktree and reuse all preserved Astra code. Do not reimplement anything and do not start other tasks. Keep the retained, already-tested checker (tools/check_p22_asset_contracts.py), build_contract.py, asset-contracts.json and test_contract.py exactly as they are. Read P22_FINAL_REPAIR_CONTEXT.md first. Use the proposed-final-doc-metadata-sync.patch and evidence/proposal under checkpoints/p22-02-slot-contract-r02 as read-only reference. Only update the two stale outputs, ASSET_CONTRACTS.md and validation.json, so they match the current code and facts. Write the contract spec hash as f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875, which is the UTF-8 hash of stdout.strip. Record that the raw file hash, c26c0b12cf7e7a7c46e671acde2e00762904732c1cd6381a53836e3d7b3f9824, differs only by a trailing newline. Report the facts honestly: the 13 root tests pass, ordinary integrity exits 0, and original require-ready still exits 2 (614 pending, 0 selected, disclosure/mandatory_scope missing). Keep integrity separate from readiness. Do not claim P22-02 or the original unit is complete. Do not fabricate assets, rights or quantities. D08/D09 stay unknown. Verification is bounded: python -B, ast.parse, test_contract.py, the checker's ordinary and require-ready modes, and confirming that every output field matches the checker output. Do not run engine or full regression. Measure the full reviewer packet on the actual final submitted state, with no omitted sources or guard changes, and confirm it is under 500000 (the prospective figure is 487283). Return a formal submitted worker JSON that lists the exact unmet original-unit conditions. Make no changes outside allowed_paths, no git writes and no acceptance waiver. The original scope, acceptance and denominator stay unchanged.",
|
||||
"codex_model": "gpt-6.1-sol",
|
||||
"codex_model_reason": "The remaining work is bounded documentation and metadata syncing. A concrete patch already exists, the code is already tested and must not change, and the facts are already settled (test results, exit codes, hashes). Sol is the default and can apply a known diff, run a few short checks and measure the packet. Astra's extra reasoning would add time and usage without improving quality, because no design, decoding or checker logic needs rework. The 1800s timeout the owner approved is enough for Sol."
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "run",
|
||||
"task_id": "P22-02",
|
||||
"reason": "P22-02はrepair_ready(修正2/2、記録済みrequest-repairを通常dispatch済み)で、base/spec/input/allowed_paths/条件は不変。正式failure receipt 8bced98116304e9cbe35521c33ab77d4-validation.json(登録exact argv未対応)を根拠に、同一worktreeのexecution/p22-02/P22_FINAL_REPAIR_CONTEXT.md全文とSPEC_HASH_CONTEXT(stripとrawを区別)に従う最終修正を実行する。範囲: 前判断の3欠陥、exact 1350690 bytes入力照合、固定alwaysFalseの除去、登録CLI `--verify-only --accepted-input.. --require-ready` のreadonly受理(登録は変更しない)。decoder/input/614全identity・全fieldはSHA参照+再構成で保持し、currentSource19と各契約の選定/不選定/不足・proofを実データに結合して検証する。元record内の未制作をempty分母へ除外しない。completed原unitとvalidate準備を分離し、validate→review→統合→finalの循環を作らない。現在実データ614未達ならreadinessは非0。synthetic正例は内部純関数に限定し、原P22のPASSへ換算しない。allfalse/selectedemptyの固定と偽boolean証拠は拒否する。変更はallowed_paths(execution/p22-02/**、tools/check_p22_asset_contracts.py)内のみ。Input/spec/checkpoints/Core/権限/予算/Git操作、余計な再調査/dup worker/engine/full regressionは禁止。修正上限2/2のため、これ以上の修正、上限変更、受入変更はオーナー判断。",
|
||||
"codex_model": "gpt-6-astra",
|
||||
"codex_model_reason": "前判断の選定理由を保持する。(1) validate→review→統合→finalの循環を作らずにreadinessへ到達できる設計が必要。(2) 固定allfalse/selectedemptyではなく、実データに結合した意味のある負例が必要。(3) schema/CRC/dimension/layout/rights/evidenceを凍結snapshotとの全==比較ではなく現在のsourceに結合する必要がある。(4) 217KiBの不変入力をSHA参照+再構成で扱い、reviewer packet全体を<500000に保つ必要がある。最終修正(2/2)で再修正の余地がないため、失敗コストが高い。前回は約45万input tokens(大半cache)で、品質を優先してastraを選ぶ価値がある。"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "wait",
|
||||
"task_id": "P22-02",
|
||||
"reason": "P22-02は blocked のまま、ordinary submitは許可されないため wait とします。正規の提出状態に戻す手段はありません。根拠は以下のとおりです。(1) 唯一の正規経路はworkerによる新しいsubmitted結果ですが、repairは3/3を使い切っており、cap4の追加とworker再実行はオーナーが禁止しています。(2) Rootがblocked状態を直接書き換えることや、run6faa74aeの結果をsubmittedに置き換えることは、結果の偽装になり、ゲートの例外を作ることになります。(3) Rootの実測(実際のRunner.packet、probe aad6284f/tree b56e0ddc/parent c6ccc5a6、491572<500000、8 sources+2 validator sources、省略なし、passed receiptなし)は有効な補強証拠です。ただし、worker自身が提出した結果の代わりにはなりません。candidateがnullなので、formalなreview・validate・prepare-integrationは成立しません。\n\nコーディネーターの次手順(実装・状態変更なし)は5つです。\n(a) probe commit aad6284fをそのまま保存専用の証拠branchに固定し、tree hash・parent・packet実測値・source一覧・4つの保持コードSHA・13テストPASS・require-ready exit 2をmanifestに記録する。このbranchはcandidateフィールドにもmainにも載せない。\n(b) 完全なpacketで、読み取り専用の独立技術レビュー(Opus)を任意で行う。結果は参考所見として扱い、正式な原受入レビューの代わりにはしない。require-readyは引き続き非ゼロのままで、614 pendingのunit未完了を明記する。\n(c) blocked理由に、ブロックの原因はコーディネーター側の計測参照の未供給だけであり、Rootの実測で解消済みであることを証拠として追記するかどうかは、オーナーが判断する。新しいworker結果を正規の提出として認める場合も、オーナーの判断が必要。\n(d) 依存関係のない別の原単位のうち、価値が高く単独で閉じられるものへ移る。\n(e) cap変更、provider再起動、受入の免除、未達コードのmain採用は行わない。",
|
||||
"codex_model": "gpt-6.1-sol",
|
||||
"codex_model_reason": "今回はrunもrepairも承認されておらず、modelフィールドが必須なのでデフォルトのSolを入れています。Astraを選ぶ根拠になる難しい実装作業はありません。"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "request-repair",
|
||||
"task_id": "P22-02",
|
||||
"reason": "The Root preflight of c6ccc5a6 found three required defects (recorded in checkpoints/p22-02-slot-contract-r02/actual-checker-and-packet-preflight-r02.json). This uses the last ordinary repair (1 used, limit 2). Fix only within allowed_paths: execution/p22-02/** and tools/check_p22_asset_contracts.py. Do not change the spec, inputs, Root checkpoint, cap, contracts, registered validation argv, permissions, or Core.\n\n(1) The checker exits 2 on the exact registered argv `--verify-only --accepted-input docs/spec/inputs/P22-02-accepted-usage.json --require-ready`. Add argparse support for `--verify-only` and `--accepted-input` without changing the registration. Keep it read-only.\n\n(2) Readiness is hardcoded to always fail, which the spec forbids. The check forces selected_assets==[], asserts all 8 original_conditions are False before computing ready with all(values), and forces ledger.current to equal the frozen all-unmet snapshot. Remove these. Keep every field of the frozen accepted input, all 614 original identities and the source observations. Verify the new current, selection and actual evidence separately, and derive ready from that real data. Reject fake booleans, file-presence-only proof and promoted fallbacks. The current ledger is genuinely short of 614, so the real P22 run must still return a nonzero readiness exit.\n\nKeep validation-ready separate from original-completed. Formal validate covers the technical readiness of function, assets, rights and the required usability. Original acceptance comes later, through a separate review, then integration, then final. Remove the cycle that puts independent review or integration completion as a gate before validation. Do not record original acceptance ahead of time.\n\nProve reachability with pure functions: one isolated positive readiness case, plus negatives for wrong proof, wrong quantity and wrong pin. Apply meaningful negatives to: missing, duplicate and stale sources; dimension, layout, license and rights mismatches; counterfeit final; quantity; codec bool-as-index; cycles; duplicate keys; NaN/Inf; and path escape. Don't reject only sample mutations, and don't use a gate that requires the whole checkpoint to equal a mirror.\n\n(3) The exact unchanged Runner packet is actually 1,350,690 bytes; the worker's 472,408 figure was wrong. It must be under 500,000 bytes, counting the full diff, all sources, the registered validation_sources (the checker plus the 217 KiB accepted input) and the tests. Don't re-embed the whole accepted_input or the roughly 1.5 MB current data in the ledger. Rebuild losslessly from the existing immutable inputs, referenced by raw SHA, decoded semantic hash, or file plus identity. Keep all 19 candidate sources, each of the 614 selections, and every gap and required field. Cut the output down with shared profiles, text and contracts. Don't extend the Core's P13-only dedup to P22.\n\nRun python -B with ast.parse only; no engine or full regression. Return submitted with the exact list of incomplete original-unit conditions. Do not claim P22-02 acceptance. No duplicate worker and no new registration.",
|
||||
"codex_model": "gpt-6-astra",
|
||||
"codex_model_reason": "This is the last ordinary repair, so a failure leaves no fallback. The work is hard: three defects at once, redesigning the readiness logic so it is reachable but still fails nonzero on the real data, untangling the validate/review/integration cycle, and a lossless decoder rebuild that shrinks the packet from 1.35 MB to under 500 KB. It also needs many meaningful negatives. The previous worker misreported the packet size and shipped always-fail logic, which suggests the default model underestimates this task. Astra's quality is worth its extra time and usage."
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "wait",
|
||||
"task_id": "P22-02",
|
||||
"reason": "P22-02 stays on wait. Advisory 25eefc570e4540d9aacd05c9763233b1 found original_unit_accepted=false. High: the positive integration path is unproved. Medium: negatives for rights, quantity, layout and the real ledger are missing, and some evidence is stale. All three repairs are used. No cap 4, no repeated full regression and no main adoption. Keep candidate aad6284f and the exact 491572-token full packet as they are. Do not count P22-02 as an original acceptance, and do not award partial points against 30/88. P02-01 and P02-02 are already formally complete, so they are not repeated.\n\nNEXT CHOSEN PLAN: P08-02, safe change to old placements. Why: it is the only candidate whose dependencies are met now. P04 waits on the owner's D05 decision. P06 waits on value approval. P13 and P18 repairs wait on the owner. P23 gestures wait on Windows. P24-01 needs UI for thoughts, emotion and shield that is not wired yet, plus a P18 candidate and unknown values. P26-01 depends on D08 and D09, which are unresolved. P08-02 can reuse the accepted P03-02 inputs. Bad migrations damage saves, so it has high value.\n\nBefore the contract is frozen, reread the exact P08-02 entry in docs/traceability/original/BASELINE.txt and the accepted-input files. Do not rely on this summary. All original acceptance conditions must be met: (1) problems with original dimensions are shown to the player, who chooses what happens; (2) unsafe auto-correction is rejected; (3) nothing overlaps, is orphaned or disappears; (4) when a problem cannot be solved, the original placements and saves are kept byte-identical, and formal backups stay intact.\n\nMissing evidence:\n- The player-choice display has been run and observed, including cancel and confirm.\n- Negatives show that unsafe auto-corrections are refused.\n- Each P03-02 rejected batch has overlap, orphan and disappearance checks: native cross-PID moving, boarded EV, rescue, logistics, and concurrent build.\n- Raw-state and save hashes are byte-identical before and after an unsolvable case, and backups are kept.\n- An independent review is done.\n\nMigration diagnostics alone do not prove P08-02.\n\nEvidence reuse: only reuse P03-02's exact raw states and formal backups after checking the version, the input SHA and the source applicability. Do not guess D07 relation conversions; record unknowns explicitly.\n\nRead-only audit scope:\n- Placement migration and validation code, the save load and write path, and backup handling.\n- The P03-02 evidence manifests and hashes.\n- Existing tests that cover placement conflicts.\n- Find which product and UI gaps remain, and which files would need to change.\n\nAfter that: targeted local tests for the touched modules, an impact analysis, a full final regression only if a change touches shared save or placement paths at integration, and then an independent Opus review. No registration and no worker run until the contract is frozen. The criteria are not weakened, and the owner decides spec, denominator, budget and main changes.",
|
||||
"codex_model": "gpt-6.1-sol",
|
||||
"codex_model_reason": "This decision is wait, so no worker runs. Sol is the default. Its quality is enough for the next step, a bounded read-only audit and contract preparation, and it saves time and usage. Consider Astra only if the frozen P08-02 contract needs complex changes to save and placement migration code."
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "run",
|
||||
"task_id": "P22-02",
|
||||
"reason": "P22-02は現在repair_readyで、修正は1/2回、2回の上限内です。出力はまだ1つも作られていません。今回の停止は、契約specSHAの比較に末尾改行を含むraw bytesのハッシュを使ったことが原因です。decoderやロジックが否決されたわけではありません。Rootの実測によると、base raw git blobとworktree bytesは一致します。不変のcontract spec_sha256(f252de3c…)はhash(raw.decode().strip().encode())と一致し、Runnerのgit helperがstdout.strip()を使う方法と同じです。spec、source、input、contract、acceptance、policyはどれも変わっていないため、仕様変更には当たりません。新規登録、重複worker、追加cap、予算変更も不要です。同じ担当がrunで普通の修正を続けてください。担当への指示は次のとおりです。(1) 最初にallowed_paths内のexecution/p22-02/P22_SPEC_HASH_CONTEXT.mdを読み、そこに固定された実SHAと算出方法に従う。(2) Runner方法(strip後のsemantic hash)を使うのは契約spec SHAの比較だけにする。個別のsource pinsとaccepted input(45fa52ac…)はraw bytesのSHA256のまま照合する。(3) ファイルのnormalize、spec・input・Runner・policyの変更、git書込、engineやfull回帰の実行は禁止。(4) 全614 identity、495 candidate、119 missing、19 source、2 state group(画像ではない)、既存current証拠を再利用し、成果物は契約、checker、具体的な製品proposalに限る。(5) record integrityはoriginal-unit readinessとは別に扱う。原unitのREADY未達と--require-readyの非0終了は保持し、構造上の合格をP22-02の受入や完了の代わりにしない。(6) submittedで返すときは、未達の原unit条件を正確に列挙する。",
|
||||
"codex_model": "gpt-6.1-sol",
|
||||
"codex_model_reason": "今回の失敗はハッシュの表し方を取り違えたことによる停止で、修正はRootが実測した方法を文書どおり当てはめるだけです。新しい設計や難しい推論は要りません。既存の入力と証拠は全部そろっていて、作業範囲は契約・checker・proposalに限られています。前回のSol実行でもdecoderとロジックは否決されていません。品質、時間、使用量のどれを見てもastraに格上げする理由がないため、既定のsolを継続します。"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "run",
|
||||
"task_id": "P22-02",
|
||||
"reason": "P22-02 is ready, has no depends_on, is unsubmitted, has 0 repairs, and its base_commit 10c62e1 matches HEAD with a clean tree. The spec SHA and the accepted input (raw SHA 45fa52ac…, 217190 bytes, lossless d/l/s/r encoding) are pinned, and the r01 and r02 preflight evidence is already in the repo, so nothing blocks starting. Scope is limited to allowed_paths (execution/p22-02/** and tools/check_p22_asset_contracts.py): contract/ledger/checker only, with no product, asset, spec, Runner, policy or git writes. The worker must: decode every field and verify the per-file semantic SHAs, the exact 614 IDs and 2 non-image state groups, and the wrong tag/type/index/cycle/duplicate-key rejects; join the 495 existing and 119 missing candidates to the real raw bytes, PNG dimensions/CRC, naming, replacement chain and current source (main.gd and world_preview updated to the current observed versions); reuse the verified Kenney 276/296 member, license and zip evidence, keeping the internal origin of BGM2 separate from final rights/hearing acceptance (left pending); keep D08/D09 explicitly unknown, with no CC0-only restriction and no invented quantities; keep record integrity separate from original-unit readiness, derived from the data, so that --require-ready exits non-zero while any original condition is unmet, with no hardcoded always-fail and no vacuous pass on zero completed frames; deduplicate through shared references so the exact reviewer packet stays under 500000; and leave concrete product/display/hearing proposals. Read the r02 JSON of about 1.5MB only with targeted python, never cat it. Use python -B and ast.parse; no engine or full regression. Submission means only that the contract work is written, never that the original P22-02 is complete (acceptance stays 0/1). Root static checks and negatives come first; the formal check, a separate Opus review and integration only after every acceptance condition is met.",
|
||||
"codex_model": "gpt-6.1-sol",
|
||||
"codex_model_reason": "The owner set Sol as the default and only one implementation slot is available. The work is mostly mechanical stdlib-Python transformation: decoding the 614 records, joining them to existing in-repo evidence and generating JSON/Markdown under a size limit. It needs no new research, engine runs or product edits, and the checker's output can be verified with static checks and negatives. Sol costs less time and usage, and two repairs are available as a buffer. The hardest point is keeping integrity separate from readiness without a false pass. If a repair is rejected on that readiness logic or on the decoder's correctness, Astra will be considered then."
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"task_id": "P22-02",
|
||||
"commit": "10c62e1fa7b71576598583f434824b59816d4705",
|
||||
"status": "blocked",
|
||||
"summary": "ASSET_CONTRACTS.mdとvalidation.jsonのみ同期。保持済みコードは変更なし。python3 -Bで13テスト合格、AST確認成功、ordinary exit 0、require-ready exit 2。出力フィールドとspec両hashを確認。指定patch・計測証拠がworktreeに存在せず参照先もアクセス拒否のため、完全最終パケットの500000未満を確認できない。487283は実測として報告していない。",
|
||||
"acceptance_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"findings": [
|
||||
{
|
||||
"severity": "high",
|
||||
"message": "完全最終レビューパケットの構築定義・参照証拠が不足し、必須サイズ計測がblocked。"
|
||||
},
|
||||
{
|
||||
"severity": "high",
|
||||
"message": "原成果未完了:614 pending、0 selected。最終命名・解像度・frame/layout・差替参照、使用可能資産とcreator/rights証拠、mandatory_scope/disclosure、必要な表示・聴感証拠が不足。D08/D09内容・数量はunknown。"
|
||||
},
|
||||
{
|
||||
"severity": "high",
|
||||
"message": "Root正式静的検証・meaningful negatives、独立Opusレビュー、統合、原30パッケージ/88成果の最終受入が未完了。ローカル整合性合格は原成果完了を意味しない。"
|
||||
}
|
||||
]
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"recorded_at": "2026-10-13T09:24:51.506077+00:00",
|
||||
"task": {
|
||||
"id": "P22-02",
|
||||
"state": "implementing",
|
||||
"repairs": 2,
|
||||
"submitted": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"reason": null
|
||||
},
|
||||
"repair_cap": 2,
|
||||
"live_run": {
|
||||
"id": "a999bbd142334aa582f2d373ed625e78",
|
||||
"status": "running",
|
||||
"pid": 95155,
|
||||
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p22-02-contract/runs/a999bbd142334aa582f2d373ed625e78"
|
||||
},
|
||||
"process_alive_verified": true,
|
||||
"exec_session": 20764,
|
||||
"actual_worker_model": "gpt-6-astra",
|
||||
"commander_model": "claude-opus-5-5",
|
||||
"actual_command_model_verified": true,
|
||||
"prior_candidate": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"prior_candidate_not_adopted": true,
|
||||
"required_defects": [
|
||||
"Registered CLI args missing; actual formal validation failed",
|
||||
"Always-false readiness and validation/review/integration cycle",
|
||||
"Actual unchanged complete packet1350690 exceeds500000"
|
||||
],
|
||||
"scope_unchanged": true,
|
||||
"no_new_original_delivery_or_acceptance": true
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"scope": "Unsubmitted preserved Astra working tree; prospective unchanged-Runner composition, NOT an exact submitted SHA packet",
|
||||
"base_commit": "10c62e1fa7b71576598583f434824b59816d4705",
|
||||
"old_submitted_commit": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"current_worktree_head": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"source_manifest_sha256": "1a7af44b722ab110aca508512ea55c18a19ca72ffc75db0ac6f39ad839079ae0",
|
||||
"prospective_guard_bytes": 487283,
|
||||
"guard_limit": 500000,
|
||||
"fits_before_final_docs_metadata": true,
|
||||
"actual_method_template_used": true,
|
||||
"all_source_and_code_diffs_included": true,
|
||||
"validation_sources_included": [
|
||||
"docs/spec/inputs/P22-02-accepted-usage.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"source_names": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_FINAL_REPAIR_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_SPEC_HASH_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"no_accepted_input_fields_omitted": true,
|
||||
"final_committed_packet_still_required": true,
|
||||
"worker_source_edited_by_root": false
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"scope": "Root actual tests of preserved, unsubmitted Astra work; not formal original acceptance",
|
||||
"argv": [
|
||||
"/Users/korizatou114/Antigravity/環境構築/agent-control/.venv/bin/python",
|
||||
"-B",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py",
|
||||
"-v"
|
||||
],
|
||||
"cwd": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement",
|
||||
"exit_code": 0,
|
||||
"elapsed_seconds": 0.7032037498429418,
|
||||
"source_hashes_before_after_equal": true,
|
||||
"source_hashes": {
|
||||
"tools/check_p22_asset_contracts.py": "7be6f044c63bf515d215731a6eef67e3aee1c2652e55a4e86cb3e45093316c83",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md": "c7fb25fa8d527cd7553f743117382a9a103dabcdd99e168bff0287e2cb523652",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_FINAL_REPAIR_CONTEXT.md": "185fb46091c74b275f7757236abf425d975029b66e6ff2c7b58d3b07effc72af",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_SPEC_HASH_CONTEXT.md": "3a5405655becb7edeacdddafbb4387d40a4c419435c15b4183501bf53697eae0",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json": "0d8bf55d4bd0a8fbc8eabed26c883fe6a0c25d0074e818629b924bb6e4302afc",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py": "20968f966912593a32a6d50ccf6e7c37cb26a380937fb26d1194f411d42b112e",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py": "dfa722ad8ac2eeb77f772a2f5cf8988af08698ff5db91f84f7b7dc91db5f4b2c",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json": "1bb42e293d814717c2ba6d21fe728ddfa8afda92f43c9f277d455a6f872c8bf8"
|
||||
},
|
||||
"run_timeout": {
|
||||
"run": "a999bbd142334aa582f2d373ed625e78",
|
||||
"exit_code": 124,
|
||||
"worker_result_received": false
|
||||
},
|
||||
"formal_acceptance_claimed": false
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
test_codec_and_strict_json (__main__.ContractTests.test_codec_and_strict_json) ... ok
|
||||
test_format_layout_state_and_quantity (__main__.ContractTests.test_format_layout_state_and_quantity) ... ok
|
||||
test_isolated_reachable_and_wrong_proof_quantity_pin (__main__.ContractTests.test_isolated_reachable_and_wrong_proof_quantity_pin) ... ok
|
||||
test_nonvacuous_and_unmade_denominator (__main__.ContractTests.test_nonvacuous_and_unmade_denominator) ... ok
|
||||
test_path_escape (__main__.ContractTests.test_path_escape) ... ok
|
||||
test_real_coverage_and_source_omission (__main__.ContractTests.test_real_coverage_and_source_omission) ... ok
|
||||
test_real_false_finished_and_fake_booleans (__main__.ContractTests.test_real_false_finished_and_fake_booleans) ... ok
|
||||
test_real_license_bytes_and_rights_subject (__main__.ContractTests.test_real_license_bytes_and_rights_subject) ... ok
|
||||
test_real_png_crc_and_layout (__main__.ContractTests.test_real_png_crc_and_layout) ... ok
|
||||
test_real_reference_mismatch (__main__.ContractTests.test_real_reference_mismatch) ... ok
|
||||
test_real_selected_contract_unknown_rights_and_forged_proof (__main__.ContractTests.test_real_selected_contract_unknown_rights_and_forged_proof) ... ok
|
||||
test_real_source_missing_and_stale (__main__.ContractTests.test_real_source_missing_and_stale) ... ok
|
||||
test_registered_cli_real_data_is_not_ready (__main__.ContractTests.test_registered_cli_real_data_is_not_ready) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 13 tests in 0.593s
|
||||
|
||||
OK
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
"""Observe the unchanged actual Runner packet without weakening its guard."""
|
||||
import argparse
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--project", required=True)
|
||||
parser.add_argument("--task", required=True)
|
||||
parser.add_argument("--commit", required=True)
|
||||
parser.add_argument("--output", required=True)
|
||||
a = parser.parse_args()
|
||||
control = Path(os.environ["OWNER_RUNNER_CONTROL"]).resolve()
|
||||
sys.path.insert(0, str(control))
|
||||
from runner.core import Runner, GateError
|
||||
runner = Runner(a.project)
|
||||
packet_code = Runner.packet.__code__
|
||||
observed = {}
|
||||
def trace(frame, event, arg):
|
||||
if frame.f_code is packet_code and event in ("return", "exception") and "body" in frame.f_locals:
|
||||
observed["body"] = copy.deepcopy(frame.f_locals["body"])
|
||||
return trace
|
||||
status = "built"
|
||||
try:
|
||||
sys.settrace(trace)
|
||||
runner.packet(a.task, "reviewer", a.commit)
|
||||
except GateError as exc:
|
||||
status = str(exc)
|
||||
finally:
|
||||
sys.settrace(None)
|
||||
body = observed.get("body")
|
||||
if body is None:
|
||||
raise RuntimeError("No actual body captured; cannot claim a measured packet")
|
||||
guard_bytes = len(json.dumps(body).encode())
|
||||
output = Path(a.output)
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
raw = json.dumps(body, ensure_ascii=False).encode()
|
||||
(output / "actual-body.json").write_bytes(raw)
|
||||
report = {"project": a.project, "task": a.task, "commit": a.commit,
|
||||
"method": "sys.settrace observes the actual unchanged Runner.packet locals; guard not bypassed",
|
||||
"control": str(control), "packet_source_sha256": hashlib.sha256(Path(control / "runner/core.py").read_bytes()).hexdigest(),
|
||||
"actual_guard_bytes": guard_bytes, "guard_limit": 500000, "fits": guard_bytes < 500000,
|
||||
"actual_packet_result": status, "model_called": False, "task_state_changed": False,
|
||||
"body_file_sha256": hashlib.sha256(raw).hexdigest(),
|
||||
"source_names": list(body.get("sources", {})),
|
||||
"validation_source_names": list(body.get("validation_sources", {})),
|
||||
"passed_validation_receipts_included": len(body.get("tests", []))}
|
||||
(output / "report.json").write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n")
|
||||
print(json.dumps(report, ensure_ascii=False))
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"project": "the-tree-p22-02-contract",
|
||||
"task": "P22-02",
|
||||
"commit": "aad6284fb75d32a73d0a4c00a53e9660ce76aad8",
|
||||
"method": "sys.settrace observes the actual unchanged Runner.packet locals; guard not bypassed",
|
||||
"control": "/private/tmp/the-tree-p24-02-control-r02",
|
||||
"packet_source_sha256": "34d0f62ec5b17b070a2d1ad4f58d06f3be7e9b6fb649ec86b366bc03b07c1329",
|
||||
"actual_guard_bytes": 491572,
|
||||
"guard_limit": 500000,
|
||||
"fits": true,
|
||||
"actual_packet_result": "built",
|
||||
"model_called": false,
|
||||
"task_state_changed": false,
|
||||
"body_file_sha256": "f64acba470e9c3182af7e4fef9344464a4c32e1de818468f1dd6c806a082eded",
|
||||
"source_names": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_FINAL_REPAIR_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_SPEC_HASH_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"validation_source_names": [
|
||||
"docs/spec/inputs/P22-02-accepted-usage.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"passed_validation_receipts_included": 0
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"probe_commit": "aad6284fb75d32a73d0a4c00a53e9660ce76aad8",
|
||||
"tree": "b56e0ddc03b705f8898387079f7bb636e3f0594d",
|
||||
"parent": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"worktree_HEAD_unchanged": true,
|
||||
"task_state_unchanged": "blocked",
|
||||
"source_names": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_FINAL_REPAIR_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_SPEC_HASH_CONTEXT.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"worker_result_unchanged": true,
|
||||
"submitted_or_accepted": false
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"task_id": "P22-02",
|
||||
"commit": "10c62e1fa7b71576598583f434824b59816d4705",
|
||||
"status": "blocked",
|
||||
"summary": "仕様の固定SHAが現物と不一致です。末尾改行を除くと指定SHAに一致しますが、無断で正規化・仕様変更はできません。今回追加した未完成checkerは撤去済みで、成果物変更はありません。正式試験は未実行、原受入は0/1です。",
|
||||
"acceptance_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"findings": [
|
||||
{
|
||||
"severity": "high",
|
||||
"message": "docs/spec/acceptance/P22-02.json: 契約SHA f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875、現物SHA c26c0b12cf7e7a7c46e671acde2e00762904732c1cd6381a53836e3d7b3f9824。差は末尾改行です。契約管理側で固定値と現物の整合が必要です。受入入力のraw SHAは一致しています。"
|
||||
}
|
||||
]
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"task_id": "P22-02",
|
||||
"commit": "c6ccc5a6ab4b1670f1ccf813937edf339ca19139",
|
||||
"kind": "validation",
|
||||
"checks": [
|
||||
{
|
||||
"id": "p22-contract",
|
||||
"exit_code": 2,
|
||||
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p22-02-contract/runs/fcebc9707f4e461e848e32e900b489ee",
|
||||
"passed": false
|
||||
}
|
||||
],
|
||||
"passed": false
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"probe_commit": "aad6284fb75d32a73d0a4c00a53e9660ce76aad8",
|
||||
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p22-02-contract/runs/25eefc570e4540d9aacd05c9763233b1",
|
||||
"model": "claude-opus-5-5",
|
||||
"read_only": true,
|
||||
"formal_original_review": false,
|
||||
"task_state_unchanged": true,
|
||||
"result": {
|
||||
"summary": "判定: changes_requested(形式受入は不可、要求もなし)。前回Rootが指摘した3件の欠陥のうち、登録argvの受付、常に失敗するreadinessの撤去、検証・レビュー・統合の循環の除去は対応済みで、コード上でも確認できた。Rootの実測では、パケット491,572 bytes(500,000未満)、テスト13件合格、整合性検査exit 0、require-readyはexit 2(pending 614件、selected 0件)。\n\n具体的なコード欠陥(このタスクの範囲内で直すもの):\n- 到達可能性の正例がreducer(technical_readiness)単体のテストしかない。実際の経路(selection_ready、receipt、check)を通る正例がない。\n- 権利文書、命名、寸法・レイアウトが、選定した素材や用途の要件と結び付いていない。結び付きはRoot発行の証明(receipt)任せになっている。\n- 未知の数量(null)が明示的な解決なしにreadinessへ到達できる。\n- ledgerを改変するnegativeをcheck()経由で試していない。\n- 文書とvalidation.jsonの記述が古く、実測値と食い違っている。\n\n原成果側の未完了(コード欠陥とは別):\n- 614件すべて未選定(候補495件、欠損119件)。\n- 作者・権利の確定、画面表示・聴感の証拠、必須範囲・開示の証拠、D08/D09がまだない。\n- 独立レビュー、統合、最終受入(原30パッケージ/88成果、部分点なし)も残っている。",
|
||||
"original_unit_accepted": false,
|
||||
"technical_findings": [
|
||||
{
|
||||
"severity": "high",
|
||||
"file": "docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py",
|
||||
"message": "到達可能性の正例(test_isolated_reachable…)は、proof_matchesの戻り値Trueをtechnical_readinessに渡しているだけで、selection_ready、receipt(checkpoint配下の文書のピン固定、anchor検証、p22-evidence-v1形式)、check()の正の経路を一度も通っていない。修理指示の「純関数で到達可能性を証明」の核心部分が未証明で、実際の経路で到達不能なバグがあっても検出できない。checkpointsを模した一時ROOTか、raw/safe_pathのモックを使い、selection_readyとreceiptを通る正例を1件追加する必要がある。"
|
||||
},
|
||||
{
|
||||
"severity": "medium",
|
||||
"file": "tools/check_p22_asset_contracts.py",
|
||||
"message": "selection_readyのrights.documentsは、ピンが合っているかしか見ておらず、選定した素材との関係を検証していない。例えば内部由来のBGMや出所不明の素材にKenneyのLicense.txtを付け、license='CC0'とすれば構造検査を通る。publisher-archive-byte-verificationの該当member(同一バイト)か、内部由来の記録との一致を必須にする必要がある。現状は防止がRootのrights receiptだけに依存している。"
|
||||
},
|
||||
{
|
||||
"severity": "medium",
|
||||
"file": "tools/check_p22_asset_contracts.py",
|
||||
"message": "quantities_validは、受入記録側がnullの数量(施設の全行など)について値の欠如(None)を許している。コメントでは「quantity receiptで解決」とあるが、それを強制するコードがない。全数量が未知のままreadinessに到達でき、spec原文の「unknownを確定しない」とreadinessの非空虚性が両立していない。"
|
||||
},
|
||||
{
|
||||
"severity": "medium",
|
||||
"file": "tools/check_p22_asset_contracts.py",
|
||||
"message": "命名(nameがパスのbasenameと等しいだけ)と差替履歴(replacement_chainは先頭と末尾しか見ない)が実質的に恒真になっている。region(領域)もsourceの範囲内かどうかしか見ず、受入記録のusage_condition.original_size(2x1など)やatlasのcell・grid境界に結び付いていない。解像度・レイアウトの不一致を構造的に検出できない。"
|
||||
},
|
||||
{
|
||||
"severity": "medium",
|
||||
"file": "docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py",
|
||||
"message": "negativeが純関数への合成入力と、snapshotの複製の改変にとどまっている。実際のledgerを改変したうえでcheck()経由で拒否されることを試していない(selectionsの欠落・追加・偽の'selected'、source_pinsの削除・改ざん、referencesの改ざん、unit_proofsへのbool注入)。spec原文の「negativeはledgerの該当値の改変・削除を含める」を満たしていない。"
|
||||
},
|
||||
{
|
||||
"severity": "medium",
|
||||
"file": "tools/check_p22_asset_contracts.py",
|
||||
"message": "verify_existing_evidenceは、observed-existing-asset-contractsのsource_pinsを無条件にpinned()で照合する。そのため、文書で提案している製品差分(pixel_tower_art.gdなど)を適用すると、ledgerを更新しても整合性検査がexit 1になる。Kenneyのmemberと内部BGMについては、バイトが異なると黙ってskipし、staleであることを報告しない。製品変更後にreadinessへ到達する経路(evidenceの再観測が必要なこと)を明記し、staleを検出・報告する必要がある。"
|
||||
},
|
||||
{
|
||||
"severity": "low",
|
||||
"file": "tools/check_p22_asset_contracts.py",
|
||||
"message": "referencesの期待集合がEVIDENCEディレクトリのiterdirで決まるため、Rootが証拠ファイルを1件追加しただけでledgerが不一致(exit 1)になる。issuer.role='root'/'owner'は自己申告のフィールドで、認証されていない(checkpointsが書き込み禁止であることに依存している)。Oggの判定も先頭128 bytes内の文字列だけで弱い。"
|
||||
},
|
||||
{
|
||||
"severity": "low",
|
||||
"file": "docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json",
|
||||
"message": "complete_packet_bytes=nullで、文書でも「487283はprospective、未確認」とされているが、Rootの実測は491,572 bytesで、上限500,000未満は確認済み。ASSET_CONTRACTS.mdは存在しないキー名「evidence_pins」に言及している(実際のキーはreferences)。いずれも記録が古いか不整合で、Root側で事実に基づき訂正が必要。CLIのテストがpending=614を固定値で表明しているため、正規の選定が1件入っただけで壊れる。"
|
||||
},
|
||||
{
|
||||
"severity": "low",
|
||||
"file": "docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py",
|
||||
"message": "build_contract.pyはledger全体を上書きし、selectionsを初期化する。read_textのencodingも指定していない。読み取り専用の検証からは呼ばれないが、誤って実行すると選定作業が失われる。"
|
||||
}
|
||||
],
|
||||
"remaining_original_conditions": [
|
||||
"614の正確な用途すべてで、使用可能な選定素材がまだない(候補495件、欠損119件、選定0件)",
|
||||
"用途ごとに最終の解像度、frame・layout、命名、差替参照、製品側の参照を確定する",
|
||||
"作者・権利の欠落を解消する(権利が未確定の媒体20件を含む。内部BGMの由来記録は最終承認ではない)",
|
||||
"必須だが未制作の範囲と開示の証拠(unit_proofsのmandatory_scopeとdisclosure)がまだない",
|
||||
"D08/D09の内容と数量はunknownのまま。発明せず、owner証拠で確定させる",
|
||||
"該当する画面表示・聴感の実証拠(usability receipt)がない",
|
||||
"Rootによる正式な静的検証と、意味のあるnegative(ledgerを改変しcheck()経由で拒否されることの確認を含む)",
|
||||
"独立したOpusレビュー",
|
||||
"統合と最終受入(原30パッケージ/88成果、部分点なし)"
|
||||
]
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"archive": "artifacts/original-completion-2026-10-02/p22-02-astra-preserved-preflight-r03/preserved-worker-outputs.tar.gz",
|
||||
"archive_sha256": "f522e723f88964fd6a8567dc5c8cd56b33bb46d934b3d370fd01e568b7167a4b",
|
||||
"members": {
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md": "c7fb25fa8d527cd7553f743117382a9a103dabcdd99e168bff0287e2cb523652",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_FINAL_REPAIR_CONTEXT.md": "185fb46091c74b275f7757236abf425d975029b66e6ff2c7b58d3b07effc72af",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/P22_SPEC_HASH_CONTEXT.md": "3a5405655becb7edeacdddafbb4387d40a4c419435c15b4183501bf53697eae0",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/asset-contracts.json": "0d8bf55d4bd0a8fbc8eabed26c883fe6a0c25d0074e818629b924bb6e4302afc",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/build_contract.py": "20968f966912593a32a6d50ccf6e7c37cb26a380937fb26d1194f411d42b112e",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/test_contract.py": "dfa722ad8ac2eeb77f772a2f5cf8988af08698ff5db91f84f7b7dc91db5f4b2c",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json": "1bb42e293d814717c2ba6d21fe728ddfa8afda92f43c9f277d455a6f872c8bf8",
|
||||
"tools/check_p22_asset_contracts.py": "7be6f044c63bf515d215731a6eef67e3aee1c2652e55a4e86cb3e45093316c83"
|
||||
},
|
||||
"all_raw_bytes_preserved": true,
|
||||
"worktree_unchanged": true,
|
||||
"source_deleted": false,
|
||||
"worker_submission_claimed": false
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
--- a/docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md
|
||||
+++ b/docs/plans/original-completion-2026-10-02/execution/p22-02/ASSET_CONTRACTS.md
|
||||
@@ -1,19 +1,15 @@
|
||||
-# P22-02 素材契約(原成果未完了)
|
||||
+# P22-02 素材契約の実装候補(原成果未完了)
|
||||
|
||||
-原30パッケージ/88成果・部分点なしを維持する。614 identityは360施設、176人物、2状態群、76その他であり、614画像ではない。495 candidate、119 missing、19 sourceを全て保持する。選定済完成資産は0。D08/D09の最終内容・数量はunknown。
|
||||
+原30パッケージ/88成果・部分点なし。614 identityは360施設/176人物/2状態群/76その他であり、614画像ではない。現台帳は全614未達、495既存候補/119候補欠損/19source。D08/D09の最終数量・内容はunknown。記録整合性の0終了を完成素材・原P22-02へ加点しない。
|
||||
|
||||
-asset-contracts.jsonは公開JSON共有参照(d/l/s/r)で、accepted_inputの全フィールドとcurrent契約の全フィールドを損失なく保持する。各identityの命名はid、候補名はcandidate_refの実path、形式と現raw SHAはcandidate_pool、historical適用性はcandidate_refs、creatorと不足は各契約にある。差替鎖は歴史的representation→現candidate→未選定replacement。missingをcode/file/fallbackで充足しない。最終の解像度・frame/layout・命名・差替参照は未確定として扱う。
|
||||
+台帳はimmutable accepted inputをraw SHAと各file semantic SHAで参照し、全fieldを復元する。current referenceもSHAで固定した歴史観測として再構成し、現在のsource factsと各identityのselection/state/proofsは別に検証する。凍結snapshot全体のmirror一致やselected_assets空の固定を判定にしない。
|
||||
|
||||
-Kenney Tiny Town/Tiny Dungeon/Interface Soundsのpublisher/member/license/manifest証拠はevidence_pinsの文書を完全再利用する。配布元URLとCC0記録はcandidate_poolおよび既存ライセンス証拠を参照。内部BGM合成recipeは内部由来であり、第三者CC0や最終聴感・権利受入へ昇格しない。自己制作・別許諾を排除しない。未知creator/rightsを推測しない。
|
||||
+checkerはread-only --verify-only/--accepted-input/--require-readyを受理する。記録整合性とvalidation-readyを分離し、準備判定は全exact useの実資産・型/量/形式・適合・creator/right・安全な参照差替・必要usability・開示・必須scope証拠に結合する。空集合/fallback/filepresence/偽booleanでPASSしない。validate→別Opusreview→integration→finalを経た後だけ原成果完了を認定する。将来の正当な証拠は到達可能であり、現data614未達は非0を維持する。
|
||||
|
||||
-checkerの通常0終了は記録整合性のみ。--require-readyは原条件未達なら2終了。READYには空でない完成資産、全exact useの選定・実利用・権利、未制作/開示不足の解消、必要な画面/聴感、Root静的検証と意味のあるnegative、独立Opusレビュー、統合・最終受入が必要。workerは正式試験も受入も主張しない。
|
||||
+Kenneyのpublisher/member/License証拠と内部合成BGMの起源を区別。創作者・最終品質・実表示/聴感は捏造しない。候補19sourceの現在bytes、PNG CRC/寸法、WAV形式、既存atlas12x11/16px/間隔0、Theme参照、historical/source applicabilityを検証する。状態群を画像として扱わず、量のNoneを0へ置換しない。
|
||||
|
||||
-## 次の製品変更提案(この実装では適用しない)
|
||||
+Rootは保持された未提出候補に13個の実試験を実行し全PASSを確認した。isolated reachable正例は内部純関数だけで、実P22/素材受入へ換算しない。意味のある負例はcoverage/duplicate/stale/missing source、wrong proof/quantity/pin、CRC/layout、license/rights、counterfeit finished、codec cycle/boolindex/key/type/NaNInf、path escape、実CLI非0を含む。正式unit受入は未実施。
|
||||
|
||||
-- scripts/ui/pixel_tower_art.gd、standard_room_art.gd、infirmary_room_art.gd: 各施設Lv1–3/表裏/外観内装のidから選定representationへ明示対応を追加。共有atlasや専用一部装飾を全施設に流用して完成扱いしない。最小差分は選定されたidの参照と該当描画分岐のみ。実画面で各対応と未制作開示を確認する。
|
||||
-- scripts/ui/pixel_people.gd: character条件ごとの選定と必要variant参照を明示し、2状態群は状態表現として接続する。数量は承認されるまでunknown。該当人物・状態の画面確認が必要。
|
||||
-- assets/themes/japanese_fantasy/visual-theme-v1.tres、scenes/main/world_preview.gd、scenes/main/main.gd: 世界/skin候補のcreator/rightsを解決してから選定素材への参照のみ差替。サイズ、alpha、atlas region、nearest/mipmapと全参照整合を確認し実表示で確認する。
|
||||
-- scripts/ui/paired_bgm.gdと2 candidate WAV: internal-origin-observationsのrecipeとbyte証拠を保持し、creator/権利の承認と両contextの聴感を取得してから最終選定。UI4音もpublisher証拠だけで最終聴感を代用しない。
|
||||
-- missing_candidateの119 identityは各契約のsource_anchors/usage_conditionを制作依頼に渡し、Kenney適合候補を先に確認する。最小asset/reference差分は選定後にのみ確定できる。未確定の絵や数量を捏造しない。
|
||||
+現在残る製品作業: 全利用条件に適合する素材/コード表現を選定し、具体的actor/facility/state/Theme参照を接続する。119候補欠損はsource_anchorsと使用条件に基づきKenneyを先に検討する。必要な制作数量・権利・品質を確定し、全対応の実画面/聴感と元条件の全証拠を揃える。未確定素材を適当に差替えたり既存generic表現を専用完成へ昇格しない。
|
||||
|
||||
-Runnerの検証対象: 全614 coverage、全decoded semantic hash、raw input/source/evidence pins、historical適用性、PNG寸法、参照・source omission、duplicate、cycle/bad index/key/type、unknown rights/false finished、数量変更。negativeはledgerの該当値の改変・削除、source/寸法・reference変更を含める。完全packetを500000 bytes未満で確認し、欠落・切捨てで縮小しない。その後に必要な製品実装・usability・独立レビュー・統合・finalを行う。
|
||||
+保持されたAstra変更は900秒timeoutで提出応答未受領。候補は未採用。正式submitted SHAの全source/diff/validation_sources/receiptsを含む実packet<500000、独立レビュー、統合/最終が必要。未提出のprospective487283bytesは実際の最終packetへ代用しない。
|
||||
--- a/docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json
|
||||
+++ b/docs/plans/original-completion-2026-10-02/execution/p22-02/validation.json
|
||||
@@ -7,11 +7,40 @@
|
||||
"spec_sha256": "f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875",
|
||||
"spec_raw_sha256": "c26c0b12cf7e7a7c46e671acde2e00762904732c1cd6381a53836e3d7b3f9824",
|
||||
"accepted_input_raw_sha256": "45fa52acf0c8bd4dd58c3b40b681cb92066f05d617df157fc18370a5e8816281",
|
||||
- "ledger_bytes": 453678,
|
||||
- "packet_bytes_before_this_validation_metadata": 472408,
|
||||
+ "ledger_bytes": 35441,
|
||||
+ "packet_bytes_before_this_validation_metadata": null,
|
||||
"syntax_ast_parse": "passed; not formal validation",
|
||||
"complete_packet_limit": 500000,
|
||||
- "runner_required": ["exact static validation", "meaningful negatives", "packet byte total", "applicable display and hearing", "independent Opus review", "integration and final original acceptance"],
|
||||
- "expected_exit_codes": {"record_integrity_if_valid": 0, "require_ready_with_current_unmet_conditions": 2, "integrity_error": 1},
|
||||
- "original_incomplete": ["614 exact uses lack completed selected usable assets; 495 candidates and 119 missing are not completion", "final per-use naming/resolution/frame/layout/replacement references", "creator and rights gaps including 20 media; internal BGM origin is not final approval", "mandatory unmade/disclosure gaps; D08/D09 content and quantities unknown", "applicable display/hearing evidence", "Root static validation and meaningful negatives", "independent Opus review", "integration and final original 30 packages/88 delivery units acceptance"]
|
||||
+ "runner_required": [
|
||||
+ "exact static validation",
|
||||
+ "meaningful negatives",
|
||||
+ "packet byte total",
|
||||
+ "applicable display and hearing",
|
||||
+ "independent Opus review",
|
||||
+ "integration and final original acceptance"
|
||||
+ ],
|
||||
+ "expected_exit_codes": {
|
||||
+ "record_integrity_if_valid": 0,
|
||||
+ "require_ready_with_current_unmet_conditions": 2,
|
||||
+ "integrity_error": 1
|
||||
+ },
|
||||
+ "original_incomplete": [
|
||||
+ "614 exact uses lack completed selected usable assets; 495 candidates and 119 missing are not completion",
|
||||
+ "final per-use naming/resolution/frame/layout/replacement references",
|
||||
+ "creator and rights gaps including 20 media; internal BGM origin is not final approval",
|
||||
+ "mandatory unmade/disclosure gaps; D08/D09 content and quantities unknown",
|
||||
+ "applicable display/hearing evidence",
|
||||
+ "Root static validation and meaningful negatives",
|
||||
+ "independent Opus review",
|
||||
+ "integration and final original 30 packages/88 delivery units acceptance"
|
||||
+ ],
|
||||
+ "prospective_full_packet_bytes": 487283,
|
||||
+ "exact_final_submitted_packet_still_required": true,
|
||||
+ "root_preserved_test_count": 13,
|
||||
+ "root_preserved_tests": "all pass; actual diagnostic execution not original acceptance",
|
||||
+ "worker_timeout_exit_code": 124,
|
||||
+ "worker_submission_result_received": false,
|
||||
+ "registered_cli_readonly_arguments_supported": true,
|
||||
+ "current_original_unit_ready": false,
|
||||
+ "current_pending_identity_count": 614
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
"""UNAPPLIED owner-side proposal; no activation or automatic authorization."""
|
||||
import json
|
||||
|
||||
def install(Runner):
|
||||
previous = Runner.process
|
||||
def process(self, task_id, role, service, argv, cwd, *args, **kwargs):
|
||||
target = (self.config["project"] == "the-tree-p22-02-contract"
|
||||
and task_id == "P22-02" and role == "implementer" and service == "codex")
|
||||
if target:
|
||||
task = self.task(task_id)
|
||||
contract = json.loads(task["contract"])
|
||||
if not (task["state"] == "implementing" and task["repairs"] == 3
|
||||
and contract["max_repair_attempts"] == 3
|
||||
and contract["base_commit"] == "10c62e1fa7b71576598583f434824b59816d4705"
|
||||
and contract["spec_sha256"] == "f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875"):
|
||||
raise ValueError("Exact owner-authorized finalization context required")
|
||||
row = self.db.execute("SELECT data FROM events WHERE task_id=? AND event='owner_authorized_p22_finalization' ORDER BY id DESC LIMIT 1", (task_id,)).fetchone()
|
||||
approval = json.loads(row[0]) if row else {}
|
||||
if not (approval.get("direct_human_reply") and approval.get("cap") == 3
|
||||
and approval.get("retained_used") == 2
|
||||
and approval.get("effective_implementer_timeout_seconds") == 1800):
|
||||
raise ValueError("No recorded direct human permission for timeout change")
|
||||
if self.config["policy"]["timeout_seconds"] != 900 or kwargs.get("timeout") not in (None, 900):
|
||||
raise ValueError("Unexpected original timeout context")
|
||||
kwargs["timeout"] = 1800
|
||||
self.event(task_id, "owner_scoped_finalization_timeout", {"role": role,
|
||||
"service": service, "argv": argv, "cwd": str(cwd), "effective_timeout_seconds": 1800,
|
||||
"project_policy_timeout_unchanged": 900, "repairs": 3, "global_policy_changed": False})
|
||||
return previous(self, task_id, role, service, argv, cwd, *args, **kwargs)
|
||||
Runner.process = process
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"recorded_at": "2026-10-13T09:11:34.088461+00:00",
|
||||
"task": {
|
||||
"id": "P22-02",
|
||||
"state": "implementing",
|
||||
"repairs": 1,
|
||||
"submitted": null,
|
||||
"contract": {
|
||||
"id": "P22-02",
|
||||
"title": "素材契約と権利(原条件全体、記録だけの完了代用なし)",
|
||||
"requirement_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"acceptance_ids": [
|
||||
"P22-02"
|
||||
],
|
||||
"spec_ref": "docs/spec/acceptance/P22-02.json",
|
||||
"base_commit": "10c62e1fa7b71576598583f434824b59816d4705",
|
||||
"worker": "codex",
|
||||
"allowed_paths": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p22-02/**",
|
||||
"tools/check_p22_asset_contracts.py"
|
||||
],
|
||||
"depends_on": [],
|
||||
"resource_locks": [
|
||||
"p22-asset-contracts-and-rights"
|
||||
],
|
||||
"validation_ids": [
|
||||
"p22-contract"
|
||||
],
|
||||
"max_repair_attempts": 2,
|
||||
"spec_sha256": "f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875"
|
||||
}
|
||||
},
|
||||
"live_run": {
|
||||
"id": "dc780018ec0b4da09d82613fc702f0ed",
|
||||
"status": "running",
|
||||
"pid": 90104,
|
||||
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p22-02-contract/runs/dc780018ec0b4da09d82613fc702f0ed"
|
||||
},
|
||||
"process_alive_verified": true,
|
||||
"active_exec_session": 44558,
|
||||
"first_worker_outcome": "blocked due raw-vs-strip contract hash; incomplete checker withdrawn; no source edits retained",
|
||||
"normal_repair_consumed": 1,
|
||||
"cap": 2,
|
||||
"no_extra_permission_requested": true,
|
||||
"duplicate_worker_started": false,
|
||||
"unit_accepted": false,
|
||||
"actual_worker_model": "gpt-6.1-sol",
|
||||
"commander_model": "claude-opus-5-5",
|
||||
"accepted_input_lossless_bytes": 217190,
|
||||
"full_decoded_records": 614,
|
||||
"current_candidate_rows": 495,
|
||||
"missing_candidate_rows": 119,
|
||||
"current_candidate_paths": 19
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"task": "P22-02",
|
||||
"base_commit": "10c62e1fa7b71576598583f434824b59816d4705",
|
||||
"spec_ref": "docs/spec/acceptance/P22-02.json",
|
||||
"contract_spec_sha256": "f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875",
|
||||
"raw_spec_sha256": "c26c0b12cf7e7a7c46e671acde2e00762904732c1cd6381a53836e3d7b3f9824",
|
||||
"runner_strip_spec_sha256": "f252de3c5cff7ebfa62322ae2f2df09fb80a44bc59eb286b76d4acb4c12ca875",
|
||||
"raw_worktree_equals_base_git_blob": true,
|
||||
"spec_changed": false,
|
||||
"contract_changed": false,
|
||||
"root_normalized_hash_verification_passed": true,
|
||||
"reason": "Runner git helper uses stdout.strip(), then UTF8; source_pins and accepted input raw SHA remain raw bytes, not stripped"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
"""Read-only advisory review of preserved P22 content; no original acceptance receipt."""
|
||||
import sys, os, json
|
||||
from pathlib import Path
|
||||
control = Path(os.environ['OWNER_RUNNER_CONTROL'])
|
||||
sys.path.insert(0, str(control))
|
||||
from runner.core import Runner, read_json
|
||||
coordinator = Path('/private/tmp/the-tree-owner-model-cli.py').read_text().rsplit('from runner.cli import main', 1)[0]
|
||||
exec(compile(coordinator, '/private/tmp/the-tree-owner-model-cli.py', 'exec'))
|
||||
r = Runner('the-tree-p22-02-contract')
|
||||
task = r.task('P22-02')
|
||||
sha = 'aad6284fb75d32a73d0a4c00a53e9660ce76aad8'
|
||||
prompt = r.packet('P22-02', 'reviewer', sha)
|
||||
supplement = {"purpose": "Independent advisory technical review ONLY; formal acceptance validator remains failed, no submitted worker result, no original acceptance or integration.", "actual_root_packet_guard_bytes": 491572, "actual_retained_code_sha_equal": True, "actual_root_tests": "13 PASS; independent Root diagnostic execution; unchanged code SHA", "actual_cli": "integrity exit0, require-ready exit2, pending614 selected0", "coordinator_failure_resolved": "References outside worker sandbox missing, Root actual complete packet now measured on exact probe tree. Do not falsify worker blocked result."}
|
||||
prompt = 'Read-only independent technical review, no editing, tools or execution. Review every original acceptance and all technical defects using provided full packet. Distinguish concrete code defects from original unfinished assets/values. Formal acceptance cannot pass and is not requested. Return concise Japanese findings with file and severity. Nothing you return changes task state or original denominator.\n' + prompt + '\nCOORDINATOR_DIAGNOSTIC_FACTS:\n' + json.dumps(supplement, ensure_ascii=False)
|
||||
schema = {"type": "object", "additionalProperties": False, "required": ["summary", "original_unit_accepted", "technical_findings", "remaining_original_conditions"], "properties": {"summary": {"type": "string"}, "original_unit_accepted": {"type": "boolean", "enum": [False]}, "technical_findings": {"type": "array", "items": {"type": "object", "additionalProperties": False, "required": ["severity", "file", "message"], "properties": {"severity": {"type": "string", "enum": ["critical", "high", "medium", "low"]}, "file": {"type": "string"}, "message": {"type": "string"}}}}, "remaining_original_conditions": {"type": "array", "items": {"type": "string"}}}}
|
||||
with r.lease('operation:P22-02', 'advisory-review:P22-02:' + str(os.getpid())):
|
||||
result, artifact = r.llm('P22-02', 'reviewer', 'claude', prompt, Path(task['worktree']), schema)
|
||||
assert r.task('P22-02')['state'] == task['state']
|
||||
r.event('P22-02', 'independent_technical_advisory_review', {"probe_commit": sha, "artifact": str(artifact), "formal_acceptance": False, "state_changed": False})
|
||||
report = {"probe_commit": sha, "artifact": str(artifact), "model": "claude-opus-5-5", "read_only": True, "formal_original_review": False, "task_state_unchanged": True, "result": result}
|
||||
output = Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/independent-technical-review-r05.json')
|
||||
output.write_text(json.dumps(report, ensure_ascii=False, indent=2) + '\n')
|
||||
print(json.dumps(report, ensure_ascii=False))
|
||||
@@ -3668,6 +3668,17 @@
|
||||
"text": "\tprint(\"TOMARI_FLOOR_TROUBLE checks=%d failures=%d\" % [checks,failures])"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"test": "tests/s1/test_p08_combined_migration.gd",
|
||||
"template": "P08 combined migration: <checks> checks, <failures> failures",
|
||||
"required": true,
|
||||
"fixed_check_count_used": false,
|
||||
"source_sha256_at_schema_audit": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855",
|
||||
"authority": {
|
||||
"path": "docs/spec/acceptance/P08-02.json",
|
||||
"scope": "new standalone mixed suite; native execution pending"
|
||||
}
|
||||
}
|
||||
],
|
||||
"unknown_roster_suite_policy": "refuse, explicitly review its source/schema before accepting",
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"host": "TakeshinoMac-mini",
|
||||
"observed_direct_lock_events": [
|
||||
"2026-10-12 21:47:18.329",
|
||||
"2026-10-13 12:57:42.740",
|
||||
"2026-10-13 13:31:42.881"
|
||||
],
|
||||
"time_zone": "Asia/Tokyo",
|
||||
"observed_os_sequence": [
|
||||
"Received a kAELockScreenEvent",
|
||||
"lockScreenImmediateUsingShortTimeout",
|
||||
"kLWLockFromDirectLock"
|
||||
],
|
||||
"guardian_bundle": "com.openai.sky.CUAService.guardian",
|
||||
"guardian_version": "26.1005.1001425",
|
||||
"guardian_same_time_hid_event": "2026-10-13 12:57:42.678",
|
||||
"inference": "Guardian-linked explicit lock request is strongly indicated; exact trigger local input, lease or connection is not established. Idle display dim locks are a distinct observed mechanism.",
|
||||
"power_settings": {
|
||||
"sleep_minutes": 0,
|
||||
"display_sleep_minutes": 180,
|
||||
"screensaver_idle_seconds": 0
|
||||
},
|
||||
"official_source": "https://learn.chatgpt.com/docs/changelog",
|
||||
"source_claim": "Locked use safeguards include relock on local input. This does not establish the trigger of these particular events.",
|
||||
"permanent_settings_changed": false,
|
||||
"guardian_bypassed": false,
|
||||
"game_data_changed": false,
|
||||
"raw_log_sha256": {
|
||||
"direct-event.log": "2101ce53d108844644a9fec40d488d1740b60dd2ecca2571de74d78f529d3671",
|
||||
"direct-event-second.log": "fea0ae7362ddea7de2fca59a52a2611137ece9674a21dfe03ccba4f2e1ce443c"
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# Macロックの調査(2026-10-13)
|
||||
|
||||
TakeshinoMac-miniで、画面消灯に伴うロックと、明示的なロック要求を区別した。12:57:42.678にCodex Computer UseのGuardianがHIDイベントを送出し、12:57:42.740にloginwindowがAppleEventのロック要求を受けた。同様の明示要求は前夜21:47と当日13:31にもある。12:57と13:31の画面消灯は要求の約30秒後であり、この2件の先行原因ではない。
|
||||
|
||||
Guardianに関連する明示要求を強く示すが、どの操作や接続状態が発火したかは未確定。公式changelogにはLocked useのローカル入力時再ロックが記載されるが、今回の各イベントの具体的発火条件を確定する証拠にはしない。Runnerやゲームがロックしたという根拠はない。
|
||||
|
||||
AC設定はシステムsleep 0分、画面sleep 180分、screen saver idleTime 0秒。設定変更やGuardian停止・迂回は実施していない。短い自前utilityだけにcaffeinate -d -iを適用し、実行中のPreventUserIdleDisplaySleep=1と終了後0を実測した。この方法は次回の許可された検証中に限る画面消灯対策として使えるが、明示ロック防止や長時間ゲーム受入の証拠ではない。外部PIDに-wした初回試行はassertionを観測できず、不成立として保存した。
|
||||
|
||||
生ログはignored artifactsに保持し、INVESTIGATION.jsonにSHAを記録。常設OS設定・保存データ・権限を変更していない。
|
||||
|
||||
公式資料: https://learn.chatgpt.com/docs/changelog
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"recorded_at": "2026-10-13T10:07:01.641642+00:00",
|
||||
"scope": "Ephemeral idle-display/system sleep prevention for one owned dummy process only; no unlock or safety bypass",
|
||||
"argv": [
|
||||
"/usr/bin/caffeinate",
|
||||
"-d",
|
||||
"-i",
|
||||
"-w",
|
||||
"11677"
|
||||
],
|
||||
"before": [
|
||||
" PreventUserIdleDisplaySleep 0"
|
||||
],
|
||||
"during": [
|
||||
" PreventUserIdleDisplaySleep 0"
|
||||
],
|
||||
"after": [
|
||||
" PreventUserIdleDisplaySleep 0"
|
||||
],
|
||||
"guard_exit_code": 0,
|
||||
"target_exited": true,
|
||||
"guard_released_on_target_exit": true,
|
||||
"permanent_settings_changed": false,
|
||||
"guardian_disabled_or_modified": false,
|
||||
"screen_unlocked_or_input_injected": false,
|
||||
"game_process_or_player_data_touched": false,
|
||||
"does_not_prevent_explicit_guardian_relock": true,
|
||||
"activation_observed": false,
|
||||
"mitigation_validated": false,
|
||||
"disposition": "Exit0 and release alone do not establish assertion activation; during reading stayed0. Retain failed/inconclusive -w pilot."
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"recorded_at": "2026-10-13T10:10:02.763962+00:00",
|
||||
"method": "caffeinate holds assertions on its utility, rather than external -w pid",
|
||||
"argv": [
|
||||
"/usr/bin/caffeinate",
|
||||
"-d",
|
||||
"-i",
|
||||
"/usr/bin/python3",
|
||||
"-B",
|
||||
"-c",
|
||||
"import time; time.sleep(8)"
|
||||
],
|
||||
"probes": [
|
||||
[
|
||||
" PreventUserIdleDisplaySleep 1",
|
||||
" pid 12637(caffeinate): [0x00261d6d00018c83] 00:00:00 PreventUserIdleSystemSleep named: \"caffeinate command-line tool\" ",
|
||||
"\tDetails: caffeinate asserting on behalf of '/usr/bin/python3' (pid 12636)",
|
||||
" pid 12637(caffeinate): [0x00261d6d00058c84] 00:00:00 PreventUserIdleDisplaySleep named: \"caffeinate command-line tool\" ",
|
||||
"\tDetails: caffeinate asserting on behalf of '/usr/bin/python3' (pid 12636)"
|
||||
],
|
||||
[
|
||||
" PreventUserIdleDisplaySleep 1",
|
||||
" pid 12637(caffeinate): [0x00261d6d00018c83] 00:00:01 PreventUserIdleSystemSleep named: \"caffeinate command-line tool\" ",
|
||||
"\tDetails: caffeinate asserting on behalf of '/usr/bin/python3' (pid 12636)",
|
||||
" pid 12637(caffeinate): [0x00261d6d00058c84] 00:00:01 PreventUserIdleDisplaySleep named: \"caffeinate command-line tool\" ",
|
||||
"\tDetails: caffeinate asserting on behalf of '/usr/bin/python3' (pid 12636)"
|
||||
],
|
||||
[
|
||||
" PreventUserIdleDisplaySleep 1",
|
||||
" pid 12637(caffeinate): [0x00261d6d00018c83] 00:00:02 PreventUserIdleSystemSleep named: \"caffeinate command-line tool\" ",
|
||||
"\tDetails: caffeinate asserting on behalf of '/usr/bin/python3' (pid 12636)",
|
||||
" pid 12637(caffeinate): [0x00261d6d00058c84] 00:00:02 PreventUserIdleDisplaySleep named: \"caffeinate command-line tool\" ",
|
||||
"\tDetails: caffeinate asserting on behalf of '/usr/bin/python3' (pid 12636)"
|
||||
]
|
||||
],
|
||||
"after": [
|
||||
" PreventUserIdleDisplaySleep 0"
|
||||
],
|
||||
"exit_code": 0,
|
||||
"stderr": "",
|
||||
"activation_observed": true,
|
||||
"release_observed": true,
|
||||
"mitigation_validated": true,
|
||||
"permanent_settings_changed": false,
|
||||
"guardian_or_manual_lock_bypassed": false,
|
||||
"game_or_player_data_touched": false
|
||||
}
|
||||
@@ -122,5 +122,16 @@ def p18_validate(self, task_id):
|
||||
|
||||
Runner.validate = p18_validate
|
||||
|
||||
adapter_path = os.environ.get("OWNER_P22_FINALIZATION_ADAPTER")
|
||||
if adapter_path:
|
||||
import importlib.util
|
||||
approved_path = Path("/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/proposed_task_timeout_adapter.py")
|
||||
if Path(adapter_path).resolve() != approved_path.resolve():
|
||||
raise ValueError("Exact approved timeout adapter required")
|
||||
adapter_spec = importlib.util.spec_from_file_location("owner_p22_finalization_timeout", approved_path)
|
||||
adapter_module = importlib.util.module_from_spec(adapter_spec)
|
||||
adapter_spec.loader.exec_module(adapter_module)
|
||||
adapter_module.install(Runner)
|
||||
|
||||
from runner.cli import main
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"plan_id": "P08-02",
|
||||
"stage": "read-only audit started; contract not frozen; no worker registered",
|
||||
"current_main": "e4dc1ef",
|
||||
"original_work": "混合建設、占有変更、役者の実位置、救護・物流・EVをまとめて移行する。",
|
||||
"original_acceptance": "重複、孤立、消失がない。解消不能時は元配置とセーブを保つ。",
|
||||
"coverage_required": [
|
||||
"混合建設・占有変更を同じ移行batchで扱う",
|
||||
"役者実位置・救護患者/担当・物流荷物/予約・EV乗客/要求の保全",
|
||||
"重複なし",
|
||||
"孤立なし",
|
||||
"消失なし",
|
||||
"解消不能時に元配置とセーブを保持"
|
||||
],
|
||||
"commander_selection": "P08-02 (Opus selection preserved; its paraphrased work is not authoritative)",
|
||||
"evidence_reuse_candidates": [
|
||||
{
|
||||
"path": "artifacts/original-completion-2026-10-02/p03-current1299-inflight-dimension-actual-root-review-r01/review.json",
|
||||
"expected_sha": "5078abfb2653b454f4405e554997936927138bd81c56fc3fb564540a00693368",
|
||||
"actual_sha": "5078abfb2653b454f4405e554997936927138bd81c56fc3fb564540a00693368",
|
||||
"scope": "Current1299 unchanged; actual direct formal dimension migration with partial guest stairs and concurrent paid legacy job,152/0,4PID,303parse,17typed,5full states,12uncapped events,12formal; Operations OFF; no whole migration or OS acceptance",
|
||||
"not_automatically_p08_accepted": true
|
||||
},
|
||||
{
|
||||
"path": "artifacts/original-completion-2026-10-02/p03-current1299-inflight-EV-dimension-actual-root-review-r01/review.json",
|
||||
"expected_sha": "6ced37bc8af78ae35310ae6d8269767d197cdaec6c7444041a0c934ac2e50c8c",
|
||||
"actual_sha": "6ced37bc8af78ae35310ae6d8269767d197cdaec6c7444041a0c934ac2e50c8c",
|
||||
"scope": "Current1299 unchanged; actual occupied EV4 and waiting passenger1 plus concurrent paid legacy job formally migrated,177/0,4PID,303parse,17typed,5full states,34uncapped events,12formal; five original request arrivals exactly once; Operations OFF; changed destination/rescue/logistics/Main OS/whole migration pending",
|
||||
"not_automatically_p08_accepted": true
|
||||
},
|
||||
{
|
||||
"path": "artifacts/original-completion-2026-10-02/p03-current1299-EV-retarget-refusal-actual-root-review-r02/review.json",
|
||||
"expected_sha": "516c8f2a5fadc3b5345d3b802a1087fe7ca4d85f8d1f00e504f27a11f5d4be09",
|
||||
"actual_sha": "516c8f2a5fadc3b5345d3b802a1087fe7ca4d85f8d1f00e504f27a11f5d4be09",
|
||||
"scope": "Current1299 unchanged; actual boarded upper-entrance retarget refused twice,193/0,4PID,303parse,25typed,7whole states,6uncapped events,8formal original/real backup members and12proof members immutable; independent Zstd3; direct APIs/Operations OFF; no whole migration or OS acceptance",
|
||||
"not_automatically_p08_accepted": true
|
||||
},
|
||||
{
|
||||
"path": "artifacts/original-completion-2026-10-02/p03-current1299-rescue-dimension-actual-root-review-r02/review.json",
|
||||
"expected_sha": "5b4ad1372adda1cc830bbd455016c7c602cf26195221a6450db43cc8c5ddaeb4",
|
||||
"actual_sha": "5b4ad1372adda1cc830bbd455016c7c602cf26195221a6450db43cc8c5ddaeb4",
|
||||
"scope": "Current1299 unchanged; actual carried patient and rescuer plus concurrent paid legacy job,158/0,4PID,303parse,17typed,5full states,10uncapped events,12formal; same rescue task completes at unchanged clinic; controlled injury Operations OFF; changed rescue destination/logistics/Main OS/full migration pending",
|
||||
"not_automatically_p08_accepted": true
|
||||
},
|
||||
{
|
||||
"path": "artifacts/original-completion-2026-10-02/p03-current1299-logistics-dimension-actual-root-review-r01/review.json",
|
||||
"expected_sha": "91bc6e55aeee1462fbd31304d3d1c9ee0e537d8d3049ce9c4a4482829dfaa34c",
|
||||
"actual_sha": "91bc6e55aeee1462fbd31304d3d1c9ee0e537d8d3049ce9c4a4482829dfaa34c",
|
||||
"scope": "Current1299 unchanged; real bought8 food, normally hired worker, carried4/reserved4 and concurrent paid old-size job formally migrated;165/0,4PID,303parse,17typed,5full states,23uncapped events,12formal; same two shipments complete with conservation; actual supply destination unchanged, Operations OFF; no Main OS/full migration acceptance",
|
||||
"not_automatically_p08_accepted": true
|
||||
},
|
||||
{
|
||||
"path": "artifacts/original-completion-2026-10-02/p03-current1299-multiple-jobs-dimension-actual-root-review-r02/review.json",
|
||||
"expected_sha": "e3baa038eba0bbd16126fdbb5941057f17493c363659abd5b9f668e38bcccfc9",
|
||||
"actual_sha": "e3baa038eba0bbd16126fdbb5941057f17493c363659abd5b9f668e38bcccfc9",
|
||||
"scope": "Current1299 unchanged; two actual simultaneous paid legacy construction jobs formally batch migrated,158/0,4PID,303parse,17typed,5full states,4uncapped events,12formal; exact seven geometry changes only; independent Zstd3; two distinct current completed facilities; Operations OFF; no whole migration or OS acceptance",
|
||||
"not_automatically_p08_accepted": true
|
||||
},
|
||||
{
|
||||
"path": "artifacts/original-completion-2026-10-02/p03-current1299-batch-later-refusal-actual-root-review-r02/review.json",
|
||||
"expected_sha": "c3caf63ec20f584b4789beaa527da5ab77951d02a404479d3dab2834a48cd8db",
|
||||
"actual_sha": "c3caf63ec20f584b4789beaa527da5ab77951d02a404479d3dab2834a48cd8db",
|
||||
"scope": "Current1299 unchanged; later real dorm task rejects after first real job candidate changed; batch rollback twice;207/0,4PID,303parse,25typed,7whole states,5events,12proof members unchanged;3 independent Zstd; direct APIs Operations OFF",
|
||||
"not_automatically_p08_accepted": true
|
||||
}
|
||||
],
|
||||
"source_sha256": {
|
||||
"scenes/main/main.gd": "41df8857f9658c17b01361350979caa942b9326c82c9f176517972c2a9692f55",
|
||||
"scripts/core/save_migration_registry.gd": "22ac2cce07a02d1a2a9ac2109e7a0ecf9a0fbe675df4dc9d5249aa9ab3583f98",
|
||||
"tests/s1/test_dimension_batch_save.gd": "ca397c0457996bab637e8be5217b7db2c14579a1b0df54434b4000a69e793bbf",
|
||||
"tests/ui/test_dimension_migration_ui.gd": "0f0cec88ea8bf5fccdcd5ade02fab70b7dc71135132048cd10db17ad9d964c0d"
|
||||
},
|
||||
"remaining_conditions": [
|
||||
"既存7証拠の適用source/input/settings/environmentを現採用版へ照合。証拠ファイルSHA一致だけでは現在適用を認定しない。",
|
||||
"個別例を混合移行全体の受入へ置き換えない。混合batch・占有変更・全実位置/搬送参照の正例/拒否例を確認。",
|
||||
"通常メニューのpreview/取消/確認と拒否時の原保存保全の実証を確認。handler試験をOS入力済みにしない。",
|
||||
"必要な局所/影響範囲検証と、共有保存/配置コードを変更する場合だけ正確な最終版で全回帰。",
|
||||
"全条件の独立Opus受入と必要統合・台帳反映。"
|
||||
],
|
||||
"spec_policy": "D07関係値変換を推測せず、P08境界で含めない理由と拒否契約を確認。原30/88を維持。",
|
||||
"capacity_bytes_available_observation": "743MiB before approved P22 run; remeasure before allocation",
|
||||
"original_unit_completed": false
|
||||
}
|
||||
+1753
File diff suppressed because it is too large
Load Diff
+51
@@ -0,0 +1,51 @@
|
||||
[
|
||||
{
|
||||
"path": "autoload/simulation_runtime.gd",
|
||||
"function": "prepare_facility_dimension_snapshot",
|
||||
"old_body_sha": "525d227a3d02759d35c64ff885fabfc6c4e205c8f7e18ec02ab5af29c8809330",
|
||||
"current_body_sha": "525d227a3d02759d35c64ff885fabfc6c4e205c8f7e18ec02ab5af29c8809330",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"path": "autoload/simulation_runtime.gd",
|
||||
"function": "migrate_facility_dimensions_at_path",
|
||||
"old_body_sha": "41b6d554ad4fd92592366d022aac9aa7224b460bb7575e9cd63f1ab34c2a3371",
|
||||
"current_body_sha": "41b6d554ad4fd92592366d022aac9aa7224b460bb7575e9cd63f1ab34c2a3371",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"path": "autoload/simulation_runtime.gd",
|
||||
"function": "prepare_all_facility_dimension_snapshots",
|
||||
"old_body_sha": "01a03f2bb400084ff86cc1b802581fa97f9a7aa3b7e3de1d7d7932bb1b4ded10",
|
||||
"current_body_sha": "01a03f2bb400084ff86cc1b802581fa97f9a7aa3b7e3de1d7d7932bb1b4ded10",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"path": "autoload/simulation_runtime.gd",
|
||||
"function": "_prepare_construction_dimension_snapshot",
|
||||
"old_body_sha": "bb7a74ea8bf6fa298ec4155a165c283d27de35c34b6da5b322d2a4baadba85ca",
|
||||
"current_body_sha": "bb7a74ea8bf6fa298ec4155a165c283d27de35c34b6da5b322d2a4baadba85ca",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"path": "autoload/simulation_runtime.gd",
|
||||
"function": "preview_facility_dimensions_at_path",
|
||||
"old_body_sha": "5bfa3f770400761b6bcf399f398b9b72c2df049b7f8190f1f6ae1f80dfd393e3",
|
||||
"current_body_sha": "5bfa3f770400761b6bcf399f398b9b72c2df049b7f8190f1f6ae1f80dfd393e3",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"path": "scenes/main/main.gd",
|
||||
"function": "_preview_dimension_migration",
|
||||
"old_body_sha": "ae2aad38a6150074f04100da7f39eae2293f8f8c75cc4540ac6581abee62d88b",
|
||||
"current_body_sha": "ae2aad38a6150074f04100da7f39eae2293f8f8c75cc4540ac6581abee62d88b",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"path": "scenes/main/main.gd",
|
||||
"function": "_confirm_dimension_migration",
|
||||
"old_body_sha": "51171acd19626bd805cf9a620ad69616cc1e472c1ff77ba8f8bae949f8854ecc",
|
||||
"current_body_sha": "51171acd19626bd805cf9a620ad69616cc1e472c1ff77ba8f8bae949f8854ecc",
|
||||
"equal": true
|
||||
}
|
||||
]
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"action": "wait",
|
||||
"task_id": "P22-02",
|
||||
"reason": "【P22-02】blocked、repairs 3/3で上限に達しているため request-repair はできない。worker が止まった理由は能力不足ではなく、最終パケットの計測(500000未満)が worker からアクセスできない場所にあることだった。オーナーの指示どおり、この計測は Root だけが行う。合格した13テスト、AST、ordinary exit 0、require-ready exit 2 は保存されている。次の判断は、Root の正確な最終パケット計測と、オーナーによる扱いの決定を待つ。provider は起動しない。\n\n【新しい P08-02 登録への推奨(提案のみ。登録・承認・予算はオーナー判断)】\n原計画の条件6つ:\nC1 混合建設\nC2 占有変更\nC3 役者の実位置\nC4 救護・物流・EV を1つの batch でまとめて移行\nC5 重複・孤立・消失がない\nC6 解消できない場合は元の配置とセーブを保つ\n\n正例:これら全部を含む混合 fixture を1つ作り、現在の main を基準に OperationsON と OperationsOFF の両方で通す。restore、finance、save reconciliation、path batch は旧 stage と違うので、ON が当てはまる根拠は説明だけでなく収集で示す。OFF だけの個別ケースでは、まとめての主張の根拠にならない。\nC6:後半の batch を解消不能にして拒否させ、live、source、以前の backup の3つが byte/SHA で変わっていないことを確認する。\nPID をまたぐ継続:プロセスAで batch を保存して終了する。新しいプロファイルのプロセスBで読み込んで続行し、不変条件の digest が一致することを確認する。\n\n負例(validator が必ず reject するもの):\n- actor ID の重複\n- 占有しているのに建物も actor もいない(孤立)\n- 救護 job、物流品、EV セッションの消失\n- 後半 batch が失敗したあとの部分適用\n- backup の上書き、live save の変更\n- PID 継続 digest の不一致\n- OFF だけの証拠で全体を主張すること\n- 旧 stage の受入の流用(29ファイル差分)\n- signals だけの UI 試験を OS 証拠として数えること\n- 期待値を常に fail にするハードコードや、サンプルの mutation だけを受け入れる validator(いずれも無効)\n\n既存資産:test_dimension_batch_save と test_dimension_migration_ui は再利用し、作り直さない。\n\nallowed_paths の案:\n- docs/plans/original-completion-2026-10-02/execution/p08-02/**\n- 新しい fixture ディレクトリ1つ(上限あり。726MiB の空きを前提に CoW stage を使う)\n- 新しい test ファイル1つ\n- tools/check_p08_02_combined_migration.py\n- tools/run_all_tests.py への最小限の登録だけ\n\nRuntime の本体と Runner の権限は対象外。不変条件の欠陥が実際に示されたときだけ、範囲を絞った別タスクを提案する。\nNative の正式チェック:Root が host で収集し、標準 sandbox の --verify-only で allocated build receipt を読む。\n完了の扱い:worker はコードを書いたら、Root の OS/native 証拠を pending のまま submitted で返す。これは original accepted ではない。全体の回帰試験は最後の変更 batch の後に1回だけ行う。",
|
||||
"codex_model": "gpt-6-astra",
|
||||
"codex_model_reason": "P22-02 では今、worker を走らせる予定はない。この選択は、後で P08-02 を登録したときの worker 用。fixture と validator は条件6つ全部を1つの batch で一貫させる必要がある。具体的には、建設、占有、移動中の actor、救護、物流、EV に、解消できない後半 batch での原子的な拒否と、PID をまたぐ継続が加わる。さらに既存の guarded CoW/native protocol を変えずに組み込み、ON の適用性を収集で示し、偽の pass ができない正例と負例を設計しなければならない。不変条件の推論が難しく、失敗したときの再試行コストも高いので、時間と使用量が増えても Astra の品質を優先する。この選択は run、repair、上限変更、受入の免除をどれも許可しない。"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# P08-02 retained implementation condition matrix
|
||||
|
||||
Status: submitted for Root verification; original P08-02 acceptance remains pending.
|
||||
Frozen spec: `docs/spec/acceptance/P08-02.json`, stripped UTF-8 SHA-256
|
||||
`19f02bb7912a4d7354e565186f02366fc1d4dd698468d26142e8204fd14ebfb0`.
|
||||
The raw file has a trailing newline. The six rows are facets of one existing unit, not six units.
|
||||
|
||||
All rows use `tests/fixtures/p08-02/mixed_world.gd` through `writer.gd` and
|
||||
`reader.gd`, and the standalone `tests/s1/test_p08_combined_migration.gd`.
|
||||
Driver phases are `off-positive`, `off-refusal`, `on-positive`, `on-refusal`,
|
||||
each with `-writer` then `-reader`; import/parse precede them.
|
||||
|
||||
| Required condition | Retained fixture/test coverage | Driver phase | Checker rule (`tools/check_p08_migration_evidence.py`) | Negative mutation (`tools/test_p08_migration_evidence.py`) | Pending evidence |
|
||||
|---|---|---|---|---|---|
|
||||
| mixed_construction | `setup`: paid zero-progress old-size premium job, progressing premium job, completed dorm in the same save; `run`: full progress/payment/reservation/completion fields | All four pairs; positive applies batch, refusal continues old shape | `semantics` checks starting/progressing paid jobs, completed dorm and diagnostic budget; `case_gate` permits only explicit typed geometry deltas and requires four-cell positive jobs | `missing_start_stage`, `resource_delta_mismatch`, `partial_batch`; unapproved typed changes are compared without dropping fields | Native runtime/save and distinct-PID continuation; normal OS flow; Root final verification pending |
|
||||
| occupancy_change | `invariant`: restore validation of ownership/support; migrated occupied/reserved cells captured in whole snapshots | All four pairs | `semantics`: disjoint cells, exact construction/world ownership and operational facility cells; `GEOMETRY` finite allowlist | `orphan_occupancy` | Native added/released cells and support validation; OS model/formal records; Root review pending |
|
||||
| actual_actor_positions | Mid-route walker, fractional credit, real staff/rescue/cargo and EV positions; no route changes approved | All four pairs, checkpoint and minutes 001–160 | `typed_differences` forbids actor/credit/route/money deltas; full typed and raw Variant writer/reader equality | `duplicate_actor`, `unequal_cross_pid` | Native actual positions/credit/routes and cross-PID equality; OS state captures; Root review pending |
|
||||
| combined_rescue_logistics_ev | `setup`: actual in-flight rescue, purchased carried food with original requests, four EV boarded plus one waiting; `run`: patient treated, original cargo completed, each EV arrival once | All four pairs and uncapped events | `semantics`: IDs, endpoints, reservations and EV actors; `case_gate`: final patient health, original cargo completion and exactly one arrival per original EV request | `lost_patient`, `lost_cargo`, `lost_ev` | Native coherent same-save mixed state and continuation; OS save/model attribution; Root review pending |
|
||||
| no_overlap_orphan_loss | Whole typed snapshots/raw Variant files and uncapped events; runtime/cargo invariants | ON and OFF positive/refusal pairs | Ordered four-case roster, actual mode, distinct lifecycle PIDs, strict markers, all 162 labels compared, semantic ownership/reference checks | `duplicate_actor`, `orphan_occupancy`, `unequal_cross_pid`, `missing_on`, `missing_phase`, `duplicate_pid`, `wrong_source`, `stale_source` | Native ON/OFF and separate writer/reader PIDs; normal-menu OS proof; final regression and Root verification pending |
|
||||
| unsolvable_preservation | Real pre-existing migration backup, late maintenance obstruction at dorm, independently migratable first job; refusal rollback and unchanged live/formal/backup | `off-refusal`, `on-refusal` writer/reader | Live equality; original equals refusal checkpoint; before/after member hash maps equal; raw four-member original/result/backup hashes bound | `partial_batch`, `overwritten_original`, `overwritten_backup` | Native late refusal and separate-PID original continuation; OS cancel/changed-source preservation; Root review pending |
|
||||
|
||||
The standalone suite executes both roles in one process and does not establish distinct-PID proof.
|
||||
Only the Root collector launches separate phases through existing `execute_phase`/owned-outer
|
||||
and fresh guarded profiles. Exactly one public suite marker exists:
|
||||
`P08 combined migration: <checks> checks, <failures> failures`.
|
||||
The driver privately owns the writer/reader marker templates; no second public entry is added.
|
||||
|
||||
Local Python tests are synthetic checker fixtures, including synthetic lifecycle/OS/regression
|
||||
records; their success establishes checker reachability and rejection tests only.
|
||||
Native Godot/OS execution, normal production menu preview/cancel/confirm/changed-source rejection,
|
||||
final full regression, final submitted reviewer-packet measurement, applicable Windows coverage,
|
||||
independent Opus review, integration/current verification and ledger closure remain Root conditions.
|
||||
Controlled old-save setup must be labelled controlled, never natural production.
|
||||
Checker integrity success cannot close the original unit. No production defect or product fix
|
||||
was demonstrated by the authorized local checks; retained code and marker contract are reused.
|
||||
|
||||
Repair r04: seed 42588; existing definition-derived construction total gold 7110 /
|
||||
materials 88, signing 150, food eight units 24. Initial gold 5000 / materials 50
|
||||
and previous added resources zero leave a deficit of gold 2284 / materials 38.
|
||||
The controlled fixture records and supplies only this derived deficit.
|
||||
Historical full metadata is now referenced by
|
||||
`implementation-historical-6c7c724.json`: both fixed Git versions were SHA-verified
|
||||
before replacement. Root's verified gzip roundtrip SHA is provenance only;
|
||||
no external archive is a checker/runtime dependency. Historical failure logs remain preserved.
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
{
|
||||
"classification": "Root coordinator supplied repair input, not worker implementation or acceptance proof",
|
||||
"measured_UIDs": {
|
||||
"tests/fixtures/p08-02/mixed_world.gd.uid": {
|
||||
"text": "uid://dg5n4yme6rk4p\n",
|
||||
"raw_sha256": "d7549f933b74f5e807cd2d3b3adcdd083af4a3bd331614314ff7bfd7b0903f31"
|
||||
},
|
||||
"tests/fixtures/p08-02/reader.gd.uid": {
|
||||
"text": "uid://741t47oxl3ct\n",
|
||||
"raw_sha256": "3e68ce192d5770e3823df9699c5c99ebb618fe0a480b4d56913624941900b08a"
|
||||
},
|
||||
"tests/fixtures/p08-02/writer.gd.uid": {
|
||||
"text": "uid://csw2850g6gjct\n",
|
||||
"raw_sha256": "8f150654767de0c66329d7d9e84d306c4fa5a65c918e04fb520b626b39f68334"
|
||||
}
|
||||
},
|
||||
"replacement_example": {
|
||||
"classification": "Synthetic machine-readable complete index from retained Proof; diagnostic ONLY, never native/OS/regression acceptance evidence.",
|
||||
"construction": "tools/test_p08_migration_evidence.py Proof creates all linked bytes and reachable whole-check positive. Embedded documents illustrate receipts/lifecycle/OS/regression/typed records. Digests belong to the disposable synthetic fixture, not delivered acceptance artifacts; reproduce with Proof in a worktree-local disposable directory.",
|
||||
"complete_example_generator": {
|
||||
"source": "tools/test_p08_migration_evidence.py",
|
||||
"source_raw_sha256": "9924f4cb4f55b15caf9f9733d91f5095553abcf2861e4b335755531480b534a9",
|
||||
"class": "Proof",
|
||||
"constructor": "Proof(Path(fresh_temporary_directory))",
|
||||
"project_root_binding": "module ROOT resolved from unchanged generator inside this exact candidate source tree",
|
||||
"generated_full_index": "proof.index",
|
||||
"generated_representative_documents": "{path: json.loads((proof.path / path).read_text()) for path in representative_artifact_document_paths}",
|
||||
"native_or_os_runs": 0
|
||||
},
|
||||
"index_top_level_fields": [
|
||||
"schema",
|
||||
"commit",
|
||||
"source_map",
|
||||
"spec_sha256",
|
||||
"marker_contract_sha256",
|
||||
"inputs",
|
||||
"cases",
|
||||
"conditions",
|
||||
"artifacts",
|
||||
"acceptance",
|
||||
"collection_error",
|
||||
"phases",
|
||||
"os_proof",
|
||||
"regression"
|
||||
],
|
||||
"representative_artifact_document_paths": [
|
||||
"runs/off-positive-writer/off-positive-writer-receipt.json",
|
||||
"runs/off-positive-reader/off-positive-reader-receipt.json",
|
||||
"runs/off-positive-writer/off-positive-writer/started.json",
|
||||
"runs/off-positive-writer/off-positive-writer/ended.json",
|
||||
"runs/off-positive-writer/off-positive-writer/outer-owned-finally.json",
|
||||
"os.json",
|
||||
"os/preview/input.json",
|
||||
"regression.json",
|
||||
"regression/input.json",
|
||||
"regression/ended.json",
|
||||
"pairs/off-positive/identity.json",
|
||||
"pairs/off-positive/writer-process.json",
|
||||
"pairs/off-positive/before-members.json"
|
||||
],
|
||||
"fixture_config_inputs": {
|
||||
"fixture_sources": {
|
||||
"tests/s1/test_p08_combined_migration.gd": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855",
|
||||
"tests/s1/test_p08_combined_migration.gd.uid": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5",
|
||||
"tests/fixtures/p08-02/README.md": "bc76975e49e7761c2a3540a1e907ab2215ec315653a1d87df6919d1cebd779e0",
|
||||
"tests/fixtures/p08-02/mixed_world.gd": "889bc895888b8c6ad50659a3b23a3ee45e9edf8dde9168f5560792c292070d26",
|
||||
"tests/fixtures/p08-02/reader.gd": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be",
|
||||
"tests/fixtures/p08-02/writer.gd": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260",
|
||||
"tools/run_p08_mixed_migration.py": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579",
|
||||
"tools/check_p08_migration_evidence.py": "8d697c8e9a606bcff6a0a8c6ec55e0e9c434ca9682b7ce6915b5bcb1ea4ff3fd",
|
||||
"tools/test_p08_migration_evidence.py": "9924f4cb4f55b15caf9f9733d91f5095553abcf2861e4b335755531480b534a9"
|
||||
},
|
||||
"native_runner_input_shape": {
|
||||
"protocol": "p08-mixed-v1",
|
||||
"commit": "<actual final commit>",
|
||||
"selected_source_map": "<exact source map>",
|
||||
"engine": "<actual executable>",
|
||||
"engine_sha256": "<raw SHA>",
|
||||
"owner_pid": "<actual collector PID>",
|
||||
"default_player": "<protected profile record>",
|
||||
"diagnostic_seed": 42588
|
||||
},
|
||||
"case_environment": {
|
||||
"P08_PAIR_ROOT": "<absolute guarded pair output>",
|
||||
"P08_OPERATIONS": "off|on",
|
||||
"P08_CASE": "positive|refusal"
|
||||
},
|
||||
"timeouts": "unchanged: collection 900s, phase maximum 180s",
|
||||
"formal_validation": "Root copies actual evidence into allocated build directory; --verify-only reads BUILD_OUTPUT_DIR/p08-evidence/index.json"
|
||||
},
|
||||
"exact_reconstruction_verification": {
|
||||
"entire_index_equal": true,
|
||||
"entire_representative_documents_equal": true,
|
||||
"index_canonical_sha256": "456c67833dc6d6d905a1c0543f7a3e6b1ead715b8e88a5fe816dbcb77072efc0",
|
||||
"representative_canonical_sha256": "5727797a0ec11363d1463406be4f1979e279a9c77fff02c284ff7fff60bc32e6",
|
||||
"canonical_encoding": "json.dumps(value,sort_keys=True,ensure_ascii=False).encode()"
|
||||
},
|
||||
"purpose": "Lossless complete synthetic example regeneration from retained code, not a real native/OS acceptance index. Explicit index_schema above remains authoritative. Root proved equality of all original fields before this proposal. Full prior implementation preserved in commit6c7c7244 and byte-verified gzip evidence."
|
||||
},
|
||||
"instructions": "Read this compact input first. Do not cat the entire 1MB old example into model context. Parse implementation.json with stdlib, replace example field, keep all other fields/schema/source logic. Add exact supplied UIDs; update outputs; after source map changes recompute current synthetic example digests with unchanged Proof class. Historical exact old reconstruction remains tied to6c. This input is within allowed scope, not an external path."
|
||||
}
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
{
|
||||
"purpose": "Same retained candidate; diagnose checker against real native outputs. Original native bytes and candidate preserved; not game acceptance.",
|
||||
"actual_candidate": "592809bfdaf6a1bbc5ec9cbaeff71a7bb072add9",
|
||||
"all8_native_phases_pass": true,
|
||||
"defects": [
|
||||
"actual Vector3i constructor scalar format rejected by decoder",
|
||||
"logistics lazy destination inventory treated as orphan although canonical live facility exists",
|
||||
"RESERVED queued request has no assigned carrier by domain contract",
|
||||
"support revision is global world revision epoch, not independent +1 counter; actual changed142→150 alongside world144→150 after occupancy rewrites"
|
||||
],
|
||||
"actual_readonly_diagnostics": {
|
||||
"ACTUAL_NATIVE_CHECKER.json": {
|
||||
"candidate": "592809bfdaf6a1bbc5ec9cbaeff71a7bb072add9",
|
||||
"elapsed_seconds": 16.212463750038296,
|
||||
"actual_readonly_checker_deficits": [
|
||||
"OS proof: unsafe artifact path",
|
||||
"case off-positive: invalid literal for int() with base 10: 'Vector3i(0'",
|
||||
"case off-refusal: invalid literal for int() with base 10: 'Vector3i(0'",
|
||||
"case on-positive: invalid literal for int() with base 10: 'Vector3i(6'",
|
||||
"case on-refusal: invalid literal for int() with base 10: 'Vector3i(-12'",
|
||||
"final regression: unsafe artifact path"
|
||||
],
|
||||
"full_game_acceptance": false,
|
||||
"original_unit_completed": false,
|
||||
"index": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p08-02-native-mixed-r05/index.json"
|
||||
},
|
||||
"VECTOR_DECODER_READONLY_DIAGNOSTIC.json": {
|
||||
"candidate": "592809bfdaf6a1bbc5ec9cbaeff71a7bb072add9",
|
||||
"scope": "Root readonly decoder prototype diagnostic; no candidate code or actual evidence altered; no acceptance",
|
||||
"observations": [
|
||||
{
|
||||
"case": "off-positive",
|
||||
"jobs": [
|
||||
{
|
||||
"id": "construction_00000015",
|
||||
"state": "BUILDING",
|
||||
"progress": 1266
|
||||
},
|
||||
{
|
||||
"id": "construction_00000016",
|
||||
"state": "PLANNED",
|
||||
"progress": 0
|
||||
}
|
||||
],
|
||||
"starting_job": "construction_00000016"
|
||||
},
|
||||
{
|
||||
"case": "off-refusal",
|
||||
"jobs": [
|
||||
{
|
||||
"id": "construction_00000015",
|
||||
"state": "BUILDING",
|
||||
"progress": 1266
|
||||
},
|
||||
{
|
||||
"id": "construction_00000016",
|
||||
"state": "PLANNED",
|
||||
"progress": 0
|
||||
}
|
||||
],
|
||||
"starting_job": "construction_00000016"
|
||||
},
|
||||
{
|
||||
"case": "on-positive",
|
||||
"jobs": [
|
||||
{
|
||||
"id": "construction_00000015",
|
||||
"state": "BUILDING",
|
||||
"progress": 1266
|
||||
},
|
||||
{
|
||||
"id": "construction_00000016",
|
||||
"state": "PLANNED",
|
||||
"progress": 0
|
||||
}
|
||||
],
|
||||
"starting_job": "construction_00000016"
|
||||
},
|
||||
{
|
||||
"case": "on-refusal",
|
||||
"jobs": [
|
||||
{
|
||||
"id": "construction_00000015",
|
||||
"state": "BUILDING",
|
||||
"progress": 1266
|
||||
},
|
||||
{
|
||||
"id": "construction_00000016",
|
||||
"state": "PLANNED",
|
||||
"progress": 0
|
||||
}
|
||||
],
|
||||
"starting_job": "construction_00000016"
|
||||
}
|
||||
],
|
||||
"remaining_deficits": [
|
||||
"OS proof: unsafe artifact path",
|
||||
"case off-positive: orphan cargo endpoint",
|
||||
"case off-refusal: orphan cargo endpoint",
|
||||
"case on-positive: orphan cargo endpoint",
|
||||
"case on-refusal: orphan cargo endpoint",
|
||||
"final regression: unsafe artifact path"
|
||||
],
|
||||
"elapsed_seconds": 16.21374141704291
|
||||
},
|
||||
"CARGO_ENDPOINT_READONLY_DIAGNOSTIC.json": [
|
||||
{
|
||||
"first_label": "original",
|
||||
"original_requests": [
|
||||
"supply.logistics_request.000000000001",
|
||||
"supply.logistics_request.000000000002"
|
||||
],
|
||||
"active_inventory_ids": [
|
||||
"cargo:staff_gina",
|
||||
"facility.inventory:facility_00000005"
|
||||
],
|
||||
"requests": [
|
||||
{
|
||||
"request_id": "supply.logistics_request.000000000001",
|
||||
"source_inventory_id": "facility.inventory:facility_00000005",
|
||||
"destination_inventory_id": "facility.inventory:facility_00000006",
|
||||
"item_requirements": {
|
||||
"ingredient/raw_food": 4
|
||||
},
|
||||
"priority": 50,
|
||||
"created_at": 728,
|
||||
"deadline": -1,
|
||||
"total_weight": 4,
|
||||
"reserved_stack_ids": [
|
||||
"stack_00000001"
|
||||
],
|
||||
"reservation_ids": [
|
||||
"reservation_00000001"
|
||||
],
|
||||
"assigned_carrier_id": "staff_gina",
|
||||
"state": "DELIVERING",
|
||||
"retry_count": 0,
|
||||
"state_reason": "",
|
||||
"state_changed_at": 735
|
||||
},
|
||||
{
|
||||
"request_id": "supply.logistics_request.000000000002",
|
||||
"source_inventory_id": "facility.inventory:facility_00000005",
|
||||
"destination_inventory_id": "facility.inventory:facility_00000006",
|
||||
"item_requirements": {
|
||||
"ingredient/raw_food": 4
|
||||
},
|
||||
"priority": 50,
|
||||
"created_at": 729,
|
||||
"deadline": -1,
|
||||
"total_weight": 4,
|
||||
"reserved_stack_ids": [
|
||||
"stack_00000001"
|
||||
],
|
||||
"reservation_ids": [
|
||||
"reservation_00000002"
|
||||
],
|
||||
"assigned_carrier_id": "",
|
||||
"state": "RESERVED",
|
||||
"retry_count": 0,
|
||||
"state_reason": "NO_AVAILABLE_PORTER_OR_ROUTE",
|
||||
"state_changed_at": 729
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"CARGO_RULE_READONLY_DIAGNOSTIC.json": {
|
||||
"candidate": "592809bfdaf6a1bbc5ec9cbaeff71a7bb072add9",
|
||||
"scope": "Root readonly prototype only. Candidate/checker/evidence files unchanged, no formal acceptance.",
|
||||
"basis": "Authoritative SupplyLogisticsBridge.validate_crosslinks lines508-554 resolves facility inventory endpoints by facility ownership and allows unassigned RESERVED request with valid reservation; destination inventory materializes upon delivery.",
|
||||
"remaining_deficits": [
|
||||
"OS proof: unsafe artifact path",
|
||||
"final regression: unsafe artifact path",
|
||||
"unapproved typed migration delta off-positive/systems/runtime/world/revisions/support",
|
||||
"unapproved typed migration delta on-positive/systems/runtime/world/revisions/support"
|
||||
],
|
||||
"elapsed_seconds": 78.40071395831183
|
||||
},
|
||||
"ACTUAL_WORLD_REVISION_DELTAS.json": [
|
||||
{
|
||||
"case": "off-positive",
|
||||
"original_world_revisions": {
|
||||
"world": 144,
|
||||
"occupancy": 144,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 142
|
||||
},
|
||||
"checkpoint_world_revisions": {
|
||||
"world": 150,
|
||||
"occupancy": 150,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 150
|
||||
}
|
||||
},
|
||||
{
|
||||
"case": "on-positive",
|
||||
"original_world_revisions": {
|
||||
"world": 144,
|
||||
"occupancy": 144,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 142
|
||||
},
|
||||
"checkpoint_world_revisions": {
|
||||
"world": 150,
|
||||
"occupancy": 150,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 150
|
||||
}
|
||||
},
|
||||
{
|
||||
"case": "off-refusal",
|
||||
"original_world_revisions": {
|
||||
"world": 144,
|
||||
"occupancy": 144,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 142
|
||||
},
|
||||
"checkpoint_world_revisions": {
|
||||
"world": 144,
|
||||
"occupancy": 144,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 142
|
||||
}
|
||||
},
|
||||
{
|
||||
"case": "on-refusal",
|
||||
"original_world_revisions": {
|
||||
"world": 144,
|
||||
"occupancy": 144,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 142
|
||||
},
|
||||
"checkpoint_world_revisions": {
|
||||
"world": 144,
|
||||
"occupancy": 144,
|
||||
"walkability": 99,
|
||||
"excavation": 0,
|
||||
"support": 142
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"source_basis": {
|
||||
"scripts/supply/supply_logistics_bridge.gd:508": [
|
||||
"static func validate_crosslinks(requests: Dictionary, staff: StaffService, inventory: InventoryService, facilities: FacilityService) -> bool:",
|
||||
"\tvar carrier_owners: Dictionary = {}",
|
||||
"\tvar active_task_ids: Dictionary = {}",
|
||||
"\tfor id: StringName in _request_ids(requests):",
|
||||
"\t\tvar request: LogisticsRequest = requests[id]",
|
||||
"\t\tvar source := _facility_for_inventory(facilities, request.source_inventory_id)",
|
||||
"\t\tvar destination := _facility_for_inventory(facilities, request.destination_inventory_id)",
|
||||
"\t\tif not String(request.source_inventory_id).begins_with(\"facility.inventory:\") or not String(request.destination_inventory_id).begins_with(\"facility.inventory:\"):",
|
||||
"\t\t\treturn false",
|
||||
"\t\tif not request.is_terminal() and (source == null or destination == null):",
|
||||
"\t\t\treturn false",
|
||||
"\t\tvar task := _active_task(staff, id)",
|
||||
"\t\tif request.state in [LogisticsRequest.State.RESERVED, LogisticsRequest.State.BLOCKED] or request.is_terminal():",
|
||||
"\t\t\tif task != null:",
|
||||
"\t\t\t\treturn false",
|
||||
"\t\t\tif request.state == LogisticsRequest.State.RESERVED and not _reservation_quantities_valid(request, inventory, true):",
|
||||
"\t\t\t\treturn false",
|
||||
"\t\t\tcontinue",
|
||||
"\t\tif request.state not in [LogisticsRequest.State.ASSIGNED, LogisticsRequest.State.PICKING_UP, LogisticsRequest.State.DELIVERING]:",
|
||||
"\t\t\treturn false",
|
||||
"\t\tvar worker := staff.get_staff(request.assigned_carrier_id)",
|
||||
"\t\tif worker == null or worker.role_id != &\"porter\" or carrier_owners.has(worker.staff_id) \\",
|
||||
"\t\t\tor task == null or task.assigned_staff_id != worker.staff_id or worker.current_task_id != task.task_id \\"
|
||||
],
|
||||
"scripts/world/world_service.gd:652": [
|
||||
"func _mark_dirty(",
|
||||
"\tcells: Array,",
|
||||
"\toccupancy_changed: bool,",
|
||||
"\twalkability_changed: bool,",
|
||||
"\texcavation_changed: bool,",
|
||||
"\tsupport_changed: bool",
|
||||
") -> void:",
|
||||
"\trevision += 1",
|
||||
"\tif occupancy_changed:",
|
||||
"\t\toccupancy_revision = revision",
|
||||
"\tif walkability_changed:",
|
||||
"\t\twalkability_revision = revision",
|
||||
"\tif excavation_changed:",
|
||||
"\t\texcavation_revision = revision",
|
||||
"\tif support_changed:",
|
||||
"\t\tsupport_revision = revision",
|
||||
"\tfor cell: Variant in cells:",
|
||||
"\t\tif cell is Vector3i and is_in_bounds(cell):",
|
||||
"\t\t\t_dirty_cells[cell] = true"
|
||||
]
|
||||
},
|
||||
"instructions": [
|
||||
"Read only this compact file first; no broad history or full evidence dump.",
|
||||
"Do not modify fixture/runtime/collector/native semantics already passed. Fix checker decoding/crosslink/counter checks, realistic targeted tests and metadata together. Original6conditions and30/88 unchanged.",
|
||||
"Native bytes must stay immutable. Decide whether tested runtime inputs exactly match final after tooling-only changes; do not silently re-label old tested SHA. If final validator requires exact full source-map, execute final native once after all tooling fixes consolidated.",
|
||||
"Freeze all source edits before running checker tests; prior README mutation during tests caused preventable stale proof retry.",
|
||||
"Root external native collector should check first-writer actual scalar/crosslink semantics before running all other phases to avoid repeated whole collection.",
|
||||
"Independent review and OS/final regression remain mandatory."
|
||||
]
|
||||
}
|
||||
+341
File diff suppressed because one or more lines are too long
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"classification": "Historical full record preserved; compact provenance reference",
|
||||
"original_raw_sha256": "ab1fcf46ef73f2157f16f69394b4039a562c031fae8d407adca013a452226e2f",
|
||||
"original_raw_bytes": 1082602,
|
||||
"git_reference": {
|
||||
"commit": "6c7c724410c350afe3d49fa8ec52defe20e78041",
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation.json"
|
||||
},
|
||||
"second_full_copy_git_reference": {
|
||||
"commit": "e59206b9b2578ddb4a1ec023f836d413a7a8fbfb",
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation-historical-6c7c724.json"
|
||||
},
|
||||
"root_lossless_archive": "artifacts/original-completion-2026-10-02/p08-02-preserved-r01/full-submitted-implementation.json.gz",
|
||||
"raw_archive_roundtrip_verified": true,
|
||||
"current_acceptance_claimed": false
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
{
|
||||
"task_id": "P08-02",
|
||||
"status": "submitted",
|
||||
"acceptance": "pending",
|
||||
"base_commit": "e196578c1a4ad2fdf84642565bd102e524be386f",
|
||||
"spec_sha256_stripped_utf8": "19f02bb7912a4d7354e565186f02366fc1d4dd698468d26142e8204fd14ebfb0",
|
||||
"spec_sha256_raw": "01b3600e8815b514ffd5c4d341d77a6a3e8341064796c1dae706062b746ba6aa",
|
||||
"scope": "Metadata-only synchronization against Git 1545bd42; no code, fixture, runtime, marker or acceptance changes.",
|
||||
"outputs": [
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json",
|
||||
"sha256": "c4c6dbea08a92682c692a280dbc90702ccbe63702a4f2624519b18d42930e18f",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/s1/test_p08_combined_migration.gd",
|
||||
"sha256": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/s1/test_p08_combined_migration.gd.uid",
|
||||
"sha256": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/fixtures/p08-02/README.md",
|
||||
"sha256": "e88ca33fdb4e96602d1fb108d71a9c35b6fa054619ecf6f1396e9a6c5e0ebd98",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/fixtures/p08-02/mixed_world.gd",
|
||||
"sha256": "a23f8a686be1d77e4874b9956eef89be4756f6e5eb01cc62454c3845acc62c25",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/fixtures/p08-02/reader.gd",
|
||||
"sha256": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/fixtures/p08-02/writer.gd",
|
||||
"sha256": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tools/run_p08_mixed_migration.py",
|
||||
"sha256": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tools/check_p08_migration_evidence.py",
|
||||
"sha256": "928353233bf85436a5aaf8c4f77f3f82472d94b8ad2646cb1b030baf92b3b5dc",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tools/test_p08_migration_evidence.py",
|
||||
"sha256": "fd9ef7ec63f53dfd5e04e261606c9303d01a2e6590e22a35fef2e35df1429280",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/CONDITION_MATRIX.md",
|
||||
"sha256": "6673051df9ae10f2df9b1812828e71ad9f5f24c433572defeef4e0978962a4e8",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation.json",
|
||||
"sha256": "fee85e6f4bb2824fc64bdfa275302f503a3234d83ab6c473c5e3ae6fdf91a3a6",
|
||||
"hash_scope": "canonical normalized self record: replace this sha256 with null, UTF-8 json.dumps(ensure_ascii=False,sort_keys=True,separators=(comma,colon)), no newline",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/fixtures/p08-02/mixed_world.gd.uid",
|
||||
"sha256": "d7549f933b74f5e807cd2d3b3adcdd083af4a3bd331614314ff7bfd7b0903f31",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/fixtures/p08-02/reader.gd.uid",
|
||||
"sha256": "3e68ce192d5770e3823df9699c5c99ebb618fe0a480b4d56913624941900b08a",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "r04 current source; retained paths and UID/marker entries"
|
||||
},
|
||||
{
|
||||
"path": "tests/fixtures/p08-02/writer.gd.uid",
|
||||
"sha256": "8f150654767de0c66329d7d9e84d306c4fa5a65c918e04fb520b626b39f68334",
|
||||
"hash_scope": "raw bytes",
|
||||
"disposition": "retained unchanged UID"
|
||||
}
|
||||
],
|
||||
"self_hash_note": "A raw self-containing SHA cannot be embedded in itself. This explicit normalized hash covers implementation.json; Root must separately measure its raw SHA and the final full packet on actual submitted SHA. No final packet measurement claimed.",
|
||||
"commands_actually_run": [
|
||||
{
|
||||
"command": "python3 -B AST parse of three P08 Python tools",
|
||||
"exit_code": 0,
|
||||
"result": "3 parses passed"
|
||||
},
|
||||
{
|
||||
"command": "python3 -B tools/test_p08_migration_evidence.py (first run)",
|
||||
"exit_code": 1,
|
||||
"result": "2 tests; positive stale source map because worker changed README during test"
|
||||
},
|
||||
{
|
||||
"command": "python3 -B tools/test_p08_migration_evidence.py (stable-source rerun)",
|
||||
"exit_code": 0,
|
||||
"result": "2 tests in 33.523s, OK; synthetic only",
|
||||
"classification": "Historical worker run; superseded as current local-check metadata, preserved without relabeling."
|
||||
},
|
||||
{
|
||||
"command": "python3 -B tools/test_p08_migration_evidence.py (Repair 7, final frozen sources)",
|
||||
"exit_code": 0,
|
||||
"result": "4 tests in 55.197s, OK; synthetic only"
|
||||
}
|
||||
],
|
||||
"local_checks": {
|
||||
"ast_parse": "passed, three Python sources",
|
||||
"checker_tests": {
|
||||
"command": "python3 -B tools/test_p08_migration_evidence.py",
|
||||
"tests_run": 4,
|
||||
"elapsed_seconds": 55.197,
|
||||
"result": "OK",
|
||||
"exit_code": 0,
|
||||
"scope": "Synthetic local checker tests only; source edits frozen before this single run. Not native, OS, full regression or acceptance evidence.",
|
||||
"final_raw_sha256": {
|
||||
"tools/test_p08_migration_evidence.py": "fd9ef7ec63f53dfd5e04e261606c9303d01a2e6590e22a35fef2e35df1429280",
|
||||
"tools/check_p08_migration_evidence.py": "928353233bf85436a5aaf8c4f77f3f82472d94b8ad2646cb1b030baf92b3b5dc",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-02/ROOT_REPAIR_INPUT-r04.json": "23ef44a0775ca53f1f67d6d64fcc96cd33eae935478768e9ce9431796eaa12ef"
|
||||
}
|
||||
},
|
||||
"native_or_full_regression_run": false,
|
||||
"evidence_reuse_pending": "Reuse of earlier native 8, OS and final 174 regression evidence is pending Root confirmation of exact source_map, input, config and environment matches. If restored r04 is in the selected source map, Root must decide whether to re-collect. Independent review and integration remain pending; no unconfirmed evidence counts asserted."
|
||||
},
|
||||
"pending_root_conditions": [
|
||||
"mixed_construction",
|
||||
"occupancy_change",
|
||||
"actual_actor_positions",
|
||||
"combined_rescue_logistics_ev",
|
||||
"no_overlap_orphan_loss",
|
||||
"unsolvable_preservation",
|
||||
"native_Godot_and_OS_execution",
|
||||
"separate_PID_writer_reader",
|
||||
"normal_menu_OS_proof",
|
||||
"final_full_regression",
|
||||
"final_submitted_packet_measurement",
|
||||
"applicable_Windows_coverage",
|
||||
"independent_Opus_review",
|
||||
"main_integration_current_final_verification",
|
||||
"ledger_reflection_and_original_unit_closure"
|
||||
],
|
||||
"product_fix_proposal": null,
|
||||
"index_schema": {
|
||||
"name": "p08-evidence-v1",
|
||||
"location": "BUILD_OUTPUT_DIR/p08-evidence/index.json",
|
||||
"authority": "tools/check_p08_migration_evidence.py check() and tools/run_p08_mixed_migration.py collect()",
|
||||
"top_level": {
|
||||
"schema": "literal p08-evidence-v1",
|
||||
"commit": "40 lowercase hex actual submitted commit; collector checks HEAD",
|
||||
"source_map": "exact runner.source_refs(root) path -> raw SHA-256 including fixture/suite/tool sources",
|
||||
"inputs": "exact frozen docs/spec/inputs/p08-02 immediate file path -> raw SHA-256",
|
||||
"spec_sha256": "stripped UTF-8 frozen spec SHA",
|
||||
"marker_contract_sha256": "raw marker contract SHA",
|
||||
"cases": "ordered off-positive, off-refusal, on-positive, on-refusal",
|
||||
"phases": "collector import/parse and case receipt paths",
|
||||
"conditions": "all six IDs -> all four cases, except unsolvable_preservation -> both refusal cases",
|
||||
"artifacts": "relative path -> {bytes: integer, sha256: raw digest}; no absolute/traversal/symlink; index itself excluded",
|
||||
"os_proof": "relative OS proof JSON path; initially null in collector",
|
||||
"regression": "relative final regression proof JSON path; initially null in collector",
|
||||
"acceptance": "literal pending, including after integrity verification",
|
||||
"collection_error": "null for integrity gate"
|
||||
},
|
||||
"case": {
|
||||
"id": "operations-kind",
|
||||
"operations": "off|on",
|
||||
"kind": "positive|refusal",
|
||||
"directory": "relative pair directory",
|
||||
"phases": "writer then reader receipt paths (two)",
|
||||
"files": "collector inventory path -> bytes/sha256; checker artifacts is content authority"
|
||||
},
|
||||
"phase_receipt": "actual_pid unique positive integer; phase, command argv, test, source_sha256, log relative to receipt parent; exit_code=0, engine_ended=true; native_process exit_code/helper_exit_code=0,timed_out=false,lifecycle_error=null; actual_private_profile.report fresh_before_parent_initialize=true,profile_writes_before_guard=0,actual_user_data_dir=expected_user_data_dir",
|
||||
"raw_native_lifecycle": "receipt parent/phase/{started.json,ended.json,outer-owned-finally.json}. Start/end actual_pid and command match receipt. Start live_identity_exact or tracked_child_ended_before_initial_probe. End exit_code=0,engine_ended=true. Outer actual_captured_pids=[actual_pid],all_captured_ended=true,no cleanup errors or foreign signals. Raw version/argv/lifecycle must be actual Root capture.",
|
||||
"strict_logs": "receipt parent/log: native version banner and exact role completion template, current source_sha256; full regression checks existing strict contracts for every current roster suite",
|
||||
"typed_state": "Every .var raw Variant has .json typed tree: Dictionary entries=[typed key,typed value], Array items plus element_type/element_class, scalar type and exact var_to_str text. Required identity,original,after-live,before-members,after-members,writer/reader-process,writer/reader-checkpoint,writer/reader-minute-001 through 160,writer/reader-events. Preserve all fields and uncapped events. Driver also retains first-candidate,preview,migration diagnostics.",
|
||||
"formal_members": "original/result/backup formal/{world.bin,manifest.json,thumbnail.png,journal.log}; raw artifact hashes bound to before/after typed member maps. Refusal preserves full original and pre-existing backup.",
|
||||
"normal_OS_proof": "commit and exact source_map; input_method=native_os,setup=controlled_old_save; ordered preview,cancel,confirm,changed_source_rejection. Each action links input_receipt (method=native_os,event_type mouse|keyboard,target_pid positive int,timestamp_ns positive),screen_before/after,model_before/after,formal_before/after. Non-confirm formal JSON maps equal. Root independently assesses actual OS input/screens/state; signal-emitted UI is handler evidence only.",
|
||||
"final_regression": "commit,directory,input,ended artifact paths. Input selected_source_map exact and roster runner.roster(root). Ended error null,cleanup_errors/guard_errors empty,ordered phases full roster each strict raw log,exit_code=0,engine_ended=true.",
|
||||
"limits": "This documents implemented gates, not an acceptance reducer. Import/parse and config/environment runner-input are retained and hashed by driver; checker explicitly gates case phases. Root independently checks native version/config/environment, normal OS behavior and original conditions. Synthetic metadata cannot prove actual execution."
|
||||
},
|
||||
"example": {
|
||||
"classification": "Synthetic machine-readable complete index from retained Proof; diagnostic ONLY, never native/OS/regression acceptance evidence.",
|
||||
"construction": "tools/test_p08_migration_evidence.py Proof creates all linked bytes and reachable whole-check positive. Embedded documents illustrate receipts/lifecycle/OS/regression/typed records. Digests belong to the disposable synthetic fixture, not delivered acceptance artifacts; reproduce with Proof in a worktree-local disposable directory.",
|
||||
"complete_example_generator": {
|
||||
"source": "tools/test_p08_migration_evidence.py",
|
||||
"source_raw_sha256": "fd9ef7ec63f53dfd5e04e261606c9303d01a2e6590e22a35fef2e35df1429280",
|
||||
"class": "Proof",
|
||||
"constructor": "Proof(Path(fresh_temporary_directory))",
|
||||
"project_root_binding": "module ROOT resolved from unchanged generator inside this exact candidate source tree",
|
||||
"generated_full_index": "proof.index",
|
||||
"generated_representative_documents": "{path: json.loads((proof.path / path).read_text()) for path in representative_artifact_document_paths}",
|
||||
"native_or_os_runs": 0
|
||||
},
|
||||
"index_top_level_fields": [
|
||||
"schema",
|
||||
"commit",
|
||||
"source_map",
|
||||
"spec_sha256",
|
||||
"marker_contract_sha256",
|
||||
"inputs",
|
||||
"cases",
|
||||
"conditions",
|
||||
"artifacts",
|
||||
"acceptance",
|
||||
"collection_error",
|
||||
"phases",
|
||||
"os_proof",
|
||||
"regression"
|
||||
],
|
||||
"representative_artifact_document_paths": [
|
||||
"runs/off-positive-writer/off-positive-writer-receipt.json",
|
||||
"runs/off-positive-reader/off-positive-reader-receipt.json",
|
||||
"runs/off-positive-writer/off-positive-writer/started.json",
|
||||
"runs/off-positive-writer/off-positive-writer/ended.json",
|
||||
"runs/off-positive-writer/off-positive-writer/outer-owned-finally.json",
|
||||
"os.json",
|
||||
"os/preview/input.json",
|
||||
"regression.json",
|
||||
"regression/input.json",
|
||||
"regression/ended.json",
|
||||
"pairs/off-positive/identity.json",
|
||||
"pairs/off-positive/writer-process.json",
|
||||
"pairs/off-positive/before-members.json"
|
||||
],
|
||||
"fixture_config_inputs": {
|
||||
"fixture_sources": {
|
||||
"tests/s1/test_p08_combined_migration.gd": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855",
|
||||
"tests/s1/test_p08_combined_migration.gd.uid": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5",
|
||||
"tests/fixtures/p08-02/README.md": "e88ca33fdb4e96602d1fb108d71a9c35b6fa054619ecf6f1396e9a6c5e0ebd98",
|
||||
"tests/fixtures/p08-02/mixed_world.gd": "a23f8a686be1d77e4874b9956eef89be4756f6e5eb01cc62454c3845acc62c25",
|
||||
"tests/fixtures/p08-02/reader.gd": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be",
|
||||
"tests/fixtures/p08-02/writer.gd": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260",
|
||||
"tools/run_p08_mixed_migration.py": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579",
|
||||
"tools/check_p08_migration_evidence.py": "928353233bf85436a5aaf8c4f77f3f82472d94b8ad2646cb1b030baf92b3b5dc",
|
||||
"tools/test_p08_migration_evidence.py": "fd9ef7ec63f53dfd5e04e261606c9303d01a2e6590e22a35fef2e35df1429280"
|
||||
},
|
||||
"native_runner_input_shape": {
|
||||
"protocol": "p08-mixed-v1",
|
||||
"commit": "<actual final commit>",
|
||||
"selected_source_map": "<exact source map>",
|
||||
"engine": "<actual executable>",
|
||||
"engine_sha256": "<raw SHA>",
|
||||
"owner_pid": "<actual collector PID>",
|
||||
"default_player": "<protected profile record>",
|
||||
"diagnostic_seed": 42588
|
||||
},
|
||||
"case_environment": {
|
||||
"P08_PAIR_ROOT": "<absolute guarded pair output>",
|
||||
"P08_OPERATIONS": "off|on",
|
||||
"P08_CASE": "positive|refusal"
|
||||
},
|
||||
"timeouts": "unchanged: collection 900s, phase maximum 180s",
|
||||
"formal_validation": "Root copies actual evidence into allocated build directory; --verify-only reads BUILD_OUTPUT_DIR/p08-evidence/index.json"
|
||||
},
|
||||
"purpose": "Synthetic Proof generator documents current schema. Historical reconstruction measurements are preserved in Git, not asserted for changed fixture.",
|
||||
"previous_full_inline_record": {
|
||||
"commit": "1545bd42d689a9a6382e2b003ee0550fa197f6e4",
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation.json",
|
||||
"sha256": "ae4a9f11c4e10a2be31d8fc6429577ff5f14f6097fae4f2d5a6a321937fefdac",
|
||||
"bytes": 16946,
|
||||
"hash_scope": "Git raw bytes",
|
||||
"preservation": "Full previous metadata/example remains byte-preserved in Git; historical links and SHA values unchanged."
|
||||
}
|
||||
},
|
||||
"historical_record": {
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation-historical-6c7c724.json",
|
||||
"sha256": "94321c2e924ef509738c8c4302c9e68854b9ce305830352d2dbb51d43f9ff34c",
|
||||
"original_full_raw_sha256": "ab1fcf46ef73f2157f16f69394b4039a562c031fae8d407adca013a452226e2f",
|
||||
"classification": "Reference to byte-preserved original full historical record in fixed Git commits and Root archive; not current canonical evidence"
|
||||
},
|
||||
"repair_r04": {
|
||||
"seed": 42588,
|
||||
"construction_cost": {
|
||||
"gold": 7110,
|
||||
"materials": 88
|
||||
},
|
||||
"signing_gold": 150,
|
||||
"food_quantity": 8,
|
||||
"food_gold": 24,
|
||||
"initial": {
|
||||
"gold": 5000,
|
||||
"materials": 50
|
||||
},
|
||||
"previous_change_resources": {},
|
||||
"derived_delta": {
|
||||
"gold": 2284,
|
||||
"materials": 38
|
||||
},
|
||||
"mismatch": "Previous zero added resources insufficient; no acceptance narrowed.",
|
||||
"git_history_verification": "Both fixed Git references raw SHA matched ab1fcf46ef73f2157f16f69394b4039a562c031fae8d407adca013a452226e2f, 1082602 bytes",
|
||||
"archive_verification": "Reuse Root supplied roundtrip evidence; archive not opened or executed."
|
||||
},
|
||||
"landing_repair": {
|
||||
"input": "ROOT_REPAIR_INPUT-r04.json",
|
||||
"ground": "initialized world paths within rank 1 bounds",
|
||||
"upper": "complete each stair pair before ordering next floor, using maximum registered build_minutes",
|
||||
"nearby_preflight": "rank bounds, registered stair definitions and existing completed logistics endpoints checked locally",
|
||||
"acceptance_sources": "all 18 retained; no omissions",
|
||||
"packet_limit_bytes": null,
|
||||
"packet_measurement": "Final actual submitted Runner packet measurement remains Root responsibility; obsolete byte cap removed; no source omission or compression.",
|
||||
"collection_timeout_seconds": 900
|
||||
},
|
||||
"metadata_sync": {
|
||||
"source_commit": "1545bd42d689a9a6382e2b003ee0550fa197f6e4",
|
||||
"current_tool_raw_sha256": {
|
||||
"tools/check_p08_migration_evidence.py": "928353233bf85436a5aaf8c4f77f3f82472d94b8ad2646cb1b030baf92b3b5dc",
|
||||
"tools/test_p08_migration_evidence.py": "fd9ef7ec63f53dfd5e04e261606c9303d01a2e6590e22a35fef2e35df1429280"
|
||||
},
|
||||
"source_map": "run_all_tests.py source_refs enumerates autoload/scripts/scenes/data/tests/assets/tools plus project.godot/export_presets.cfg/Makefile/AGENTS.md, excluding docs. Only docs changed, so source refs unchanged.",
|
||||
"worker_validation": "JSON parse, Git raw SHA equality, generator Proof reference existence; no checker/native/Godot/full regression execution.",
|
||||
"review_material_context_gap": "No .review-material or explicit complete 18-source Runner packet manifest provided in this checkout. Exact packet bytes cannot be claimed without Runner operation (prohibited); Root must measure complete actual submitted packet. No required source was removed."
|
||||
}
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
{
|
||||
"scope": "P22 new worktree stable tracked inputs only; every worker allowed path excluded",
|
||||
"authorization": "User content-preserving compression etc; no unapproved data deletion",
|
||||
"before_free_bytes": 360034304,
|
||||
"after_free_bytes": 440082432,
|
||||
"observed_delta_free_bytes": 80048128,
|
||||
"processed_files": 24,
|
||||
"elapsed_seconds": 0.9416218330152333,
|
||||
"rows": [
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/audio/bgm/tree_theme_back_candidate.wav",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/audio/bgm/tree_theme_back_candidate.wav",
|
||||
"sha256": "efe4cc1aa588661d73376720e4278427f7220ce93a5d446f198c5af607c141ca",
|
||||
"bytes": 7526444,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/audio/bgm/tree_theme_front_candidate.wav",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/audio/bgm/tree_theme_front_candidate.wav",
|
||||
"sha256": "6df0a7af307327f703c9325f5ca2ac456888102d50ef1fa76bf4cdf19d2b86cb",
|
||||
"bytes": 7526444,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-main-gameplay-visual-mock-v1.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-main-gameplay-visual-mock-v1.png",
|
||||
"sha256": "58877bb1afbf0e72af6531cadab01eca82f9bd8cefb0cdb45f81d6d2dbb83717",
|
||||
"bytes": 2722232,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-main-gameplay-visual-mock-v2-japanese-fantasy.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-main-gameplay-visual-mock-v2-japanese-fantasy.png",
|
||||
"sha256": "1c079ebb8b2b9610df0e79a2750cc5a0db53f26d137b6df511b12cb6884532d0",
|
||||
"bytes": 3049138,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-main-gameplay-visual-mock-v3-tower-style.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-main-gameplay-visual-mock-v3-tower-style.png",
|
||||
"sha256": "f802d2b4f275f136fcacc963f7d06228f5d71dbc2399a19f7e04c6bc7531321b",
|
||||
"bytes": 3076090,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-runtime-ui-v3-assets-front.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-runtime-ui-v3-assets-front.png",
|
||||
"sha256": "e54ff252bae66010dc885846acdcdb0117b930e0e3cfc8f5459acc2841eabf0d",
|
||||
"bytes": 1461992,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-runtime-ui-v4-icons.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-runtime-ui-v4-icons.png",
|
||||
"sha256": "b0826ffce116d96dbe5b901174713f84b55a0e72931f29821e0947b844b9c1b8",
|
||||
"bytes": 1317405,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-runtime-ui-v5-map-icons.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-runtime-ui-v5-map-icons.png",
|
||||
"sha256": "aca56c954b209b0a03342c0fde576cef15bfaa2ce2a1f9feedd51744fcfdb42c",
|
||||
"bytes": 1321334,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-runtime-ui-v6-actors-4k.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-runtime-ui-v6-actors-4k.png",
|
||||
"sha256": "9b8a1d9e2e4408b7ee99505d1978a44a489eb8b6945d669d1c52e7e220937e79",
|
||||
"bytes": 6569282,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-runtime-ui-v6-actors.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-runtime-ui-v6-actors.png",
|
||||
"sha256": "8f9ea1b8bbc779e3f401d4cfdc8dcb0d10b95b7f87f37d3737af9bc85aa9dddd",
|
||||
"bytes": 1322150,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-runtime-ui-v7-skins-4k.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-runtime-ui-v7-skins-4k.png",
|
||||
"sha256": "a32d61772e06b944cf7aeb7a2dd0bd1ccfac7cbb3d8e293a6d7075f780f48904",
|
||||
"bytes": 8849219,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/mockups/the-tree-runtime-ui-v7-skins.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/mockups/the-tree-runtime-ui-v7-skins.png",
|
||||
"sha256": "f0dec82c2da661df52124cd3c2f59c3ac94db9cb5d384846d42f1901ada370cf",
|
||||
"bytes": 1778605,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/themes/japanese_fantasy/actor-markers-v2.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/themes/japanese_fantasy/actor-markers-v2.png",
|
||||
"sha256": "b742c207613d773e47f21c917975a2ba0eec8a2d9485ff655fef37e3ebf4bde4",
|
||||
"bytes": 2165570,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/themes/japanese_fantasy/facility-icons-v2.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/themes/japanese_fantasy/facility-icons-v2.png",
|
||||
"sha256": "6fb830fbe3961125fe0f3e640efe63ecba4de5ea6fb758eaf0da2738940fa1b6",
|
||||
"bytes": 1848036,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/themes/japanese_fantasy/system-icons-v2.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/themes/japanese_fantasy/system-icons-v2.png",
|
||||
"sha256": "1f1d4f5e20ba4de61e3fb967352b68db435fa36ec5e4bacab2802f132e3b8d40",
|
||||
"bytes": 1786659,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/themes/japanese_fantasy/ui-skin-v1.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/themes/japanese_fantasy/ui-skin-v1.png",
|
||||
"sha256": "4b4906cc9c6ed3fdb5330bfc11177376e5fec10afa3f2dac9318dbaf71833ff2",
|
||||
"bytes": 2492477,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/themes/japanese_fantasy/world-back-v1.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/themes/japanese_fantasy/world-back-v1.png",
|
||||
"sha256": "2b0dbf07c17e677ed023c56b1e90f013c40362f46c427950033868b042508c7c",
|
||||
"bytes": 2616183,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/assets/themes/japanese_fantasy/world-front-v1.png",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/assets/themes/japanese_fantasy/world-front-v1.png",
|
||||
"sha256": "02b52ea05bdb4bbe78b8c905374052505bb73411eb7f2b0578e9b1a82994cde5",
|
||||
"bytes": 2774704,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/docs/plans/original-completion-2026-10-02/atomic_requirements.json",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/atomic_requirements.json",
|
||||
"sha256": "44530bb929fcc8c68c06d0d94da66dd04b8db7680af731b5037cd44677502938",
|
||||
"bytes": 6962475,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/all-slot-current-candidate-contracts.json",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/all-slot-current-candidate-contracts.json",
|
||||
"sha256": "5cf93b6b3fd9d0cc060075878804f65195c0d90711c969cc36e2f58f3a1917fd",
|
||||
"bytes": 1866918,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/docs/plans/original-completion-2026-10-02/current_evidence_links.json",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/current_evidence_links.json",
|
||||
"sha256": "db1837bcc8497201134297e312f4b266a297102285307ec3075d4e23632e26c2",
|
||||
"bytes": 5957822,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/docs/plans/original-completion-2026-10-02/execution/p22-03/production_backlog.json",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/execution/p22-03/production_backlog.json",
|
||||
"sha256": "ccd3a46caacae6f87c2c752a3eef49048807bb760b8cfd1abdc65bf653768177",
|
||||
"bytes": 1748832,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/docs/plans/original-completion-2026-10-02/facility_value_contracts.json",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/facility_value_contracts.json",
|
||||
"sha256": "447388ba03a29bfac25f2bcd068665aedbb07ba7641ce86f2db93d44f4c9f326",
|
||||
"bytes": 1851641,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
},
|
||||
{
|
||||
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p22-02-contract/P22-02-implement/docs/plans/original-completion-2026-10-02/work_packages.json",
|
||||
"anchor": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/docs/plans/original-completion-2026-10-02/work_packages.json",
|
||||
"sha256": "af340d1897186cf20f21e5c441929156bcdba41d21d1a4806977da7a5511fea8",
|
||||
"bytes": 1231960,
|
||||
"content_mode_owner_mtime_preserved": true
|
||||
}
|
||||
],
|
||||
"worker_output_or_source_edited": false,
|
||||
"product_anchor_modified": false,
|
||||
"semantic_changes": 0
|
||||
}
|
||||
@@ -254,6 +254,6 @@
|
||||
"validate_facility_value_contracts.py": "91640e2a76cd6cc9186f7b85c0bf379b24b6cac0d48962815235ee628e7ae43e",
|
||||
"validate_plan.py": "23678227d9b3c556f1bd903f4b5b3147c4a82ce5085e10055481026803451b80",
|
||||
"validator_update_checks.json": "f997d0f3de2cea29550840b1d5cb23647d64f81329de46758551e2b6c8fecc27",
|
||||
"work_packages.json": "af340d1897186cf20f21e5c441929156bcdba41d21d1a4806977da7a5511fea8"
|
||||
"work_packages.json": "8bdfb665f07543bddac0b8e47caab916663673d4094f70eee2d0e9cef9e972b7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6766,8 +6766,17 @@
|
||||
"title": "旧配置の安全な変更",
|
||||
"work": "混合建設、占有変更、役者の実位置、救護・物流・EVをまとめて移行する。",
|
||||
"acceptance": "重複、孤立、消失がない。解消不能時は元配置とセーブを保つ。",
|
||||
"state": "planned",
|
||||
"evidence": []
|
||||
"state": "in_progress",
|
||||
"evidence": [],
|
||||
"progress_summary": "実Opus判断でP08-02を次の原成果単位に選定。読み取り専用監査を開始し、原work/acceptanceを変更せず固定。P03-02の移動/EV/救護/物流/同時建設/後段拒否の7証拠を候補としてSHA照合し、適用版・混合batch・実位置・全参照・拒否保存の不足を確認中。個別診断を全混合受入へ拡張しない。新規実装/登録/全回帰は未起動、完了増分0。",
|
||||
"remaining_gaps": [
|
||||
"既存7証拠の適用source/input/settings/environmentを現採用版へ照合。証拠ファイルSHA一致だけでは現在適用を認定しない。",
|
||||
"個別例を混合移行全体の受入へ置き換えない。混合batch・占有変更・全実位置/搬送参照の正例/拒否例を確認。",
|
||||
"通常メニューのpreview/取消/確認と拒否時の原保存保全の実証を確認。handler試験をOS入力済みにしない。",
|
||||
"必要な局所/影響範囲検証と、共有保存/配置コードを変更する場合だけ正確な最終版で全回帰。",
|
||||
"全条件の独立Opus受入と必要統合・台帳反映。"
|
||||
],
|
||||
"updated_at_jst": "2026-10-13T19:26:15.610772+09:00"
|
||||
},
|
||||
{
|
||||
"id": "P08-03",
|
||||
@@ -9286,15 +9295,39 @@
|
||||
"sha256_at_integration": "8b72f9a24f5f1670116fdfb41995491ce42f44bab38a9f9c7206e0aaaefbb08a",
|
||||
"scope": "Located original BGM recipe/output and code SVG provenance, no final rights/quality inference",
|
||||
"current_game_acceptance_inferred": false
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/runner-live-handoff-r02.json",
|
||||
"sha256_at_integration": "03f80d548674466066dde28caabe93129fdeb1ab655c105b326b0bedca28201f",
|
||||
"scope": "Actual original task registration, lossless inputs, Opus run and same-worker normal repair; live implementation only, no acceptance",
|
||||
"current_game_acceptance_inferred": false
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/astra-live-handoff-r03.json",
|
||||
"sha256_at_integration": "c348e2ef062298542e8e28f2e6838ac633bcae0355f1ad7dfb47f233021ef50b",
|
||||
"scope": "Actual Root preflight/failed validator and recorded Opus selection of live final Astra repair; no original acceptance",
|
||||
"current_game_acceptance_inferred": false
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/astra-preserved-test-execution.json",
|
||||
"sha256_at_integration": "ad7bc30470d474cb46cfea7f10aa0465c595f3e01e43f60155dcbb5a48b656ab",
|
||||
"scope": "Actual 13 tests on unchanged preserved unsubmitted Astra code, isolated reachable positive and meaningful negatives; no original acceptance",
|
||||
"current_game_acceptance_inferred": false
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/checkpoints/p22-02-slot-contract-r02/astra-preserved-prospective-packet.json",
|
||||
"sha256_at_integration": "944ff11f24bfac185f0fef0754efbaab2f8e256e8da4fa0e4c914d9bd14fcd92",
|
||||
"scope": "Prospective complete packet487283, not exact submitted SHA; final full actual method required",
|
||||
"current_game_acceptance_inferred": false
|
||||
}
|
||||
],
|
||||
"progress_summary": "P22-01の614利用記録(360施設/176人物/2状態群/76その他)をSHA付きで引継ぎ。現物296mediaを再監査し、Kenney2packの283同梱files、UI音4とLicenseが公式archiveとbyte一致。276mediaに配布元CC0の権利証拠を結合、20mediaの最終権利は未検証。BGM2は既存original合成recipeと同byte出力を発見、SVGはbaseline codeを確認するが完成/最終権利へ昇格しない。2packed atlas192x176/16px/12x11、既存nearest/mipmap/Theme差替接続を記録。全利用枠適合/欠損開示/実表示・実聴/正式独立review/統合は未達。製品変更・新規素材導入・原成果完了増加0。",
|
||||
"progress_summary": "P22-01の614利用記録(360施設/176人物/2状態群/76その他)をSHA付きで引継ぎ。現物296mediaを再監査し、Kenney2packの283同梱files、UI音4とLicenseが公式archiveとbyte一致。276mediaに配布元CC0の権利証拠を結合、20mediaの最終権利は未検証。BGM2は既存original合成recipeと同byte出力を発見、SVGはbaseline codeを確認するが完成/最終権利へ昇格しない。2packed atlas192x176/16px/12x11、既存nearest/mipmap/Theme差替接続を記録。全利用枠適合/欠損開示/実表示・実聴/正式独立review/統合は未達。製品変更・新規素材導入・原成果完了増加0。 同じ原P22-02を新規登録し、無損失217KiB全614入力と原条件を固定。495候補/119欠損/19paths、旧SHA変化2件を照合。実OpusがSol runを選択。最初はspec raw/strip表現混同で停止、元spec/base byte一致とRunner SHA一致を実測し、普通repair1/2で同じ担当を再開。契約/checker実装中、正式unit受入0/1。 初回提出c6ccc5a6の診断integrity0/614未達を保持。正式exact argvは未対応で失敗、到達不能readyとexact資料1350690>500000をRoot実証。実Opusが最終repair2/2をAstraへ切替判断、同じtask/worktreeで修正中。c6は未採用。 Astra最終run a999bbd142334aa582f2d373ed625e78は900.05秒/exit124で終了、worker提出応答なし。残コードを保持してRoot実13試験PASS、actualCLI integrity0/ready2/614未達を確認。台帳35441bytes、prospective全packet487283<500000だが未提出なのでexact final SHA検証ではない。古い説明/metadata2文書の同期と提出応答を残し、2026-10-13: 人の直接回答で追加1回(上限2→3、使用済み2を保持)とその実装run限定timeout900→1800を承認。同じtaskを通常repairで3/3へ進めrepair_ready。プロジェクトpolicy900/他task/他role/原条件は不変。保持コード再利用・2文書同期・必要確認・正式提出に限定してOpus判断を依頼。本体未採用、原P22-02未完。 追加run6faa74aeの文書同期/AST/13試験/integrity0/ready2は終了。保持4コードSHA不変。Root計測資料の参照未供給でworkerはblocked応答、応答を改竄せず保存。Rootが正確な完成tree b56e0ddc/証拠commit aad6284fのactual全packet491572<500000を計測し参照不足を解消。Opus判断で証拠branchへ保存、通常提出/state例外/追加runなし。別Opus技術review25eefc57は高1/中5/低3を指摘、原unit受入false。highはselection_ready/receipt/checkの実正例欠損。権利・quantity・layout・実ledger負例・stale証拠等も不足。技術所見は正式原受入reviewの代替にせず、本体未採用/原完了増分0。独立して閉じられる次の原unitへ移行する。",
|
||||
"remaining_gaps": [
|
||||
"614利用記録の候補選定/適合、解像度・命名・差替・現source・権利の全対応。状態群は素材枚数へ変換しない。",
|
||||
"旧theme/mockup/BGM/iconの残る最終権利・creator記録と、完成枠の実利用・表示/聴感・欠損の非隠蔽。276の配布元権利検証は完成素材受入ではない。",
|
||||
"原条件の全証拠を固めた最終版で必要検証・別Opus独立レビュー・統合/最終・台帳完了。D08/D09未確定数量・内容を捏造しない。"
|
||||
"全614用途の使用可能な完成選定(現在0)、用途ごとの形式・解像度・命名・差替・権利・表示/実聴、必須範囲/開示を揃える。D08/D09を捏造しない。",
|
||||
"独立技術review-r05のhigh: selection_ready/receipt/checkの実到達正例。medium: 権利と素材の対応、未知数量の明示解決、用途レイアウト、実ledger改変拒否、製品更新後stale証拠の再観測。",
|
||||
"workerの正式submitted応答と通常提出、正確な対象版で正式検証・全条件独立原受入・統合。修正3/3を無断拡大せず、応答/状態を書き換えて完了させない。"
|
||||
],
|
||||
"updated_at_jst": "2026-10-13T17:42:48.624114+09:00"
|
||||
"updated_at_jst": "2026-10-13T19:25:11.280538+09:00"
|
||||
},
|
||||
{
|
||||
"id": "P22-03",
|
||||
@@ -9559,7 +9592,7 @@
|
||||
"controlled_injury_fixture": true,
|
||||
"medical_values_approved": false
|
||||
},
|
||||
"updated_at_jst": "2026-10-13T17:42:48.624114+09:00"
|
||||
"updated_at_jst": "2026-10-13T18:49:52.847202+09:00"
|
||||
},
|
||||
{
|
||||
"id": "P23",
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"id": "P08-02",
|
||||
"title": "旧配置の安全な変更",
|
||||
"work": "混合建設、占有変更、役者の実位置、救護・物流・EVをまとめて移行する。",
|
||||
"acceptance": "重複、孤立、消失がない。解消不能時は元配置とセーブを保つ。",
|
||||
"counting_scope": "Existing one unit among30 packages/88delivery units. No partial credit; 6 decomposed facets are not new delivery units or game atomic denominator.",
|
||||
"original_authority": "docs/traceability/original/BASELINE.txt",
|
||||
"approved_plan": "docs/plans/original-completion-2026-10-02/IMPLEMENTATION_PLAN.md",
|
||||
"accepted_audit_input": "docs/spec/inputs/p08-02/historical-inputs.json",
|
||||
"accepted_audit_input_raw_sha256": "b49fdcd1fa99666edb682d9bb34707d68722310b68df068e5132d339bac5464b",
|
||||
"required_conditions": [
|
||||
{
|
||||
"id": "mixed_construction",
|
||||
"text": "複数の旧寸法建設中ジョブと完成施設を同一batchで実移行し、進捗・支払・予約・完成IDを保全する。"
|
||||
},
|
||||
{
|
||||
"id": "occupancy_change",
|
||||
"text": "追加/解放セル、support、world占有とconstruction所有を一致させ、重複と孤立を残さない。"
|
||||
},
|
||||
{
|
||||
"id": "actual_actor_positions",
|
||||
"text": "移動途中の客/職員の実位置・movement credit・経路/予約・所持資金等を許可された形状/明示route変更以外で変えない。"
|
||||
},
|
||||
{
|
||||
"id": "combined_rescue_logistics_ev",
|
||||
"text": "同一保存/移行batchに実救護患者/搬送者/目的地、物流荷物/予約/要求、EV乗客/待機/旅程を含め、全IDと相互参照・数量・元要求の一回完了を保全する。"
|
||||
},
|
||||
{
|
||||
"id": "no_overlap_orphan_loss",
|
||||
"text": "同一current版のOperations ON/OFFと別PID保存再開で全状態/全イベントと対象数/参照を照合し、重複・孤立・消失・二重効果がない。"
|
||||
},
|
||||
{
|
||||
"id": "unsolvable_preservation",
|
||||
"text": "後段の解消不能batchを拒否し、先行候補の部分適用なし。現live・原配置/正式save全member・既存migration backup全memberを保持し、別PIDで元の動作を継続できる。"
|
||||
}
|
||||
],
|
||||
"current_source_pins": {
|
||||
"autoload/simulation_runtime.gd": "d52a995ae715542bbc550f68d35889540658275d12e04ae0b21ac276f5843f39",
|
||||
"scripts/construction/facility_resize_preview.gd": "d0e8d772a648a297ee0a4625206b073be2668b32c7dba2575ba1295f5b1866ac",
|
||||
"scripts/construction/facility_resize_routes.gd": "05d4aedcc930160eafc2945711f867744f63f5f391e4759f8e2de9211b968201",
|
||||
"scripts/core/save_service.gd": "0c158d3e6ee693b89814bf232c954e4757c5ff91dc9df03bb322c3e593e73617",
|
||||
"scripts/world/path_service.gd": "447135729a1106639a6eee6754af3195c8a8b458ca26980ae91fa39d80dcfbd4",
|
||||
"scenes/main/main.gd": "41df8857f9658c17b01361350979caa942b9326c82c9f176517972c2a9692f55",
|
||||
"tools/run_all_tests.py": "320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4",
|
||||
"tools/regression/owned_outer.py": "c2e3483b76db1a3ff940f23f88ea0083fc78736e874ebcdb385d766dde8866e7",
|
||||
"tools/strict_test_markers.py": "1cb16da6c5c00c1a0610a3fc04beb97d1eb3ba492fb1bc8fe5b621d2b7bc0406",
|
||||
"tests/s1/test_dimension_batch_save.gd": "ca397c0457996bab637e8be5217b7db2c14579a1b0df54434b4000a69e793bbf",
|
||||
"tests/ui/test_dimension_migration_ui.gd": "0f0cec88ea8bf5fccdcd5ade02fab70b7dc71135132048cd10db17ad9d964c0d"
|
||||
},
|
||||
"evidence_requirements": [
|
||||
"Exact final submitted source map and input/config/environment (real native PID/version and private guarded profiles), bounded raw logs and strict completion markers. Historical7 cases had29 source differences and OperationsOFF; cannot become current combined PASS solely by hashes or function matching.",
|
||||
"One coherent mixed fixture includes all6 facets; actual Runtime methods, real persisted actors/jobs/items/transport. Exercise both OperationsON/OFF, positive migration and late refusal, actual formal save/backup and separate writer/reader PID continuation. Full typed states and uncapped events preserved; only explicitly enumerated approved geometry/route changes and pre-existing justified IO schema difference may differ, never discard unexplained fields/events.",
|
||||
"Normal production migration menu preview/cancel/confirm and changed-source rejection at samecandidate: Root collects real OS inputs/screens/model/formal state; signal-emitted UI test is only handler evidence. Root stage can load controlled oldsave; do not label injected setup as natural production.",
|
||||
"Existing current local UI/dimension batch, save/restoration/path/ownership suites are reused. Required final full regression after final changes batch; only repeat if actual changes/failures require. Full regression and tests counts never replace all6 acceptance.",
|
||||
"All original conditions, separate independent Opus review, main integration/current applicable final verification and ledger reflection are required before unit closure. Windows coverage stays explicitly pending where applicable, no inference from Mac native/PCK."
|
||||
],
|
||||
"implementation_outputs": [
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-02/CONDITION_MATRIX.md",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-02/implementation.json",
|
||||
"tests/s1/test_p08_combined_migration.gd",
|
||||
"tests/fixtures/p08-02/",
|
||||
"tools/run_p08_mixed_migration.py",
|
||||
"tools/check_p08_migration_evidence.py",
|
||||
"tools/test_p08_migration_evidence.py"
|
||||
],
|
||||
"worker_instructions": [
|
||||
"Read exact work and acceptance. Preserve existing successful migration code and supplied21 historical fixture/driver files. Historicaldrivers have frozen external paths/oldsourcecounts; use as design references, never run them as current. All needed source is inside this frozenrepo. No secondworker, provider switch, git writes, Runner or cap/policy edits.",
|
||||
"Authorized implementation is new bounded mixed fixture/driver/evidence checker/docs. No runtime/UI production edits in initial scope. If actual invariant defect demonstrated, submit concrete minimal proposed patch and failing evidence without silently narrowing acceptance; originalunit stays incomplete until requiredfix and allacceptance.",
|
||||
"Reuse source from docs/spec/inputs/p08-02/. Create composable writer and reader under tests/fixtures/p08-02 with new standalone test_p08_combined_migration suite. Actual mixed state must include active guest route, realstaff/rescue/foodcargo/EV requests and oldsize paidjob plus completed facility in sameworld. Use existing domain methods and fixture setup, no invented production coefficients. Controlled fixture values/seeds explicitly diagnostic inputs.",
|
||||
"Use existing tools/run_all_tests.py execute_phase/profile guard/owned_outer protocol for bounded host collection, all current-source CoW and guarded fresh profiles, captured realprocess cleanup, strictmarkers, exactworld and formal package members. Driver receives --project-root and --output absolute args; no fixed outsideworktree input paths or1299 admission constant. Root invokes --collect with actual finalcommit; worker need not runGodot/fullregression. New finite fixtures standalone so final fullroster can run without external Root artifact paths. Do not edit tools/run_all_tests.py or existing suite policy. Add exactly one new test_p08_combined_migration marker entry to docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json, preserving every existing entry. Driver owns only newfixture phase markers and customcase traces. Public added suite must run independently of external artifacts; this suite addition is a test, not a new delivery unit.",
|
||||
"Checker --verify-only reads BUILD_OUTPUT_DIR/p08-evidence/index.json. Root copies actual evidence into allocateddir before formalvalidation. Index has exact source map, fixture/config inputs, phase receipts, rawcaptured native lifecycle, strictlogs, whole typedstate/formal-member hashes and every6condition attribution, normalOS proof and final regression receipt. Verify source and bound artifact content, actual distinctPID/ended/exit, not self-reported PASS booleans. Missing/stale/malformed/partialcase must list deficits and non0; technical artifact integrity cannot claim original unit accepted.",
|
||||
"Review Root native index shape from existing native receipts; define newindex explicitly in docs with machine-readable example fixture rather than invent opaque proof. Preserve read-only fullcontent mapping and logged refusals. Anybyte-copy operation verifies rawSHA/content and does not delete earlierproofs. Root host collection and formalchecker are different; no sandboxrights expansion or paidAPI.",
|
||||
"Meaningful wholechecker positives and negatives: pure isolated temporary proof fixture exercises check() through exact schema/source/phase/file links, then realindex mutations/deletions for duplicateactor, orphanoccupancy, patient/cargo/EV loss, partialbatch, overwrittenoriginal/backup, unequal crossPID state, missingON, wrong/stale source and fakeOSsignals. Positive must be reachable; do not replace full proof with allbooltrue reducer or alwaysfail readiness. Negativecorruptdata in disposable fixtures only. Avoid implementation-mirroring trivial tests; tests prove original invariants/gatefalseacceptance.",
|
||||
"Python stdlib, python -B/ast.parse, bounded local checker tests only in worker. Native/fullregression/OS collection is Root responsibility after formal code submission. Read specSHA as gitshow stdout.strip UTF8, distinguish raw trailingnewline. Final full reviewerpacket measurement belongs Root on actualsubmittedSHA. Never refuse code submission solely because Root references/native/OS/finalpacket not yet collected.",
|
||||
"Return genuine status submitted when bounded implemented code is ready forRoot verification, listing every pending originalcondition, actual check/failure and exact productfix proposal if any. Pending native/OS/fullregression/independentreview is not originalcompleted and not a reason to manufacture missingproof or change response to blocked. If code cannot be implemented state precisecause instead; do not selfclaimtests/sourceacceptance.",
|
||||
"Keep scope focused. No manavalues, D05/D07/D08/D09 semantic choices, new assets, economicprices, storycontent, original30/88 or source baseline rewriting. Preserve unique-character protection/defaultplayer and all historicalfailedlogs."
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,131 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-EV-retarget-refusal-native-r02/migration-pair"
|
||||
const MODE := "read"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
var room_id: StringName
|
||||
const OLD_TARGET:=Vector3i(-7,3,0)
|
||||
const SLOT: String="user://p03-EV-refusal/manual"
|
||||
func package_hashes() -> Dictionary:
|
||||
var values: Dictionary={}
|
||||
for suffix: String in ["",SaveService.MIGRATION_BACKUP_SUFFIX]:
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
values[suffix+"/"+name]=FileAccess.get_sha256(ProjectSettings.globalize_path(SLOT+suffix).path_join(name))
|
||||
return values
|
||||
func refusal(label: String) -> void:
|
||||
var before: Dictionary=runtime.create_snapshot()
|
||||
var packages: Dictionary=package_hashes()
|
||||
var prepared: Dictionary=runtime.prepare_facility_dimension_snapshot(room_id)
|
||||
expect(not prepared.get(&"ok",false) and &"TRANSPORT_REPLAN_REQUIRED" in prepared.get(&"retargeting",{}).get(&"errors",[]),"actual occupied trip explicitly refuses retarget")
|
||||
expect(prepared.get(&"routes",{}).get(&"guest_replans",[]).size()==1,"one actual guest destination requires replan")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(SLOT)
|
||||
expect(not preview.get(&"ok",false),"formal migration review rejects occupied retarget")
|
||||
var result: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(not result.get(&"ok",false) and result.get(&"code",&"")==&"DIMENSION_MIGRATION_REJECTED" and result.get(&"details",{}).get(&"rolled_back",false),"formal batch refuses and rolls back isolated candidate")
|
||||
expect(var_to_bytes(before)==var_to_bytes(runtime.create_snapshot()),"entire live world unchanged after all three migration paths")
|
||||
expect(package_hashes()==packages,"all original and real preexisting backup files unchanged")
|
||||
write_proof(MODE+"-"+label+"-refusal.var",{&"prepared":prepared,&"preview":preview,&"result":result,&"packages":packages})
|
||||
capture(label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new();clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42588)[&"valid"],"canonical current initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"own fresh evidence directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived definition")
|
||||
for row: Array in [[&"guest_elevator",Vector3i(-8,0,0)],[&"reception",Vector3i(-6,0,0)],[&"premium_room",Vector3i(-6,2,0)],[&"guest_stairs",Vector3i(-7,2,0)],[&"guest_stairs",Vector3i(-7,3,0)]]:
|
||||
if not command(&"build_facility",{&"definition_id":row[0],&"origin":row[1]}).is_success():
|
||||
runtime.free();clock.free();state.free()
|
||||
print("EV retarget refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures);return
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(row[0]).build_minutes)
|
||||
for instance: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if instance.definition_id==&"premium_room":room_id=instance.instance_id
|
||||
expect(not room_id.is_empty(),"normally paid completed old-size room")
|
||||
expect(not runtime.path_service.find_path(Vector3i(-8,0,0),OLD_TARGET).is_empty(),"real paid old upper entrance reachable through EV and corridors")
|
||||
var baseline: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,baseline)[&"ok"],"formal old room baseline before real backup creation")
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"current approved footprint registry")
|
||||
var first: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(first.get(&"ok",false) and first.get(&"backup_created",false),"normal unoccupied migration creates actual verified backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(baseline),"first migration leaves live original geometry")
|
||||
expect(var_to_bytes(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{}))==var_to_bytes(baseline),"actual backup exactly restores pre-migration baseline")
|
||||
write_proof("baseline.var",baseline)
|
||||
command(&"spawn_guest",{&"guest_id":&"p03.retarget.passenger",&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i(-8,0,0),&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"target_facility_id":room_id,&"path_handle":{&"target_cell":OLD_TARGET}}})
|
||||
clock.advance_minutes(2)
|
||||
var trip: Dictionary=runtime.elevators.get_actor_trip(&"guest:p03.retarget.passenger")
|
||||
expect(not trip.is_empty() and trip.get(&"state",&"")==&"BOARDED","real passenger owns actual boarded EV trip")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,legacy)[&"ok"],"formal original includes occupied trip and old entrance")
|
||||
write_proof("legacy.var",legacy);write_proof("identity.var",{&"room_id":room_id,&"serial":serial,&"request_id":trip.get(&"request_id",&"")})
|
||||
copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("original/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current approved footprint registry")
|
||||
var identity: Dictionary=read_proof("identity.var");room_id=identity[&"room_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("original/formal"),ProjectSettings.globalize_path(SLOT))
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{})),"separate PID restores real earlier backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("baseline.var")),"whole earlier backup state matches")
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT).get(&"snapshot",{})),"actual original boarded package restores")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole boarded original restored exactly")
|
||||
capture("checkpoint");refusal("reject1");refusal("reject2")
|
||||
if MODE=="write":copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("after-refusal/formal"))
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.refusal.uncapped",Callable(self,"observe")),"whole uncapped post-refusal journal")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(10);capture("final20")
|
||||
expect(runtime.facility_service.get_instance(room_id).occupied_cells.size()==6,"rejected conversion retains original facility shape")
|
||||
expect(runtime.elevators.get_actor_trip(&"guest:p03.retarget.passenger").is_empty() and runtime.path_service.get_transit_actor_ids().is_empty(),"original EV trip finishes without orphan transit after refusal")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"post-refusal continuation remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"entire post-refusal journal matches without deletion or replacement")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("EV retarget refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,131 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-EV-retarget-refusal-native-r02/migration-pair"
|
||||
const MODE := "write"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
var room_id: StringName
|
||||
const OLD_TARGET:=Vector3i(-7,3,0)
|
||||
const SLOT: String="user://p03-EV-refusal/manual"
|
||||
func package_hashes() -> Dictionary:
|
||||
var values: Dictionary={}
|
||||
for suffix: String in ["",SaveService.MIGRATION_BACKUP_SUFFIX]:
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
values[suffix+"/"+name]=FileAccess.get_sha256(ProjectSettings.globalize_path(SLOT+suffix).path_join(name))
|
||||
return values
|
||||
func refusal(label: String) -> void:
|
||||
var before: Dictionary=runtime.create_snapshot()
|
||||
var packages: Dictionary=package_hashes()
|
||||
var prepared: Dictionary=runtime.prepare_facility_dimension_snapshot(room_id)
|
||||
expect(not prepared.get(&"ok",false) and &"TRANSPORT_REPLAN_REQUIRED" in prepared.get(&"retargeting",{}).get(&"errors",[]),"actual occupied trip explicitly refuses retarget")
|
||||
expect(prepared.get(&"routes",{}).get(&"guest_replans",[]).size()==1,"one actual guest destination requires replan")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(SLOT)
|
||||
expect(not preview.get(&"ok",false),"formal migration review rejects occupied retarget")
|
||||
var result: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(not result.get(&"ok",false) and result.get(&"code",&"")==&"DIMENSION_MIGRATION_REJECTED" and result.get(&"details",{}).get(&"rolled_back",false),"formal batch refuses and rolls back isolated candidate")
|
||||
expect(var_to_bytes(before)==var_to_bytes(runtime.create_snapshot()),"entire live world unchanged after all three migration paths")
|
||||
expect(package_hashes()==packages,"all original and real preexisting backup files unchanged")
|
||||
write_proof(MODE+"-"+label+"-refusal.var",{&"prepared":prepared,&"preview":preview,&"result":result,&"packages":packages})
|
||||
capture(label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new();clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42588)[&"valid"],"canonical current initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"own fresh evidence directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived definition")
|
||||
for row: Array in [[&"guest_elevator",Vector3i(-8,0,0)],[&"reception",Vector3i(-6,0,0)],[&"premium_room",Vector3i(-6,2,0)],[&"guest_stairs",Vector3i(-7,2,0)],[&"guest_stairs",Vector3i(-7,3,0)]]:
|
||||
if not command(&"build_facility",{&"definition_id":row[0],&"origin":row[1]}).is_success():
|
||||
runtime.free();clock.free();state.free()
|
||||
print("EV retarget refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures);return
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(row[0]).build_minutes)
|
||||
for instance: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if instance.definition_id==&"premium_room":room_id=instance.instance_id
|
||||
expect(not room_id.is_empty(),"normally paid completed old-size room")
|
||||
expect(not runtime.path_service.find_path(Vector3i(-8,0,0),OLD_TARGET).is_empty(),"real paid old upper entrance reachable through EV and corridors")
|
||||
var baseline: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,baseline)[&"ok"],"formal old room baseline before real backup creation")
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"current approved footprint registry")
|
||||
var first: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(first.get(&"ok",false) and first.get(&"backup_created",false),"normal unoccupied migration creates actual verified backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(baseline),"first migration leaves live original geometry")
|
||||
expect(var_to_bytes(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{}))==var_to_bytes(baseline),"actual backup exactly restores pre-migration baseline")
|
||||
write_proof("baseline.var",baseline)
|
||||
command(&"spawn_guest",{&"guest_id":&"p03.retarget.passenger",&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i(-8,0,0),&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"target_facility_id":room_id,&"path_handle":{&"target_cell":OLD_TARGET}}})
|
||||
clock.advance_minutes(2)
|
||||
var trip: Dictionary=runtime.elevators.get_actor_trip(&"guest:p03.retarget.passenger")
|
||||
expect(not trip.is_empty() and trip.get(&"state",&"")==&"BOARDED","real passenger owns actual boarded EV trip")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,legacy)[&"ok"],"formal original includes occupied trip and old entrance")
|
||||
write_proof("legacy.var",legacy);write_proof("identity.var",{&"room_id":room_id,&"serial":serial,&"request_id":trip.get(&"request_id",&"")})
|
||||
copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("original/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current approved footprint registry")
|
||||
var identity: Dictionary=read_proof("identity.var");room_id=identity[&"room_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("original/formal"),ProjectSettings.globalize_path(SLOT))
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{})),"separate PID restores real earlier backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("baseline.var")),"whole earlier backup state matches")
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT).get(&"snapshot",{})),"actual original boarded package restores")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole boarded original restored exactly")
|
||||
capture("checkpoint");refusal("reject1");refusal("reject2")
|
||||
if MODE=="write":copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("after-refusal/formal"))
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.refusal.uncapped",Callable(self,"observe")),"whole uncapped post-refusal journal")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(10);capture("final20")
|
||||
expect(runtime.facility_service.get_instance(room_id).occupied_cells.size()==6,"rejected conversion retains original facility shape")
|
||||
expect(runtime.elevators.get_actor_trip(&"guest:p03.retarget.passenger").is_empty() and runtime.path_service.get_transit_actor_ids().is_empty(),"original EV trip finishes without orphan transit after refusal")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"post-refusal continuation remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"entire post-refusal journal matches without deletion or replacement")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("EV retarget refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import hashlib,importlib.util,json,sys,os
|
||||
sys.dont_write_bytecode=True
|
||||
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';P=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-EV-retarget-refusal-prep-r02')
|
||||
TEST='tests/s3/test_runtime_staff_assignment.gd'
|
||||
READER='tests/s6/test_runtime_snapshot_serialization.gd'
|
||||
def module(n,p):
|
||||
s=importlib.util.spec_from_file_location(n,p);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
|
||||
def main():
|
||||
assert len(sys.argv)==2
|
||||
mode='formal-cross-pid';out=Path(sys.argv[1]);assert out.parent==A and not out.exists() and str(out)==json.loads((P/'preparation.json').read_bytes())['planned_output']
|
||||
r=module('role_formal_literal_runner',R/'tools/run_all_tests.py')
|
||||
seal=r.read(P/'input-seal.json')
|
||||
assert set(str(p.relative_to(P)) for p in P.rglob('*') if p.is_file())==set(seal['files'])|{'input-seal.json','preparation.json'}
|
||||
for n,v in seal['files'].items():assert Path(v['path'])==P/n and r.sha(v['path'])==v['sha256'] and Path(v['path']).stat().st_size==v['bytes']
|
||||
for name in ['writer.gd','reader.gd']:
|
||||
lines=(P/name).read_text().splitlines();bindings=[line[len('const PAIR_ROOT := '):]for line in lines if line.startswith('const PAIR_ROOT := ')]
|
||||
assert len(bindings)==1 and json.loads(bindings[0])==str(out/'migration-pair') and not (out/'migration-pair').exists()
|
||||
root_before=r.source_refs(R);assert len(root_before)==1299
|
||||
adopted=r.read(A/'p03-current1299-defense-empty-two-ref-source-adoption-r01/source-after.json')
|
||||
assert {n:v['sha256']for n,v in root_before.items()}==adopted
|
||||
refs=dict(root_before);refs[TEST]=seal['files']['writer.gd'];refs[READER]=seal['files']['reader.gd']
|
||||
for n,v in refs.items():assert Path(v['path']).stat().st_size==v['bytes'] and r.sha(v['path'])==v['sha256']
|
||||
docs={n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in ('IMPLEMENTATION_PLAN.md','PROGRESS_INTEGRATION.md','work_packages.json','progress_snapshot.json')}
|
||||
outer=module('bath_literal_owned_outer',r.SUPPORT/'owned_outer.py');assert not outer.native.helper['live_engines']()
|
||||
engine='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
out.mkdir();stage=out/'stage';stage.mkdir();(out/'starters').mkdir();(out/'bootstrap').mkdir()
|
||||
for n,v in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data=v['text'].encode();assert hashlib.sha256(data).hexdigest()==v['sha256'];(out/'bootstrap'/n).write_bytes(data)
|
||||
protected=r.default_player(R);expected={n:{'bytes':v['bytes'],'sha256':v['sha256']}for n,v in refs.items()}
|
||||
selected={'root_before':root_before,'map':{n:v['sha256']for n,v in refs.items()},'timeout':180}
|
||||
for n,v in refs.items():
|
||||
p=stage/n;p.parent.mkdir(parents=True,exist_ok=True);r.copy_source(Path(v['path']),p)
|
||||
assert r.inventory(stage,stage=True)==expected
|
||||
public=(stage/'project.godot').read_bytes();paths=['res://'+n for n in sorted(refs) if n.endswith('.gd')];r.write(out/'parse-paths.json',paths)
|
||||
markers=module('bath_literal_markers',R/'tools/strict_test_markers.py')
|
||||
contracts=markers.load_contracts(R/'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json')
|
||||
contracts[TEST]={'test':TEST,'template':'EV retarget refusal formal write: <checks> checks, <failures> failures','required':True}
|
||||
contracts[READER]={'test':READER,'template':'EV retarget refusal formal read: <checks> checks, <failures> failures','required':True}
|
||||
policy=r.read(r.SUPPORT/'suite-policy.json');assert TEST not in policy['suite_policies'] and READER not in policy['suite_policies']
|
||||
r.write(out/'runner-input.json',{'mode':mode,'owner_pid':os.getpid(),'wrapper_sha256':r.sha(__file__),'runner_sha256':r.sha(R/'tools/run_all_tests.py'),'selected_source_map':selected['map'],'source_before':root_before,'default_player':protected,'doc4_before':docs,'actual_full':False,'source_adoption':False})
|
||||
diagnostics=module('bath_literal_diagnostics',r.SUPPORT/'diagnostic_gate.py');owners=module('bath_literal_owners',r.SUPPORT/'ordinary_proof_gate.py');audio=module('bath_literal_audio',r.SUPPORT/'audio_evidence_gate.py')
|
||||
phases=[];previous={};error=None;formal_before=None
|
||||
try:
|
||||
for phase,test in [('import',None),('parse',None),('writer',TEST),('reader',READER)]:
|
||||
if phase=='writer':assert not (out/'migration-pair').exists()
|
||||
if phase=='reader':assert r.inventory(out/'migration-pair')==pair_before
|
||||
row=r.execute_phase(engine,stage,out,phase,test,selected,expected,previous,policy,contracts,paths,public,protected,R,outer,markers,diagnostics,owners,audio);phases.append(row)
|
||||
print(json.dumps({'phase':phase,'passed':row['passed'],'checks':row.get('reported_checks'),'error':row.get('validation_error'),'guard_error':row.get('guard_error')}),flush=True)
|
||||
r.require(row['passed'],'strict phase failure stops without retry')
|
||||
if phase=='writer':
|
||||
pair_before=r.inventory(out/'migration-pair');formal_before={n:v for n,v in pair_before.items()if '/formal/'in n}
|
||||
assert len(formal_before)==12
|
||||
r.write(out/'actual-formal-before-reader.json',formal_before)
|
||||
if phase=='reader':
|
||||
after=r.inventory(out/'migration-pair');assert {n:v for n,v in after.items()if '/formal/'in n}==formal_before
|
||||
assert all(after[n]==v for n,v in pair_before.items())
|
||||
r.write(out/'actual-formal-after-reader.json',{n:v for n,v in after.items()if '/formal/'in n})
|
||||
except BaseException as caught:error=type(caught).__name__+': '+str(caught)
|
||||
finally:cleanup,cleanup_errors=outer.finish_captured(outer.OWNED)
|
||||
passed=error is None and not cleanup_errors and len(phases)==4 and all(x['passed'] for x in phases) and all(x['engine_ended'] for x in cleanup)
|
||||
assert r.source_refs(R)==root_before and r.default_player(R)==protected
|
||||
assert {n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in docs}==docs
|
||||
assert r.inventory(stage,stage=True)==dict(expected,**previous)
|
||||
r.write(out/'runner-ended.json',{'mode':mode,'passed':passed,'phases':phases,'cleanup':cleanup,'cleanup_errors':cleanup_errors,'error':error,'whole_source_unchanged':True,'whole_default_profile_unchanged':True,'doc4_unchanged':True,'source_adoption':False,'normal_GUI_accepted':False,'full_regression_accepted':False,'formal_cross_PID_accepted':False,'actual_captured_PIDs':[p.pid for p in outer.OWNED],'actual_native_processes':len(outer.OWNED),'actual_checks':sum(p.get('reported_checks',0)for p in phases if p['test']) if passed else None,'formal_reader_evidence_scope':'headless direct formal changed-entrance migration refusal with actual paid old room and boarded passenger; actual earlier successful migration backup retained; separate-PID whole original/backup and post-refusal continuation. Operations OFF public fixture passenger; no Main OS/rescue/logistics/full migration acceptance','native_Windows_accepted':False,'whole_goal_accepted':False})
|
||||
print(json.dumps({'mode':mode,'passed':passed,'error':error,'actual_native':len(phases),'actual_checks':phases[-1].get('reported_checks')}),flush=True)
|
||||
return 0 if passed else 1
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1,143 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-batch-later-refusal-native-r02/migration-pair"
|
||||
const MODE := "read"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
var room_id: StringName
|
||||
const OLD_TARGET:=Vector3i(-7,3,1)
|
||||
const SLOT: String="user://p03-batch-later-refusal/manual"
|
||||
func package_hashes() -> Dictionary:
|
||||
var values: Dictionary={}
|
||||
for suffix: String in ["",SaveService.MIGRATION_BACKUP_SUFFIX]:
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
values[suffix+"/"+name]=FileAccess.get_sha256(ProjectSettings.globalize_path(SLOT+suffix).path_join(name))
|
||||
return values
|
||||
func refusal(label: String) -> void:
|
||||
var before: Dictionary=runtime.create_snapshot()
|
||||
var packages: Dictionary=package_hashes()
|
||||
var first: Dictionary=runtime.prepare_facility_dimension_snapshot(job_id)
|
||||
expect(first.get(&"ok",false),"first paid legacy job is independently migratable before later refusal")
|
||||
var prepared: Dictionary=runtime.prepare_all_facility_dimension_snapshots()
|
||||
expect(not prepared.get(&"ok",false) and prepared.get(&"facility_id",&"")==room_id and prepared.get(&"rolled_back",false),"actual second-target rejection rolls back earlier applied job")
|
||||
expect(prepared.get(&"details",{}).get(&"routes",{}).get(&"errors",[]).any(func(error: Variant):return error is Dictionary and error.get(&"code",&"")==&"TASK_DESTINATION_CHANGED"),"real old upper-entry task specifically refuses lost destination")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(SLOT)
|
||||
expect(not preview.get(&"ok",false),"formal preview rejects later target")
|
||||
var result: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(not result.get(&"ok",false) and result.get(&"code",&"")==&"DIMENSION_MIGRATION_REJECTED" and result.get(&"details",{}).get(&"rolled_back",false),"formal batch refuses and rolls back isolated candidate")
|
||||
expect(var_to_bytes(before)==var_to_bytes(runtime.create_snapshot()),"entire live world unchanged after all three migration paths")
|
||||
expect(package_hashes()==packages,"all original and real preexisting backup files unchanged")
|
||||
write_proof(MODE+"-"+label+"-refusal.var",{&"first":first,&"prepared":prepared,&"preview":preview,&"result":result,&"packages":packages})
|
||||
capture(label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new();clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42588)[&"valid"],"canonical current initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"own fresh evidence directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://tests/fixtures/legacy_staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived definition")
|
||||
for row: Array in [[&"warehouse",Vector3i(-6,0,1)],[&"service_stairs",Vector3i(-7,1,1)],[&"service_stairs",Vector3i(-7,2,1)],[&"service_stairs",Vector3i(-7,3,1)],[&"staff_dormitory",Vector3i(-6,2,1)],[&"reception",Vector3i(-6,0,0)],[&"guest_stairs",Vector3i(4,1,0)],[&"guest_stairs",Vector3i(4,2,0)],[&"guest_stairs",Vector3i(4,3,0)]]:
|
||||
if not command(&"build_facility",{&"definition_id":row[0],&"origin":row[1]}).is_success():
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Batch later refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures);return
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(row[0]).build_minutes)
|
||||
for instance: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if instance.definition_id==&"staff_dormitory":room_id=instance.instance_id
|
||||
expect(not room_id.is_empty(),"normally paid completed archived dormitory")
|
||||
if not command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)}).is_success():runtime.free();clock.free();state.free();quit(1);return
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid first-target partial job")
|
||||
if job_id.is_empty():runtime.free();clock.free();state.free();quit(1);return
|
||||
var baseline: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,baseline)[&"ok"],"formal old room baseline before real backup creation")
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
paths.erase("res://tests/fixtures/legacy_staff_dormitory.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"current approved footprint registry")
|
||||
var first: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(first.get(&"ok",false) and first.get(&"backup_created",false),"normal unconstrained two-target migration creates actual verified backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(baseline),"first migration leaves live original geometry")
|
||||
expect(var_to_bytes(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{}))==var_to_bytes(baseline),"actual backup exactly restores pre-migration baseline")
|
||||
write_proof("baseline.var",baseline)
|
||||
expect(command(&"register_staff",{&"staff_id":&"batch_maintainer",&"role_id":&"porter",&"options":{&"current_cell":Vector3i(-7,1,1),&"state":StaffRuntime.State.AVAILABLE}}).is_success(),"public worker for actual old-entry task")
|
||||
expect(runtime.staff_service.create_task(&"maintenance",10,clock.absolute_minute,{&"target_entity_id":room_id,&"target_cell":OLD_TARGET,&"estimated_minutes":30},&"batch_old_entry_task").is_success(),"public actual old-entry maintenance task")
|
||||
expect(runtime.staff_service.assign_task_to_staff(&"batch_old_entry_task",&"batch_maintainer",clock.absolute_minute).is_success(),"public real task owner assignment")
|
||||
clock.advance_minutes(1)
|
||||
var task: StaffTask=runtime.staff_service.get_task(&"batch_old_entry_task")
|
||||
expect(not task.is_terminal() and task.assigned_staff_id==&"batch_maintainer" and runtime.staff_service.get_staff(&"batch_maintainer").current_task_id==task.task_id,"real old-entry work remains in flight at formal save")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,legacy)[&"ok"],"formal original includes partial job and real upper-entry task")
|
||||
write_proof("legacy.var",legacy);write_proof("identity.var",{&"room_id":room_id,&"serial":serial,&"job_id":job_id,&"task_id":&"batch_old_entry_task"})
|
||||
copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("original/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current approved footprint registry")
|
||||
var identity: Dictionary=read_proof("identity.var");room_id=identity[&"room_id"];job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("original/formal"),ProjectSettings.globalize_path(SLOT))
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{})),"separate PID restores real earlier backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("baseline.var")),"whole earlier backup state matches")
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT).get(&"snapshot",{})),"actual original batch-source package restores")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole original batch source restored exactly")
|
||||
capture("checkpoint");refusal("reject1");refusal("reject2")
|
||||
if MODE=="write":copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("after-refusal/formal"))
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.refusal.uncapped",Callable(self,"observe")),"whole uncapped post-refusal journal")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
expect(runtime.facility_service.get_instance(room_id).occupied_cells.size()==8,"later rejected dorm retains entire original footprint")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==6,"earlier rolled-back job completes with its original legacy footprint")
|
||||
expect(runtime.staff_service.get_task(&"batch_old_entry_task").state==StaffTask.State.COMPLETED and runtime.staff_service.get_staff(&"batch_maintainer").current_cell==OLD_TARGET and runtime.staff_service.get_staff(&"batch_maintainer").current_task_id.is_empty(),"actual original maintenance reaches old entry and finishes without orphan work")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"post-refusal continuation remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"entire post-refusal journal matches without deletion or replacement")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Batch later refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,143 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-batch-later-refusal-native-r02/migration-pair"
|
||||
const MODE := "write"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
var room_id: StringName
|
||||
const OLD_TARGET:=Vector3i(-7,3,1)
|
||||
const SLOT: String="user://p03-batch-later-refusal/manual"
|
||||
func package_hashes() -> Dictionary:
|
||||
var values: Dictionary={}
|
||||
for suffix: String in ["",SaveService.MIGRATION_BACKUP_SUFFIX]:
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
values[suffix+"/"+name]=FileAccess.get_sha256(ProjectSettings.globalize_path(SLOT+suffix).path_join(name))
|
||||
return values
|
||||
func refusal(label: String) -> void:
|
||||
var before: Dictionary=runtime.create_snapshot()
|
||||
var packages: Dictionary=package_hashes()
|
||||
var first: Dictionary=runtime.prepare_facility_dimension_snapshot(job_id)
|
||||
expect(first.get(&"ok",false),"first paid legacy job is independently migratable before later refusal")
|
||||
var prepared: Dictionary=runtime.prepare_all_facility_dimension_snapshots()
|
||||
expect(not prepared.get(&"ok",false) and prepared.get(&"facility_id",&"")==room_id and prepared.get(&"rolled_back",false),"actual second-target rejection rolls back earlier applied job")
|
||||
expect(prepared.get(&"details",{}).get(&"routes",{}).get(&"errors",[]).any(func(error: Variant):return error is Dictionary and error.get(&"code",&"")==&"TASK_DESTINATION_CHANGED"),"real old upper-entry task specifically refuses lost destination")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(SLOT)
|
||||
expect(not preview.get(&"ok",false),"formal preview rejects later target")
|
||||
var result: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(not result.get(&"ok",false) and result.get(&"code",&"")==&"DIMENSION_MIGRATION_REJECTED" and result.get(&"details",{}).get(&"rolled_back",false),"formal batch refuses and rolls back isolated candidate")
|
||||
expect(var_to_bytes(before)==var_to_bytes(runtime.create_snapshot()),"entire live world unchanged after all three migration paths")
|
||||
expect(package_hashes()==packages,"all original and real preexisting backup files unchanged")
|
||||
write_proof(MODE+"-"+label+"-refusal.var",{&"first":first,&"prepared":prepared,&"preview":preview,&"result":result,&"packages":packages})
|
||||
capture(label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new();clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42588)[&"valid"],"canonical current initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"own fresh evidence directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://tests/fixtures/legacy_staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived definition")
|
||||
for row: Array in [[&"warehouse",Vector3i(-6,0,1)],[&"service_stairs",Vector3i(-7,1,1)],[&"service_stairs",Vector3i(-7,2,1)],[&"service_stairs",Vector3i(-7,3,1)],[&"staff_dormitory",Vector3i(-6,2,1)],[&"reception",Vector3i(-6,0,0)],[&"guest_stairs",Vector3i(4,1,0)],[&"guest_stairs",Vector3i(4,2,0)],[&"guest_stairs",Vector3i(4,3,0)]]:
|
||||
if not command(&"build_facility",{&"definition_id":row[0],&"origin":row[1]}).is_success():
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Batch later refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures);return
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(row[0]).build_minutes)
|
||||
for instance: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if instance.definition_id==&"staff_dormitory":room_id=instance.instance_id
|
||||
expect(not room_id.is_empty(),"normally paid completed archived dormitory")
|
||||
if not command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)}).is_success():runtime.free();clock.free();state.free();quit(1);return
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid first-target partial job")
|
||||
if job_id.is_empty():runtime.free();clock.free();state.free();quit(1);return
|
||||
var baseline: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,baseline)[&"ok"],"formal old room baseline before real backup creation")
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
paths.erase("res://tests/fixtures/legacy_staff_dormitory.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"current approved footprint registry")
|
||||
var first: Dictionary=runtime.migrate_facility_dimensions_at_path(SLOT)
|
||||
expect(first.get(&"ok",false) and first.get(&"backup_created",false),"normal unconstrained two-target migration creates actual verified backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(baseline),"first migration leaves live original geometry")
|
||||
expect(var_to_bytes(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{}))==var_to_bytes(baseline),"actual backup exactly restores pre-migration baseline")
|
||||
write_proof("baseline.var",baseline)
|
||||
expect(command(&"register_staff",{&"staff_id":&"batch_maintainer",&"role_id":&"porter",&"options":{&"current_cell":Vector3i(-7,1,1),&"state":StaffRuntime.State.AVAILABLE}}).is_success(),"public worker for actual old-entry task")
|
||||
expect(runtime.staff_service.create_task(&"maintenance",10,clock.absolute_minute,{&"target_entity_id":room_id,&"target_cell":OLD_TARGET,&"estimated_minutes":30},&"batch_old_entry_task").is_success(),"public actual old-entry maintenance task")
|
||||
expect(runtime.staff_service.assign_task_to_staff(&"batch_old_entry_task",&"batch_maintainer",clock.absolute_minute).is_success(),"public real task owner assignment")
|
||||
clock.advance_minutes(1)
|
||||
var task: StaffTask=runtime.staff_service.get_task(&"batch_old_entry_task")
|
||||
expect(not task.is_terminal() and task.assigned_staff_id==&"batch_maintainer" and runtime.staff_service.get_staff(&"batch_maintainer").current_task_id==task.task_id,"real old-entry work remains in flight at formal save")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(SLOT,legacy)[&"ok"],"formal original includes partial job and real upper-entry task")
|
||||
write_proof("legacy.var",legacy);write_proof("identity.var",{&"room_id":room_id,&"serial":serial,&"job_id":job_id,&"task_id":&"batch_old_entry_task"})
|
||||
copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("original/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current approved footprint registry")
|
||||
var identity: Dictionary=read_proof("identity.var");room_id=identity[&"room_id"];job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("original/formal"),ProjectSettings.globalize_path(SLOT))
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT+SaveService.MIGRATION_BACKUP_SUFFIX).get(&"snapshot",{})),"separate PID restores real earlier backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("baseline.var")),"whole earlier backup state matches")
|
||||
expect(runtime.restore_snapshot(SaveService.load_snapshot(SLOT).get(&"snapshot",{})),"actual original batch-source package restores")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole original batch source restored exactly")
|
||||
capture("checkpoint");refusal("reject1");refusal("reject2")
|
||||
if MODE=="write":copy_package(ProjectSettings.globalize_path(SLOT),PAIR_ROOT.path_join("after-refusal/formal"))
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.refusal.uncapped",Callable(self,"observe")),"whole uncapped post-refusal journal")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
expect(runtime.facility_service.get_instance(room_id).occupied_cells.size()==8,"later rejected dorm retains entire original footprint")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==6,"earlier rolled-back job completes with its original legacy footprint")
|
||||
expect(runtime.staff_service.get_task(&"batch_old_entry_task").state==StaffTask.State.COMPLETED and runtime.staff_service.get_staff(&"batch_maintainer").current_cell==OLD_TARGET and runtime.staff_service.get_staff(&"batch_maintainer").current_task_id.is_empty(),"actual original maintenance reaches old entry and finishes without orphan work")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"post-refusal continuation remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"entire post-refusal journal matches without deletion or replacement")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Batch later refusal formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import hashlib,importlib.util,json,sys,os
|
||||
sys.dont_write_bytecode=True
|
||||
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';P=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-batch-later-refusal-prep-r02')
|
||||
TEST='tests/s3/test_runtime_staff_assignment.gd'
|
||||
READER='tests/s6/test_runtime_snapshot_serialization.gd'
|
||||
def module(n,p):
|
||||
s=importlib.util.spec_from_file_location(n,p);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
|
||||
def main():
|
||||
assert len(sys.argv)==2
|
||||
mode='formal-cross-pid';out=Path(sys.argv[1]);assert out.parent==A and not out.exists() and str(out)==json.loads((P/'preparation.json').read_bytes())['planned_output']
|
||||
r=module('role_formal_literal_runner',R/'tools/run_all_tests.py')
|
||||
seal=r.read(P/'input-seal.json')
|
||||
assert set(str(p.relative_to(P)) for p in P.rglob('*') if p.is_file())==set(seal['files'])|{'input-seal.json','preparation.json'}
|
||||
for n,v in seal['files'].items():assert Path(v['path'])==P/n and r.sha(v['path'])==v['sha256'] and Path(v['path']).stat().st_size==v['bytes']
|
||||
for name in ['writer.gd','reader.gd']:
|
||||
lines=(P/name).read_text().splitlines();bindings=[line[len('const PAIR_ROOT := '):]for line in lines if line.startswith('const PAIR_ROOT := ')]
|
||||
assert len(bindings)==1 and json.loads(bindings[0])==str(out/'migration-pair') and not (out/'migration-pair').exists()
|
||||
root_before=r.source_refs(R);assert len(root_before)==1299
|
||||
adopted=r.read(A/'p03-current1299-defense-empty-two-ref-source-adoption-r01/source-after.json')
|
||||
assert {n:v['sha256']for n,v in root_before.items()}==adopted
|
||||
refs=dict(root_before);refs[TEST]=seal['files']['writer.gd'];refs[READER]=seal['files']['reader.gd']
|
||||
for n,v in refs.items():assert Path(v['path']).stat().st_size==v['bytes'] and r.sha(v['path'])==v['sha256']
|
||||
docs={n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in ('IMPLEMENTATION_PLAN.md','PROGRESS_INTEGRATION.md','work_packages.json','progress_snapshot.json')}
|
||||
outer=module('bath_literal_owned_outer',r.SUPPORT/'owned_outer.py');assert not outer.native.helper['live_engines']()
|
||||
engine='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
out.mkdir();stage=out/'stage';stage.mkdir();(out/'starters').mkdir();(out/'bootstrap').mkdir()
|
||||
for n,v in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data=v['text'].encode();assert hashlib.sha256(data).hexdigest()==v['sha256'];(out/'bootstrap'/n).write_bytes(data)
|
||||
protected=r.default_player(R);expected={n:{'bytes':v['bytes'],'sha256':v['sha256']}for n,v in refs.items()}
|
||||
selected={'root_before':root_before,'map':{n:v['sha256']for n,v in refs.items()},'timeout':180}
|
||||
for n,v in refs.items():
|
||||
p=stage/n;p.parent.mkdir(parents=True,exist_ok=True);r.copy_source(Path(v['path']),p)
|
||||
assert r.inventory(stage,stage=True)==expected
|
||||
public=(stage/'project.godot').read_bytes();paths=['res://'+n for n in sorted(refs) if n.endswith('.gd')];r.write(out/'parse-paths.json',paths)
|
||||
markers=module('bath_literal_markers',R/'tools/strict_test_markers.py')
|
||||
contracts=markers.load_contracts(R/'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json')
|
||||
contracts[TEST]={'test':TEST,'template':'Batch later refusal formal write: <checks> checks, <failures> failures','required':True}
|
||||
contracts[READER]={'test':READER,'template':'Batch later refusal formal read: <checks> checks, <failures> failures','required':True}
|
||||
policy=r.read(r.SUPPORT/'suite-policy.json');assert TEST not in policy['suite_policies'] and READER not in policy['suite_policies']
|
||||
r.write(out/'runner-input.json',{'mode':mode,'owner_pid':os.getpid(),'wrapper_sha256':r.sha(__file__),'runner_sha256':r.sha(R/'tools/run_all_tests.py'),'selected_source_map':selected['map'],'source_before':root_before,'default_player':protected,'doc4_before':docs,'actual_full':False,'source_adoption':False})
|
||||
diagnostics=module('bath_literal_diagnostics',r.SUPPORT/'diagnostic_gate.py');owners=module('bath_literal_owners',r.SUPPORT/'ordinary_proof_gate.py');audio=module('bath_literal_audio',r.SUPPORT/'audio_evidence_gate.py')
|
||||
phases=[];previous={};error=None;formal_before=None
|
||||
try:
|
||||
for phase,test in [('import',None),('parse',None),('writer',TEST),('reader',READER)]:
|
||||
if phase=='writer':assert not (out/'migration-pair').exists()
|
||||
if phase=='reader':assert r.inventory(out/'migration-pair')==pair_before
|
||||
row=r.execute_phase(engine,stage,out,phase,test,selected,expected,previous,policy,contracts,paths,public,protected,R,outer,markers,diagnostics,owners,audio);phases.append(row)
|
||||
print(json.dumps({'phase':phase,'passed':row['passed'],'checks':row.get('reported_checks'),'error':row.get('validation_error'),'guard_error':row.get('guard_error')}),flush=True)
|
||||
r.require(row['passed'],'strict phase failure stops without retry')
|
||||
if phase=='writer':
|
||||
pair_before=r.inventory(out/'migration-pair');formal_before={n:v for n,v in pair_before.items()if '/formal/'in n}
|
||||
assert len(formal_before)==12
|
||||
r.write(out/'actual-formal-before-reader.json',formal_before)
|
||||
if phase=='reader':
|
||||
after=r.inventory(out/'migration-pair');assert {n:v for n,v in after.items()if '/formal/'in n}==formal_before
|
||||
assert all(after[n]==v for n,v in pair_before.items())
|
||||
r.write(out/'actual-formal-after-reader.json',{n:v for n,v in after.items()if '/formal/'in n})
|
||||
except BaseException as caught:error=type(caught).__name__+': '+str(caught)
|
||||
finally:cleanup,cleanup_errors=outer.finish_captured(outer.OWNED)
|
||||
passed=error is None and not cleanup_errors and len(phases)==4 and all(x['passed'] for x in phases) and all(x['engine_ended'] for x in cleanup)
|
||||
assert r.source_refs(R)==root_before and r.default_player(R)==protected
|
||||
assert {n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in docs}==docs
|
||||
assert r.inventory(stage,stage=True)==dict(expected,**previous)
|
||||
r.write(out/'runner-ended.json',{'mode':mode,'passed':passed,'phases':phases,'cleanup':cleanup,'cleanup_errors':cleanup_errors,'error':error,'whole_source_unchanged':True,'whole_default_profile_unchanged':True,'doc4_unchanged':True,'source_adoption':False,'normal_GUI_accepted':False,'full_regression_accepted':False,'formal_cross_PID_accepted':False,'actual_captured_PIDs':[p.pid for p in outer.OWNED],'actual_native_processes':len(outer.OWNED),'actual_checks':sum(p.get('reported_checks',0)for p in phases if p['test']) if passed else None,'formal_reader_evidence_scope':'headless direct formal later-target rejection and whole two-target rollback, actual paid partial premium job and completed old dorm with real assigned upper-entry task; real earlier backup unchanged and separate-PID whole continuation. Operations OFF public worker fixture, no Main OS or full migration acceptance','native_Windows_accepted':False,'whole_goal_accepted':False})
|
||||
print(json.dumps({'mode':mode,'passed':passed,'error':error,'actual_native':len(phases),'actual_checks':phases[-1].get('reported_checks') if phases else None}),flush=True)
|
||||
return 0 if passed else 1
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1,143 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-inflight-EV-dimension-native-r01/migration-pair"
|
||||
const MODE := "read"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var original_requests: Dictionary={}
|
||||
var arrivals: Dictionary={}
|
||||
var arrival_errors: Array[String]=[]
|
||||
const GOAL:=Vector3i(0,1,0)
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:
|
||||
journal.append(event.to_dictionary())
|
||||
if event.event_type==&"ELEVATOR_ARRIVED":
|
||||
var request_id: StringName=event.payload[&"request_id"]
|
||||
if not original_requests.has(request_id):arrival_errors.append("unexpected request")
|
||||
arrivals[request_id]=int(arrivals.get(request_id,0))+1
|
||||
if event.payload[&"cell"]!=GOAL or event.payload.get(&"emergency",false):arrival_errors.append("wrong arrival")
|
||||
func advance(minutes: int) -> void:
|
||||
for step: int in range(minutes):
|
||||
clock.advance_minutes(1)
|
||||
for guest: GuestRuntime in runtime.guest_service.get_guests():
|
||||
if guest.current_cell==GOAL:
|
||||
expect(runtime.guest_service.begin_leaving(guest.guest_id,clock.absolute_minute,&"P03_GOAL_REACHED").get(&"ok",false),"actual arrival begins normal departure")
|
||||
expect(runtime.guest_service.despawn_guest(guest.guest_id,clock.absolute_minute).get(&"ok",false),"actual completed passenger leaves normal lifecycle")
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
command(&"build_facility",{&"definition_id":&"guest_elevator",&"origin":Vector3i.ZERO})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_elevator").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
for index: int in range(5):
|
||||
command(&"spawn_guest",{&"guest_id":StringName("p03.inflight.passenger.%d"%index),&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i.ZERO,&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"path_handle":{&"target_cell":GOAL}}})
|
||||
clock.advance_minutes(2)
|
||||
var car: Dictionary=runtime.elevators.get_report()[&"shafts"][0]
|
||||
expect(car[&"phase"]==&"BOARDING" and car[&"passenger_count"]==4 and car[&"waiting_count"]==1,"actual four boarded passengers and one queued passenger at save")
|
||||
expect(runtime.path_service.get_current_density(Vector3i.ZERO)==1 and runtime.path_service.get_transit_actor_ids().size()==4,"real cabin seats excluded from floor density")
|
||||
for trip: Dictionary in runtime.elevators.get_report()[&"trips"]:original_requests[trip[&"request_id"]]=trip[&"actor_id"]
|
||||
expect(original_requests.size()==5,"all five actual request IDs saved")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial,&"original_requests":original_requests})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"];original_requests=identity[&"original_requests"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
advance(1);capture("next1")
|
||||
advance(1);capture("next2")
|
||||
advance(8);capture("next10")
|
||||
advance(150);capture("final160")
|
||||
var exactly_once:=arrivals.size()==5 and arrival_errors.is_empty()
|
||||
for request_id: StringName in original_requests:exactly_once=exactly_once and arrivals.get(request_id,0)==1
|
||||
expect(exactly_once,"all five migrated actual EV request IDs arrive exactly once without emergency")
|
||||
expect(runtime.guest_service.get_guests().is_empty() and runtime.elevators.get_report()[&"trips"].is_empty() and runtime.path_service.get_transit_actor_ids().is_empty(),"no orphan passenger seat trip or path transit after actual arrivals")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Inflight EV dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,143 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-inflight-EV-dimension-native-r01/migration-pair"
|
||||
const MODE := "write"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var original_requests: Dictionary={}
|
||||
var arrivals: Dictionary={}
|
||||
var arrival_errors: Array[String]=[]
|
||||
const GOAL:=Vector3i(0,1,0)
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:
|
||||
journal.append(event.to_dictionary())
|
||||
if event.event_type==&"ELEVATOR_ARRIVED":
|
||||
var request_id: StringName=event.payload[&"request_id"]
|
||||
if not original_requests.has(request_id):arrival_errors.append("unexpected request")
|
||||
arrivals[request_id]=int(arrivals.get(request_id,0))+1
|
||||
if event.payload[&"cell"]!=GOAL or event.payload.get(&"emergency",false):arrival_errors.append("wrong arrival")
|
||||
func advance(minutes: int) -> void:
|
||||
for step: int in range(minutes):
|
||||
clock.advance_minutes(1)
|
||||
for guest: GuestRuntime in runtime.guest_service.get_guests():
|
||||
if guest.current_cell==GOAL:
|
||||
expect(runtime.guest_service.begin_leaving(guest.guest_id,clock.absolute_minute,&"P03_GOAL_REACHED").get(&"ok",false),"actual arrival begins normal departure")
|
||||
expect(runtime.guest_service.despawn_guest(guest.guest_id,clock.absolute_minute).get(&"ok",false),"actual completed passenger leaves normal lifecycle")
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
command(&"build_facility",{&"definition_id":&"guest_elevator",&"origin":Vector3i.ZERO})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_elevator").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
for index: int in range(5):
|
||||
command(&"spawn_guest",{&"guest_id":StringName("p03.inflight.passenger.%d"%index),&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i.ZERO,&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"path_handle":{&"target_cell":GOAL}}})
|
||||
clock.advance_minutes(2)
|
||||
var car: Dictionary=runtime.elevators.get_report()[&"shafts"][0]
|
||||
expect(car[&"phase"]==&"BOARDING" and car[&"passenger_count"]==4 and car[&"waiting_count"]==1,"actual four boarded passengers and one queued passenger at save")
|
||||
expect(runtime.path_service.get_current_density(Vector3i.ZERO)==1 and runtime.path_service.get_transit_actor_ids().size()==4,"real cabin seats excluded from floor density")
|
||||
for trip: Dictionary in runtime.elevators.get_report()[&"trips"]:original_requests[trip[&"request_id"]]=trip[&"actor_id"]
|
||||
expect(original_requests.size()==5,"all five actual request IDs saved")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial,&"original_requests":original_requests})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"];original_requests=identity[&"original_requests"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
advance(1);capture("next1")
|
||||
advance(1);capture("next2")
|
||||
advance(8);capture("next10")
|
||||
advance(150);capture("final160")
|
||||
var exactly_once:=arrivals.size()==5 and arrival_errors.is_empty()
|
||||
for request_id: StringName in original_requests:exactly_once=exactly_once and arrivals.get(request_id,0)==1
|
||||
expect(exactly_once,"all five migrated actual EV request IDs arrive exactly once without emergency")
|
||||
expect(runtime.guest_service.get_guests().is_empty() and runtime.elevators.get_report()[&"trips"].is_empty() and runtime.path_service.get_transit_actor_ids().is_empty(),"no orphan passenger seat trip or path transit after actual arrivals")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Inflight EV dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import hashlib,importlib.util,json,sys,os
|
||||
sys.dont_write_bytecode=True
|
||||
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';P=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-inflight-EV-dimension-prep-r01')
|
||||
TEST='tests/s3/test_runtime_staff_assignment.gd'
|
||||
READER='tests/s6/test_runtime_snapshot_serialization.gd'
|
||||
def module(n,p):
|
||||
s=importlib.util.spec_from_file_location(n,p);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
|
||||
def main():
|
||||
assert len(sys.argv)==2
|
||||
mode='formal-cross-pid';out=Path(sys.argv[1]);assert out.parent==A and not out.exists() and str(out)==json.loads((P/'preparation.json').read_bytes())['planned_output']
|
||||
r=module('role_formal_literal_runner',R/'tools/run_all_tests.py')
|
||||
seal=r.read(P/'input-seal.json')
|
||||
assert set(str(p.relative_to(P)) for p in P.rglob('*') if p.is_file())==set(seal['files'])|{'input-seal.json','preparation.json'}
|
||||
for n,v in seal['files'].items():assert Path(v['path'])==P/n and r.sha(v['path'])==v['sha256'] and Path(v['path']).stat().st_size==v['bytes']
|
||||
for name in ['writer.gd','reader.gd']:
|
||||
lines=(P/name).read_text().splitlines();bindings=[line[len('const PAIR_ROOT := '):]for line in lines if line.startswith('const PAIR_ROOT := ')]
|
||||
assert len(bindings)==1 and json.loads(bindings[0])==str(out/'migration-pair') and not (out/'migration-pair').exists()
|
||||
root_before=r.source_refs(R);assert len(root_before)==1299
|
||||
adopted=r.read(A/'p03-current1299-defense-empty-two-ref-source-adoption-r01/source-after.json')
|
||||
assert {n:v['sha256']for n,v in root_before.items()}==adopted
|
||||
refs=dict(root_before);refs[TEST]=seal['files']['writer.gd'];refs[READER]=seal['files']['reader.gd']
|
||||
for n,v in refs.items():assert Path(v['path']).stat().st_size==v['bytes'] and r.sha(v['path'])==v['sha256']
|
||||
docs={n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in ('IMPLEMENTATION_PLAN.md','PROGRESS_INTEGRATION.md','work_packages.json','progress_snapshot.json')}
|
||||
outer=module('bath_literal_owned_outer',r.SUPPORT/'owned_outer.py');assert not outer.native.helper['live_engines']()
|
||||
engine='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
out.mkdir();stage=out/'stage';stage.mkdir();(out/'starters').mkdir();(out/'bootstrap').mkdir()
|
||||
for n,v in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data=v['text'].encode();assert hashlib.sha256(data).hexdigest()==v['sha256'];(out/'bootstrap'/n).write_bytes(data)
|
||||
protected=r.default_player(R);expected={n:{'bytes':v['bytes'],'sha256':v['sha256']}for n,v in refs.items()}
|
||||
selected={'root_before':root_before,'map':{n:v['sha256']for n,v in refs.items()},'timeout':180}
|
||||
for n,v in refs.items():
|
||||
p=stage/n;p.parent.mkdir(parents=True,exist_ok=True);r.copy_source(Path(v['path']),p)
|
||||
assert r.inventory(stage,stage=True)==expected
|
||||
public=(stage/'project.godot').read_bytes();paths=['res://'+n for n in sorted(refs) if n.endswith('.gd')];r.write(out/'parse-paths.json',paths)
|
||||
markers=module('bath_literal_markers',R/'tools/strict_test_markers.py')
|
||||
contracts=markers.load_contracts(R/'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json')
|
||||
contracts[TEST]={'test':TEST,'template':'Inflight EV dimension formal write: <checks> checks, <failures> failures','required':True}
|
||||
contracts[READER]={'test':READER,'template':'Inflight EV dimension formal read: <checks> checks, <failures> failures','required':True}
|
||||
policy=r.read(r.SUPPORT/'suite-policy.json');assert TEST not in policy['suite_policies'] and READER not in policy['suite_policies']
|
||||
r.write(out/'runner-input.json',{'mode':mode,'owner_pid':os.getpid(),'wrapper_sha256':r.sha(__file__),'runner_sha256':r.sha(R/'tools/run_all_tests.py'),'selected_source_map':selected['map'],'source_before':root_before,'default_player':protected,'doc4_before':docs,'actual_full':False,'source_adoption':False})
|
||||
diagnostics=module('bath_literal_diagnostics',r.SUPPORT/'diagnostic_gate.py');owners=module('bath_literal_owners',r.SUPPORT/'ordinary_proof_gate.py');audio=module('bath_literal_audio',r.SUPPORT/'audio_evidence_gate.py')
|
||||
phases=[];previous={};error=None;formal_before=None
|
||||
try:
|
||||
for phase,test in [('import',None),('parse',None),('writer',TEST),('reader',READER)]:
|
||||
if phase=='writer':assert not (out/'migration-pair').exists()
|
||||
if phase=='reader':assert r.inventory(out/'migration-pair')==pair_before
|
||||
row=r.execute_phase(engine,stage,out,phase,test,selected,expected,previous,policy,contracts,paths,public,protected,R,outer,markers,diagnostics,owners,audio);phases.append(row)
|
||||
print(json.dumps({'phase':phase,'passed':row['passed'],'checks':row.get('reported_checks'),'error':row.get('validation_error'),'guard_error':row.get('guard_error')}),flush=True)
|
||||
r.require(row['passed'],'strict phase failure stops without retry')
|
||||
if phase=='writer':
|
||||
pair_before=r.inventory(out/'migration-pair');formal_before={n:v for n,v in pair_before.items()if '/formal/'in n}
|
||||
assert len(formal_before)==12
|
||||
r.write(out/'actual-formal-before-reader.json',formal_before)
|
||||
if phase=='reader':
|
||||
after=r.inventory(out/'migration-pair');assert {n:v for n,v in after.items()if '/formal/'in n}==formal_before
|
||||
assert all(after[n]==v for n,v in pair_before.items())
|
||||
r.write(out/'actual-formal-after-reader.json',{n:v for n,v in after.items()if '/formal/'in n})
|
||||
except BaseException as caught:error=type(caught).__name__+': '+str(caught)
|
||||
finally:cleanup,cleanup_errors=outer.finish_captured(outer.OWNED)
|
||||
passed=error is None and not cleanup_errors and len(phases)==4 and all(x['passed'] for x in phases) and all(x['engine_ended'] for x in cleanup)
|
||||
assert r.source_refs(R)==root_before and r.default_player(R)==protected
|
||||
assert {n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in docs}==docs
|
||||
assert r.inventory(stage,stage=True)==dict(expected,**previous)
|
||||
r.write(out/'runner-ended.json',{'mode':mode,'passed':passed,'phases':phases,'cleanup':cleanup,'cleanup_errors':cleanup_errors,'error':error,'whole_source_unchanged':True,'whole_default_profile_unchanged':True,'doc4_unchanged':True,'source_adoption':False,'normal_GUI_accepted':False,'full_regression_accepted':False,'formal_cross_PID_accepted':False,'actual_captured_PIDs':[p.pid for p in outer.OWNED],'actual_native_processes':len(outer.OWNED),'actual_checks':sum(p.get('reported_checks',0)for p in phases if p['test']) if passed else None,'formal_reader_evidence_scope':'headless direct formal legacy-dimension migration with four actual boarded passengers and one queued passenger plus paid concurrent construction; separate-PID original backup and migrated full continuation; Operations OFF public guest inputs; changed destination rejection, Main OS input, rescue/logistics and whole migration remain unaccepted','native_Windows_accepted':False,'whole_goal_accepted':False})
|
||||
print(json.dumps({'mode':mode,'passed':passed,'error':error,'actual_native':len(phases),'actual_checks':phases[-1].get('reported_checks')}),flush=True)
|
||||
return 0 if passed else 1
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1,121 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-inflight-dimension-native-r01/migration-pair"
|
||||
const MODE := "read"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
command(&"spawn_guest",{&"guest_id":&"p03.inflight.guest",&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i(4,0,0),&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"path_handle":{&"target_cell":Vector3i(4,3,0)}}})
|
||||
clock.advance_minutes(1)
|
||||
var guest: GuestRuntime=runtime.guest_service.get_guest(&"p03.inflight.guest")
|
||||
expect(guest!=null and guest.current_cell==Vector3i(4,0,0) and guest.state==GuestRuntime.State.MOVING,"actual partial staircase travel at save time")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
expect(legacy[&"systems"][&"runtime"][&"movement_credits"].size()==1 and legacy[&"systems"][&"runtime"][&"movement_credits"][0][&"credit"]==1000,"actual fractional movement credit saved")
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(runtime.guest_service.get_guest(&"p03.inflight.guest").current_cell==Vector3i(4,1,0),"real half-step finishes exactly once after migration")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Inflight dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,121 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-inflight-dimension-native-r01/migration-pair"
|
||||
const MODE := "write"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
command(&"spawn_guest",{&"guest_id":&"p03.inflight.guest",&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i(4,0,0),&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"path_handle":{&"target_cell":Vector3i(4,3,0)}}})
|
||||
clock.advance_minutes(1)
|
||||
var guest: GuestRuntime=runtime.guest_service.get_guest(&"p03.inflight.guest")
|
||||
expect(guest!=null and guest.current_cell==Vector3i(4,0,0) and guest.state==GuestRuntime.State.MOVING,"actual partial staircase travel at save time")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
expect(legacy[&"systems"][&"runtime"][&"movement_credits"].size()==1 and legacy[&"systems"][&"runtime"][&"movement_credits"][0][&"credit"]==1000,"actual fractional movement credit saved")
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(runtime.guest_service.get_guest(&"p03.inflight.guest").current_cell==Vector3i(4,1,0),"real half-step finishes exactly once after migration")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Inflight dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import hashlib,importlib.util,json,sys,os
|
||||
sys.dont_write_bytecode=True
|
||||
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';P=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-inflight-dimension-prep-r01')
|
||||
TEST='tests/s3/test_runtime_staff_assignment.gd'
|
||||
READER='tests/s6/test_runtime_snapshot_serialization.gd'
|
||||
def module(n,p):
|
||||
s=importlib.util.spec_from_file_location(n,p);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
|
||||
def main():
|
||||
assert len(sys.argv)==2
|
||||
mode='formal-cross-pid';out=Path(sys.argv[1]);assert out.parent==A and not out.exists() and str(out)==json.loads((P/'preparation.json').read_bytes())['planned_output']
|
||||
r=module('role_formal_literal_runner',R/'tools/run_all_tests.py')
|
||||
seal=r.read(P/'input-seal.json')
|
||||
assert set(str(p.relative_to(P)) for p in P.rglob('*') if p.is_file())==set(seal['files'])|{'input-seal.json','preparation.json'}
|
||||
for n,v in seal['files'].items():assert Path(v['path'])==P/n and r.sha(v['path'])==v['sha256'] and Path(v['path']).stat().st_size==v['bytes']
|
||||
for name in ['writer.gd','reader.gd']:
|
||||
lines=(P/name).read_text().splitlines();bindings=[line[len('const PAIR_ROOT := '):]for line in lines if line.startswith('const PAIR_ROOT := ')]
|
||||
assert len(bindings)==1 and json.loads(bindings[0])==str(out/'migration-pair') and not (out/'migration-pair').exists()
|
||||
root_before=r.source_refs(R);assert len(root_before)==1299
|
||||
adopted=r.read(A/'p03-current1299-defense-empty-two-ref-source-adoption-r01/source-after.json')
|
||||
assert {n:v['sha256']for n,v in root_before.items()}==adopted
|
||||
refs=dict(root_before);refs[TEST]=seal['files']['writer.gd'];refs[READER]=seal['files']['reader.gd']
|
||||
for n,v in refs.items():assert Path(v['path']).stat().st_size==v['bytes'] and r.sha(v['path'])==v['sha256']
|
||||
docs={n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in ('IMPLEMENTATION_PLAN.md','PROGRESS_INTEGRATION.md','work_packages.json','progress_snapshot.json')}
|
||||
outer=module('bath_literal_owned_outer',r.SUPPORT/'owned_outer.py');assert not outer.native.helper['live_engines']()
|
||||
engine='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
out.mkdir();stage=out/'stage';stage.mkdir();(out/'starters').mkdir();(out/'bootstrap').mkdir()
|
||||
for n,v in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data=v['text'].encode();assert hashlib.sha256(data).hexdigest()==v['sha256'];(out/'bootstrap'/n).write_bytes(data)
|
||||
protected=r.default_player(R);expected={n:{'bytes':v['bytes'],'sha256':v['sha256']}for n,v in refs.items()}
|
||||
selected={'root_before':root_before,'map':{n:v['sha256']for n,v in refs.items()},'timeout':180}
|
||||
for n,v in refs.items():
|
||||
p=stage/n;p.parent.mkdir(parents=True,exist_ok=True);r.copy_source(Path(v['path']),p)
|
||||
assert r.inventory(stage,stage=True)==expected
|
||||
public=(stage/'project.godot').read_bytes();paths=['res://'+n for n in sorted(refs) if n.endswith('.gd')];r.write(out/'parse-paths.json',paths)
|
||||
markers=module('bath_literal_markers',R/'tools/strict_test_markers.py')
|
||||
contracts=markers.load_contracts(R/'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json')
|
||||
contracts[TEST]={'test':TEST,'template':'Inflight dimension formal write: <checks> checks, <failures> failures','required':True}
|
||||
contracts[READER]={'test':READER,'template':'Inflight dimension formal read: <checks> checks, <failures> failures','required':True}
|
||||
policy=r.read(r.SUPPORT/'suite-policy.json');assert TEST not in policy['suite_policies'] and READER not in policy['suite_policies']
|
||||
r.write(out/'runner-input.json',{'mode':mode,'owner_pid':os.getpid(),'wrapper_sha256':r.sha(__file__),'runner_sha256':r.sha(R/'tools/run_all_tests.py'),'selected_source_map':selected['map'],'source_before':root_before,'default_player':protected,'doc4_before':docs,'actual_full':False,'source_adoption':False})
|
||||
diagnostics=module('bath_literal_diagnostics',r.SUPPORT/'diagnostic_gate.py');owners=module('bath_literal_owners',r.SUPPORT/'ordinary_proof_gate.py');audio=module('bath_literal_audio',r.SUPPORT/'audio_evidence_gate.py')
|
||||
phases=[];previous={};error=None;formal_before=None
|
||||
try:
|
||||
for phase,test in [('import',None),('parse',None),('writer',TEST),('reader',READER)]:
|
||||
if phase=='writer':assert not (out/'migration-pair').exists()
|
||||
if phase=='reader':assert r.inventory(out/'migration-pair')==pair_before
|
||||
row=r.execute_phase(engine,stage,out,phase,test,selected,expected,previous,policy,contracts,paths,public,protected,R,outer,markers,diagnostics,owners,audio);phases.append(row)
|
||||
print(json.dumps({'phase':phase,'passed':row['passed'],'checks':row.get('reported_checks'),'error':row.get('validation_error'),'guard_error':row.get('guard_error')}),flush=True)
|
||||
r.require(row['passed'],'strict phase failure stops without retry')
|
||||
if phase=='writer':
|
||||
pair_before=r.inventory(out/'migration-pair');formal_before={n:v for n,v in pair_before.items()if '/formal/'in n}
|
||||
assert len(formal_before)==12
|
||||
r.write(out/'actual-formal-before-reader.json',formal_before)
|
||||
if phase=='reader':
|
||||
after=r.inventory(out/'migration-pair');assert {n:v for n,v in after.items()if '/formal/'in n}==formal_before
|
||||
assert all(after[n]==v for n,v in pair_before.items())
|
||||
r.write(out/'actual-formal-after-reader.json',{n:v for n,v in after.items()if '/formal/'in n})
|
||||
except BaseException as caught:error=type(caught).__name__+': '+str(caught)
|
||||
finally:cleanup,cleanup_errors=outer.finish_captured(outer.OWNED)
|
||||
passed=error is None and not cleanup_errors and len(phases)==4 and all(x['passed'] for x in phases) and all(x['engine_ended'] for x in cleanup)
|
||||
assert r.source_refs(R)==root_before and r.default_player(R)==protected
|
||||
assert {n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in docs}==docs
|
||||
assert r.inventory(stage,stage=True)==dict(expected,**previous)
|
||||
r.write(out/'runner-ended.json',{'mode':mode,'passed':passed,'phases':phases,'cleanup':cleanup,'cleanup_errors':cleanup_errors,'error':error,'whole_source_unchanged':True,'whole_default_profile_unchanged':True,'doc4_unchanged':True,'source_adoption':False,'normal_GUI_accepted':False,'full_regression_accepted':False,'formal_cross_PID_accepted':False,'actual_captured_PIDs':[p.pid for p in outer.OWNED],'actual_native_processes':len(outer.OWNED),'actual_checks':sum(p.get('reported_checks',0)for p in phases if p['test']) if passed else None,'formal_reader_evidence_scope':'headless direct formal legacy-dimension migration, real paid concurrent construction and fractional guest stair travel; separate-PID original backup and migrated continuation; Operations OFF controlled guest input, no Main OS input, rescue/logistics/occupied EV/whole original acceptance','native_Windows_accepted':False,'whole_goal_accepted':False})
|
||||
print(json.dumps({'mode':mode,'passed':passed,'error':error,'actual_native':len(phases),'actual_checks':phases[-1].get('reported_checks')}),flush=True)
|
||||
return 0 if passed else 1
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1,151 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-logistics-dimension-native-r02/migration-pair"
|
||||
const MODE := "read"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
if not result.is_success():runtime.free();clock.free();state.free();quit(1)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
for row: Array in [[&"warehouse",Vector3i(-8,0,1)],[&"kitchen",Vector3i(2,0,1)],[&"staff_door",Vector3i(0,0,1)]]:
|
||||
command(&"build_facility",{&"definition_id":row[0],&"origin":row[1]})
|
||||
clock.advance_minutes(180)
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
if job_id.is_empty():runtime.free();clock.free();state.free();quit(1);return
|
||||
var warehouse: FacilityInstance
|
||||
var kitchen: FacilityInstance
|
||||
for room: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if room.definition_id==&"warehouse":warehouse=room
|
||||
if room.definition_id==&"kitchen":kitchen=room
|
||||
expect(warehouse!=null and kitchen!=null,"real paid supply endpoints completed")
|
||||
if warehouse==null or kitchen==null:runtime.free();clock.free();state.free();quit(1);return
|
||||
command(&"hire_staff_candidate",{&"candidate_id":&"staff_gina"})
|
||||
command(&"set_staff_work_assignment",{&"staff_id":&"staff_gina",&"facility_id":warehouse.instance_id,&"template_id":&"DAY"})
|
||||
command(&"purchase_supplies",{&"warehouse_id":warehouse.instance_id,&"item_id":SupplyCatalog.RAW_FOOD,&"quantity":8})
|
||||
command(&"set_kitchen_production",{&"facility_id":kitchen.instance_id,&"enabled":true,&"target_stock":4})
|
||||
var loaded:=false
|
||||
for minute: int in range(60):
|
||||
clock.advance_minutes(1)
|
||||
var worker: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
||||
if not worker.carried_inventory_id.is_empty():loaded=true;break
|
||||
expect(loaded,"normally hired porter actually picks up purchased cargo")
|
||||
if not loaded:runtime.free();clock.free();state.free();quit(1);return
|
||||
var porter: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
||||
expect(runtime.inventory_service.total_quantity(porter.carried_inventory_id,SupplyCatalog.RAW_FOOD)==4,"actual cargo contains four paid food units from an eight-unit purchase")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(SupplyLogisticsBridge.validate_crosslinks(runtime.logistics_requests,runtime.staff_service,runtime.inventory_service,runtime.facility_service),"actual cargo crosslinks after first continued minute")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
var porter: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
||||
var delivered:=0
|
||||
for request: LogisticsRequest in runtime.logistics_requests.values():
|
||||
if request.state==LogisticsRequest.State.COMPLETED and request.item_requirements.has(SupplyCatalog.RAW_FOOD):delivered+=1
|
||||
expect(delivered==2 and porter.carried_inventory_id.is_empty(),"two real four-unit shipments complete and releases porter cargo")
|
||||
var kitchen: FacilityInstance
|
||||
for room: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if room.definition_id==&"kitchen":kitchen=room
|
||||
expect(kitchen!=null and runtime.inventory_service.total_quantity(kitchen.local_inventory_id,SupplyCatalog.RAW_FOOD)==8,"all eight purchased units actually arrive at kitchen")
|
||||
expect(SupplyLogisticsBridge.validate_crosslinks(runtime.logistics_requests,runtime.staff_service,runtime.inventory_service,runtime.facility_service),"all final physical cargo ownership crosslinks valid")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Logistics dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,151 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-logistics-dimension-native-r02/migration-pair"
|
||||
const MODE := "write"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
if not result.is_success():runtime.free();clock.free();state.free();quit(1)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
for row: Array in [[&"warehouse",Vector3i(-8,0,1)],[&"kitchen",Vector3i(2,0,1)],[&"staff_door",Vector3i(0,0,1)]]:
|
||||
command(&"build_facility",{&"definition_id":row[0],&"origin":row[1]})
|
||||
clock.advance_minutes(180)
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
if job_id.is_empty():runtime.free();clock.free();state.free();quit(1);return
|
||||
var warehouse: FacilityInstance
|
||||
var kitchen: FacilityInstance
|
||||
for room: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if room.definition_id==&"warehouse":warehouse=room
|
||||
if room.definition_id==&"kitchen":kitchen=room
|
||||
expect(warehouse!=null and kitchen!=null,"real paid supply endpoints completed")
|
||||
if warehouse==null or kitchen==null:runtime.free();clock.free();state.free();quit(1);return
|
||||
command(&"hire_staff_candidate",{&"candidate_id":&"staff_gina"})
|
||||
command(&"set_staff_work_assignment",{&"staff_id":&"staff_gina",&"facility_id":warehouse.instance_id,&"template_id":&"DAY"})
|
||||
command(&"purchase_supplies",{&"warehouse_id":warehouse.instance_id,&"item_id":SupplyCatalog.RAW_FOOD,&"quantity":8})
|
||||
command(&"set_kitchen_production",{&"facility_id":kitchen.instance_id,&"enabled":true,&"target_stock":4})
|
||||
var loaded:=false
|
||||
for minute: int in range(60):
|
||||
clock.advance_minutes(1)
|
||||
var worker: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
||||
if not worker.carried_inventory_id.is_empty():loaded=true;break
|
||||
expect(loaded,"normally hired porter actually picks up purchased cargo")
|
||||
if not loaded:runtime.free();clock.free();state.free();quit(1);return
|
||||
var porter: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
||||
expect(runtime.inventory_service.total_quantity(porter.carried_inventory_id,SupplyCatalog.RAW_FOOD)==4,"actual cargo contains four paid food units from an eight-unit purchase")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(SupplyLogisticsBridge.validate_crosslinks(runtime.logistics_requests,runtime.staff_service,runtime.inventory_service,runtime.facility_service),"actual cargo crosslinks after first continued minute")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
var porter: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
||||
var delivered:=0
|
||||
for request: LogisticsRequest in runtime.logistics_requests.values():
|
||||
if request.state==LogisticsRequest.State.COMPLETED and request.item_requirements.has(SupplyCatalog.RAW_FOOD):delivered+=1
|
||||
expect(delivered==2 and porter.carried_inventory_id.is_empty(),"two real four-unit shipments complete and releases porter cargo")
|
||||
var kitchen: FacilityInstance
|
||||
for room: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if room.definition_id==&"kitchen":kitchen=room
|
||||
expect(kitchen!=null and runtime.inventory_service.total_quantity(kitchen.local_inventory_id,SupplyCatalog.RAW_FOOD)==8,"all eight purchased units actually arrive at kitchen")
|
||||
expect(SupplyLogisticsBridge.validate_crosslinks(runtime.logistics_requests,runtime.staff_service,runtime.inventory_service,runtime.facility_service),"all final physical cargo ownership crosslinks valid")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Logistics dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import hashlib,importlib.util,json,sys,os
|
||||
sys.dont_write_bytecode=True
|
||||
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';P=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-logistics-dimension-prep-r02')
|
||||
TEST='tests/s3/test_runtime_staff_assignment.gd'
|
||||
READER='tests/s6/test_runtime_snapshot_serialization.gd'
|
||||
def module(n,p):
|
||||
s=importlib.util.spec_from_file_location(n,p);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
|
||||
def main():
|
||||
assert len(sys.argv)==2
|
||||
mode='formal-cross-pid';out=Path(sys.argv[1]);assert out.parent==A and not out.exists() and str(out)==json.loads((P/'preparation.json').read_bytes())['planned_output']
|
||||
r=module('role_formal_literal_runner',R/'tools/run_all_tests.py')
|
||||
seal=r.read(P/'input-seal.json')
|
||||
assert set(str(p.relative_to(P)) for p in P.rglob('*') if p.is_file())==set(seal['files'])|{'input-seal.json','preparation.json'}
|
||||
for n,v in seal['files'].items():assert Path(v['path'])==P/n and r.sha(v['path'])==v['sha256'] and Path(v['path']).stat().st_size==v['bytes']
|
||||
for name in ['writer.gd','reader.gd']:
|
||||
lines=(P/name).read_text().splitlines();bindings=[line[len('const PAIR_ROOT := '):]for line in lines if line.startswith('const PAIR_ROOT := ')]
|
||||
assert len(bindings)==1 and json.loads(bindings[0])==str(out/'migration-pair') and not (out/'migration-pair').exists()
|
||||
root_before=r.source_refs(R);assert len(root_before)==1299
|
||||
adopted=r.read(A/'p03-current1299-defense-empty-two-ref-source-adoption-r01/source-after.json')
|
||||
assert {n:v['sha256']for n,v in root_before.items()}==adopted
|
||||
refs=dict(root_before);refs[TEST]=seal['files']['writer.gd'];refs[READER]=seal['files']['reader.gd']
|
||||
for n,v in refs.items():assert Path(v['path']).stat().st_size==v['bytes'] and r.sha(v['path'])==v['sha256']
|
||||
docs={n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in ('IMPLEMENTATION_PLAN.md','PROGRESS_INTEGRATION.md','work_packages.json','progress_snapshot.json')}
|
||||
outer=module('bath_literal_owned_outer',r.SUPPORT/'owned_outer.py');assert not outer.native.helper['live_engines']()
|
||||
engine='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
out.mkdir();stage=out/'stage';stage.mkdir();(out/'starters').mkdir();(out/'bootstrap').mkdir()
|
||||
for n,v in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data=v['text'].encode();assert hashlib.sha256(data).hexdigest()==v['sha256'];(out/'bootstrap'/n).write_bytes(data)
|
||||
protected=r.default_player(R);expected={n:{'bytes':v['bytes'],'sha256':v['sha256']}for n,v in refs.items()}
|
||||
selected={'root_before':root_before,'map':{n:v['sha256']for n,v in refs.items()},'timeout':180}
|
||||
for n,v in refs.items():
|
||||
p=stage/n;p.parent.mkdir(parents=True,exist_ok=True);r.copy_source(Path(v['path']),p)
|
||||
assert r.inventory(stage,stage=True)==expected
|
||||
public=(stage/'project.godot').read_bytes();paths=['res://'+n for n in sorted(refs) if n.endswith('.gd')];r.write(out/'parse-paths.json',paths)
|
||||
markers=module('bath_literal_markers',R/'tools/strict_test_markers.py')
|
||||
contracts=markers.load_contracts(R/'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json')
|
||||
contracts[TEST]={'test':TEST,'template':'Logistics dimension formal write: <checks> checks, <failures> failures','required':True}
|
||||
contracts[READER]={'test':READER,'template':'Logistics dimension formal read: <checks> checks, <failures> failures','required':True}
|
||||
policy=r.read(r.SUPPORT/'suite-policy.json');assert TEST not in policy['suite_policies'] and READER not in policy['suite_policies']
|
||||
r.write(out/'runner-input.json',{'mode':mode,'owner_pid':os.getpid(),'wrapper_sha256':r.sha(__file__),'runner_sha256':r.sha(R/'tools/run_all_tests.py'),'selected_source_map':selected['map'],'source_before':root_before,'default_player':protected,'doc4_before':docs,'actual_full':False,'source_adoption':False})
|
||||
diagnostics=module('bath_literal_diagnostics',r.SUPPORT/'diagnostic_gate.py');owners=module('bath_literal_owners',r.SUPPORT/'ordinary_proof_gate.py');audio=module('bath_literal_audio',r.SUPPORT/'audio_evidence_gate.py')
|
||||
phases=[];previous={};error=None;formal_before=None
|
||||
try:
|
||||
for phase,test in [('import',None),('parse',None),('writer',TEST),('reader',READER)]:
|
||||
if phase=='writer':assert not (out/'migration-pair').exists()
|
||||
if phase=='reader':assert r.inventory(out/'migration-pair')==pair_before
|
||||
row=r.execute_phase(engine,stage,out,phase,test,selected,expected,previous,policy,contracts,paths,public,protected,R,outer,markers,diagnostics,owners,audio);phases.append(row)
|
||||
print(json.dumps({'phase':phase,'passed':row['passed'],'checks':row.get('reported_checks'),'error':row.get('validation_error'),'guard_error':row.get('guard_error')}),flush=True)
|
||||
r.require(row['passed'],'strict phase failure stops without retry')
|
||||
if phase=='writer':
|
||||
pair_before=r.inventory(out/'migration-pair');formal_before={n:v for n,v in pair_before.items()if '/formal/'in n}
|
||||
assert len(formal_before)==12
|
||||
r.write(out/'actual-formal-before-reader.json',formal_before)
|
||||
if phase=='reader':
|
||||
after=r.inventory(out/'migration-pair');assert {n:v for n,v in after.items()if '/formal/'in n}==formal_before
|
||||
assert all(after[n]==v for n,v in pair_before.items())
|
||||
r.write(out/'actual-formal-after-reader.json',{n:v for n,v in after.items()if '/formal/'in n})
|
||||
except BaseException as caught:error=type(caught).__name__+': '+str(caught)
|
||||
finally:cleanup,cleanup_errors=outer.finish_captured(outer.OWNED)
|
||||
passed=error is None and not cleanup_errors and len(phases)==4 and all(x['passed'] for x in phases) and all(x['engine_ended'] for x in cleanup)
|
||||
assert r.source_refs(R)==root_before and r.default_player(R)==protected
|
||||
assert {n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in docs}==docs
|
||||
assert r.inventory(stage,stage=True)==dict(expected,**previous)
|
||||
r.write(out/'runner-ended.json',{'mode':mode,'passed':passed,'phases':phases,'cleanup':cleanup,'cleanup_errors':cleanup_errors,'error':error,'whole_source_unchanged':True,'whole_default_profile_unchanged':True,'doc4_unchanged':True,'source_adoption':False,'normal_GUI_accepted':False,'full_regression_accepted':False,'formal_cross_PID_accepted':False,'actual_captured_PIDs':[p.pid for p in outer.OWNED],'actual_native_processes':len(outer.OWNED),'actual_checks':sum(p.get('reported_checks',0)for p in phases if p['test']) if passed else None,'formal_reader_evidence_scope':'headless formal migration with real paid supplies, normally hired porter and actual cargo plus concurrent paid legacy construction; whole separate-PID continuation and backup; Operations OFF, unchanged actual supply endpoints, no Main OS or full acceptance','native_Windows_accepted':False,'whole_goal_accepted':False})
|
||||
print(json.dumps({'mode':mode,'passed':passed,'error':error,'actual_native':len(phases),'actual_checks':phases[-1].get('reported_checks')}),flush=True)
|
||||
return 0 if passed else 1
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1,129 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-multiple-jobs-dimension-native-r01/migration-pair"
|
||||
const MODE := "read"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var dorm_job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://tests/fixtures/legacy_staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"warehouse",&"origin":Vector3i(-6,0,1)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"warehouse").build_minutes)
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"service_stairs",&"origin":Vector3i(-7,y,1)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"service_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
command(&"build_facility",{&"definition_id":&"staff_dormitory",&"origin":Vector3i(-6,2,1)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
if job.definition_id==&"staff_dormitory" and not job.is_terminal():dorm_job_id=job.job_id
|
||||
expect(not job_id.is_empty() and not dorm_job_id.is_empty(),"two real paid archived construction jobs are simultaneously in flight")
|
||||
if job_id.is_empty() or dorm_job_id.is_empty():runtime.free();clock.free();state.free();quit(1);return
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_jobs: Array=[runtime.construction_service.get_job(job_id).create_snapshot(),runtime.construction_service.get_job(dorm_job_id).create_snapshot()]
|
||||
expect(original_jobs[0][&"reserved_cells"].size()==6 and original_jobs[1][&"reserved_cells"].size()==8 and original_jobs.all(func(job: Dictionary):return job[&"work_units_done"]==70000 and job[&"progress"]==466 and job[&"state"]=="BUILDING"),"actual two seven-minute jobs retain paid progress and old14 reserved cells")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_jobs)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
paths.erase("res://tests/fixtures/legacy_staff_dormitory.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and preview.get(&"facility_ids",[]).size()==2 and preview.get(&"facility_ids",[]).has(job_id) and preview.get(&"facility_ids",[]).has(dorm_job_id) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"dorm_job_id":dorm_job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];dorm_job_id=identity[&"dorm_job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Array=read_proof("original-job.var")
|
||||
for index: int in range(2):
|
||||
var id: StringName=job_id if index==0 else dorm_job_id
|
||||
var actual: Dictionary=runtime.construction_service.get_job(id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==(4 if index==0 else 2) and actual[&"progress"]==original[index][&"progress"] and actual[&"construction_cost"]==original[index][&"construction_cost"] and actual[&"started_at"]==original[index][&"started_at"],"batch preserves actual paid work and changes each footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(runtime.construction_service.get_job(job_id).work_units_done==80000 and runtime.construction_service.get_job(dorm_job_id).work_units_done==80000,"both real jobs continue one minute exactly")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
for id: StringName in [job_id,dorm_job_id]:
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==(4 if id==job_id else 2),"each actual resized job completes with its own facility owner")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Multiple jobs dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,129 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-multiple-jobs-dimension-native-r01/migration-pair"
|
||||
const MODE := "write"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var dorm_job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://tests/fixtures/legacy_staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"warehouse",&"origin":Vector3i(-6,0,1)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"warehouse").build_minutes)
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"service_stairs",&"origin":Vector3i(-7,y,1)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"service_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
command(&"build_facility",{&"definition_id":&"staff_dormitory",&"origin":Vector3i(-6,2,1)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
if job.definition_id==&"staff_dormitory" and not job.is_terminal():dorm_job_id=job.job_id
|
||||
expect(not job_id.is_empty() and not dorm_job_id.is_empty(),"two real paid archived construction jobs are simultaneously in flight")
|
||||
if job_id.is_empty() or dorm_job_id.is_empty():runtime.free();clock.free();state.free();quit(1);return
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_jobs: Array=[runtime.construction_service.get_job(job_id).create_snapshot(),runtime.construction_service.get_job(dorm_job_id).create_snapshot()]
|
||||
expect(original_jobs[0][&"reserved_cells"].size()==6 and original_jobs[1][&"reserved_cells"].size()==8 and original_jobs.all(func(job: Dictionary):return job[&"work_units_done"]==70000 and job[&"progress"]==466 and job[&"state"]=="BUILDING"),"actual two seven-minute jobs retain paid progress and old14 reserved cells")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_jobs)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
paths.erase("res://tests/fixtures/legacy_staff_dormitory.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and preview.get(&"facility_ids",[]).size()==2 and preview.get(&"facility_ids",[]).has(job_id) and preview.get(&"facility_ids",[]).has(dorm_job_id) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"dorm_job_id":dorm_job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres");paths.append("res://data/facilities/expansion/staff_dormitory.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];dorm_job_id=identity[&"dorm_job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Array=read_proof("original-job.var")
|
||||
for index: int in range(2):
|
||||
var id: StringName=job_id if index==0 else dorm_job_id
|
||||
var actual: Dictionary=runtime.construction_service.get_job(id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==(4 if index==0 else 2) and actual[&"progress"]==original[index][&"progress"] and actual[&"construction_cost"]==original[index][&"construction_cost"] and actual[&"started_at"]==original[index][&"started_at"],"batch preserves actual paid work and changes each footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(runtime.construction_service.get_job(job_id).work_units_done==80000 and runtime.construction_service.get_job(dorm_job_id).work_units_done==80000,"both real jobs continue one minute exactly")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
for id: StringName in [job_id,dorm_job_id]:
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==(4 if id==job_id else 2),"each actual resized job completes with its own facility owner")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Multiple jobs dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import hashlib,importlib.util,json,sys,os
|
||||
sys.dont_write_bytecode=True
|
||||
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';P=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-multiple-jobs-dimension-prep-r01')
|
||||
TEST='tests/s3/test_runtime_staff_assignment.gd'
|
||||
READER='tests/s6/test_runtime_snapshot_serialization.gd'
|
||||
def module(n,p):
|
||||
s=importlib.util.spec_from_file_location(n,p);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
|
||||
def main():
|
||||
assert len(sys.argv)==2
|
||||
mode='formal-cross-pid';out=Path(sys.argv[1]);assert out.parent==A and not out.exists() and str(out)==json.loads((P/'preparation.json').read_bytes())['planned_output']
|
||||
r=module('role_formal_literal_runner',R/'tools/run_all_tests.py')
|
||||
seal=r.read(P/'input-seal.json')
|
||||
assert set(str(p.relative_to(P)) for p in P.rglob('*') if p.is_file())==set(seal['files'])|{'input-seal.json','preparation.json'}
|
||||
for n,v in seal['files'].items():assert Path(v['path'])==P/n and r.sha(v['path'])==v['sha256'] and Path(v['path']).stat().st_size==v['bytes']
|
||||
for name in ['writer.gd','reader.gd']:
|
||||
lines=(P/name).read_text().splitlines();bindings=[line[len('const PAIR_ROOT := '):]for line in lines if line.startswith('const PAIR_ROOT := ')]
|
||||
assert len(bindings)==1 and json.loads(bindings[0])==str(out/'migration-pair') and not (out/'migration-pair').exists()
|
||||
root_before=r.source_refs(R);assert len(root_before)==1299
|
||||
adopted=r.read(A/'p03-current1299-defense-empty-two-ref-source-adoption-r01/source-after.json')
|
||||
assert {n:v['sha256']for n,v in root_before.items()}==adopted
|
||||
refs=dict(root_before);refs[TEST]=seal['files']['writer.gd'];refs[READER]=seal['files']['reader.gd']
|
||||
for n,v in refs.items():assert Path(v['path']).stat().st_size==v['bytes'] and r.sha(v['path'])==v['sha256']
|
||||
docs={n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in ('IMPLEMENTATION_PLAN.md','PROGRESS_INTEGRATION.md','work_packages.json','progress_snapshot.json')}
|
||||
outer=module('bath_literal_owned_outer',r.SUPPORT/'owned_outer.py');assert not outer.native.helper['live_engines']()
|
||||
engine='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
out.mkdir();stage=out/'stage';stage.mkdir();(out/'starters').mkdir();(out/'bootstrap').mkdir()
|
||||
for n,v in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data=v['text'].encode();assert hashlib.sha256(data).hexdigest()==v['sha256'];(out/'bootstrap'/n).write_bytes(data)
|
||||
protected=r.default_player(R);expected={n:{'bytes':v['bytes'],'sha256':v['sha256']}for n,v in refs.items()}
|
||||
selected={'root_before':root_before,'map':{n:v['sha256']for n,v in refs.items()},'timeout':180}
|
||||
for n,v in refs.items():
|
||||
p=stage/n;p.parent.mkdir(parents=True,exist_ok=True);r.copy_source(Path(v['path']),p)
|
||||
assert r.inventory(stage,stage=True)==expected
|
||||
public=(stage/'project.godot').read_bytes();paths=['res://'+n for n in sorted(refs) if n.endswith('.gd')];r.write(out/'parse-paths.json',paths)
|
||||
markers=module('bath_literal_markers',R/'tools/strict_test_markers.py')
|
||||
contracts=markers.load_contracts(R/'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json')
|
||||
contracts[TEST]={'test':TEST,'template':'Multiple jobs dimension formal write: <checks> checks, <failures> failures','required':True}
|
||||
contracts[READER]={'test':READER,'template':'Multiple jobs dimension formal read: <checks> checks, <failures> failures','required':True}
|
||||
policy=r.read(r.SUPPORT/'suite-policy.json');assert TEST not in policy['suite_policies'] and READER not in policy['suite_policies']
|
||||
r.write(out/'runner-input.json',{'mode':mode,'owner_pid':os.getpid(),'wrapper_sha256':r.sha(__file__),'runner_sha256':r.sha(R/'tools/run_all_tests.py'),'selected_source_map':selected['map'],'source_before':root_before,'default_player':protected,'doc4_before':docs,'actual_full':False,'source_adoption':False})
|
||||
diagnostics=module('bath_literal_diagnostics',r.SUPPORT/'diagnostic_gate.py');owners=module('bath_literal_owners',r.SUPPORT/'ordinary_proof_gate.py');audio=module('bath_literal_audio',r.SUPPORT/'audio_evidence_gate.py')
|
||||
phases=[];previous={};error=None;formal_before=None
|
||||
try:
|
||||
for phase,test in [('import',None),('parse',None),('writer',TEST),('reader',READER)]:
|
||||
if phase=='writer':assert not (out/'migration-pair').exists()
|
||||
if phase=='reader':assert r.inventory(out/'migration-pair')==pair_before
|
||||
row=r.execute_phase(engine,stage,out,phase,test,selected,expected,previous,policy,contracts,paths,public,protected,R,outer,markers,diagnostics,owners,audio);phases.append(row)
|
||||
print(json.dumps({'phase':phase,'passed':row['passed'],'checks':row.get('reported_checks'),'error':row.get('validation_error'),'guard_error':row.get('guard_error')}),flush=True)
|
||||
r.require(row['passed'],'strict phase failure stops without retry')
|
||||
if phase=='writer':
|
||||
pair_before=r.inventory(out/'migration-pair');formal_before={n:v for n,v in pair_before.items()if '/formal/'in n}
|
||||
assert len(formal_before)==12
|
||||
r.write(out/'actual-formal-before-reader.json',formal_before)
|
||||
if phase=='reader':
|
||||
after=r.inventory(out/'migration-pair');assert {n:v for n,v in after.items()if '/formal/'in n}==formal_before
|
||||
assert all(after[n]==v for n,v in pair_before.items())
|
||||
r.write(out/'actual-formal-after-reader.json',{n:v for n,v in after.items()if '/formal/'in n})
|
||||
except BaseException as caught:error=type(caught).__name__+': '+str(caught)
|
||||
finally:cleanup,cleanup_errors=outer.finish_captured(outer.OWNED)
|
||||
passed=error is None and not cleanup_errors and len(phases)==4 and all(x['passed'] for x in phases) and all(x['engine_ended'] for x in cleanup)
|
||||
assert r.source_refs(R)==root_before and r.default_player(R)==protected
|
||||
assert {n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in docs}==docs
|
||||
assert r.inventory(stage,stage=True)==dict(expected,**previous)
|
||||
r.write(out/'runner-ended.json',{'mode':mode,'passed':passed,'phases':phases,'cleanup':cleanup,'cleanup_errors':cleanup_errors,'error':error,'whole_source_unchanged':True,'whole_default_profile_unchanged':True,'doc4_unchanged':True,'source_adoption':False,'normal_GUI_accepted':False,'full_regression_accepted':False,'formal_cross_PID_accepted':False,'actual_captured_PIDs':[p.pid for p in outer.OWNED],'actual_native_processes':len(outer.OWNED),'actual_checks':sum(p.get('reported_checks',0)for p in phases if p['test']) if passed else None,'formal_reader_evidence_scope':'headless direct formal legacy-dimension migration, real paid concurrent construction and fractional guest stair travel; separate-PID original backup and migrated continuation; Operations OFF controlled guest input, no Main OS input, rescue/logistics/occupied EV/whole original acceptance','native_Windows_accepted':False,'whole_goal_accepted':False})
|
||||
print(json.dumps({'mode':mode,'passed':passed,'error':error,'actual_native':len(phases),'actual_checks':phases[-1].get('reported_checks')}),flush=True)
|
||||
return 0 if passed else 1
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1,134 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-rescue-dimension-native-r01/migration-pair"
|
||||
const MODE := "read"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
command(&"build_facility",{&"definition_id":&"infirmary",&"origin":Vector3i(-6,0,1)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"infirmary").build_minutes)
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
for id: StringName in [&"patient",&"porter"]:
|
||||
command(&"register_staff",{&"staff_id":id,&"role_id":&"porter",&"options":{&"current_cell":Vector3i(3,0,1) if id==&"patient" else Vector3i(5,0,1),&"health":0 if id==&"patient" else 100,&"state":StaffRuntime.State.AVAILABLE,&"role_tags":[&"medic"],&"permitted_task_tags":[&"rescue"]}})
|
||||
var carrying:=false
|
||||
for minute: int in range(6):
|
||||
clock.advance_minutes(1)
|
||||
for task: StaffTask in runtime.staff_service.get_tasks():
|
||||
if task.task_type==&"rescue_transport" and task.state==StaffTask.State.MOVING:carrying=true
|
||||
if carrying:break
|
||||
expect(carrying,"actual rescue transport started without forced movement")
|
||||
if not carrying:runtime.free();clock.free();state.free();quit(1);return
|
||||
var patient: StaffRuntime=runtime.staff_service.get_staff(&"patient")
|
||||
var porter: StaffRuntime=runtime.staff_service.get_staff(&"porter")
|
||||
expect(patient.current_cell==porter.current_cell and patient.health==0,"actual carried patient shares porter cell without healing")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(runtime.staff_service.get_staff(&"patient").health==0,"first post-migration minute does not skip actual transport")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
var patient: StaffRuntime=runtime.staff_service.get_staff(&"patient")
|
||||
expect(patient.health==100 and patient.state==StaffRuntime.State.OFF_DUTY and patient.current_cell.x<0 and patient.current_cell.z==1,"actual carrier transport and treatment finish after migrated continuation")
|
||||
expect(runtime.staff_service.validate_invariants()[&"ok"],"rescue ownership invariants preserved")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Rescue dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,134 @@
|
||||
extends SceneTree
|
||||
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-rescue-dimension-native-r01/migration-pair"
|
||||
const MODE := "write"
|
||||
var checks:=0
|
||||
var failures:=0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var job_id: StringName
|
||||
var serial:=0
|
||||
var journal: Array[Dictionary]=[]
|
||||
func _initialize() -> void:call_deferred("run")
|
||||
func expect(ok: bool,label: String) -> void:
|
||||
checks+=1
|
||||
print(("PASS " if ok else "FAIL ")+label)
|
||||
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
||||
func write_proof(name: String,value: Variant) -> void:
|
||||
var path:=PAIR_ROOT.path_join(name)
|
||||
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
||||
var file:=FileAccess.open(path,FileAccess.WRITE)
|
||||
expect(file!=null,"open proof "+name)
|
||||
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
||||
func read_proof(name: String) -> Variant:
|
||||
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
||||
expect(not data.is_empty(),"read whole proof "+name)
|
||||
return bytes_to_var(data)
|
||||
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
||||
serial+=1
|
||||
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
||||
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
||||
return result
|
||||
func copy_package(source: String,destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
||||
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
||||
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
||||
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
||||
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
||||
expect(file!=null,"open formal member "+name)
|
||||
if file!=null:file.store_buffer(original);file.close()
|
||||
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
||||
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
||||
func capture(label: String) -> void:
|
||||
var snapshot: Dictionary=runtime.create_snapshot()
|
||||
write_proof(MODE+"-"+label+".var",snapshot)
|
||||
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
||||
func run() -> void:
|
||||
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
||||
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime=load("res://autoload/simulation_runtime.gd").new()
|
||||
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
||||
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
var slot: String="user://p03-inflight-dimension/manual"
|
||||
if MODE=="write":
|
||||
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
||||
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
||||
command(&"build_facility",{&"definition_id":&"infirmary",&"origin":Vector3i(-6,0,1)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"infirmary").build_minutes)
|
||||
for y: int in [1,2,3]:
|
||||
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
||||
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
||||
clock.advance_minutes(7)
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
||||
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
||||
for id: StringName in [&"patient",&"porter"]:
|
||||
command(&"register_staff",{&"staff_id":id,&"role_id":&"porter",&"options":{&"current_cell":Vector3i(3,0,1) if id==&"patient" else Vector3i(5,0,1),&"health":0 if id==&"patient" else 100,&"state":StaffRuntime.State.AVAILABLE,&"role_tags":[&"medic"],&"permitted_task_tags":[&"rescue"]}})
|
||||
var carrying:=false
|
||||
for minute: int in range(6):
|
||||
clock.advance_minutes(1)
|
||||
for task: StaffTask in runtime.staff_service.get_tasks():
|
||||
if task.task_type==&"rescue_transport" and task.state==StaffTask.State.MOVING:carrying=true
|
||||
if carrying:break
|
||||
expect(carrying,"actual rescue transport started without forced movement")
|
||||
if not carrying:runtime.free();clock.free();state.free();quit(1);return
|
||||
var patient: StaffRuntime=runtime.staff_service.get_staff(&"patient")
|
||||
var porter: StaffRuntime=runtime.staff_service.get_staff(&"porter")
|
||||
expect(patient.current_cell==porter.current_cell and patient.health==0,"actual carried patient shares porter cell without healing")
|
||||
var legacy: Dictionary=runtime.create_snapshot()
|
||||
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
||||
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
||||
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
||||
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
||||
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
||||
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
||||
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
||||
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
||||
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
||||
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
||||
write_proof("identity.var",{&"job_id":job_id,&"serial":serial})
|
||||
else:
|
||||
paths.append("res://data/facilities/expansion/premium_room.tres")
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
||||
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"]
|
||||
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
||||
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
||||
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
||||
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
||||
var loaded:=SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
||||
var original: Dictionary=read_proof("original-job.var")
|
||||
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
||||
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
||||
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
||||
capture("checkpoint")
|
||||
clock.advance_minutes(1);capture("next1")
|
||||
expect(runtime.staff_service.get_staff(&"patient").health==0,"first post-migration minute does not skip actual transport")
|
||||
clock.advance_minutes(1);capture("next2")
|
||||
clock.advance_minutes(8);capture("next10")
|
||||
clock.advance_minutes(150);capture("final160")
|
||||
var patient: StaffRuntime=runtime.staff_service.get_staff(&"patient")
|
||||
expect(patient.health==100 and patient.state==StaffRuntime.State.OFF_DUTY and patient.current_cell.x<0 and patient.current_cell.z==1,"actual carrier transport and treatment finish after migrated continuation")
|
||||
expect(runtime.staff_service.validate_invariants()[&"ok"],"rescue ownership invariants preserved")
|
||||
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
||||
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
||||
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
||||
write_proof(MODE+"-events.var",journal)
|
||||
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
||||
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
||||
runtime.free();clock.free();state.free()
|
||||
print("Rescue dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import hashlib,importlib.util,json,sys,os
|
||||
sys.dont_write_bytecode=True
|
||||
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';P=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-rescue-dimension-prep-r01')
|
||||
TEST='tests/s3/test_runtime_staff_assignment.gd'
|
||||
READER='tests/s6/test_runtime_snapshot_serialization.gd'
|
||||
def module(n,p):
|
||||
s=importlib.util.spec_from_file_location(n,p);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
|
||||
def main():
|
||||
assert len(sys.argv)==2
|
||||
mode='formal-cross-pid';out=Path(sys.argv[1]);assert out.parent==A and not out.exists() and str(out)==json.loads((P/'preparation.json').read_bytes())['planned_output']
|
||||
r=module('role_formal_literal_runner',R/'tools/run_all_tests.py')
|
||||
seal=r.read(P/'input-seal.json')
|
||||
assert set(str(p.relative_to(P)) for p in P.rglob('*') if p.is_file())==set(seal['files'])|{'input-seal.json','preparation.json'}
|
||||
for n,v in seal['files'].items():assert Path(v['path'])==P/n and r.sha(v['path'])==v['sha256'] and Path(v['path']).stat().st_size==v['bytes']
|
||||
for name in ['writer.gd','reader.gd']:
|
||||
lines=(P/name).read_text().splitlines();bindings=[line[len('const PAIR_ROOT := '):]for line in lines if line.startswith('const PAIR_ROOT := ')]
|
||||
assert len(bindings)==1 and json.loads(bindings[0])==str(out/'migration-pair') and not (out/'migration-pair').exists()
|
||||
root_before=r.source_refs(R);assert len(root_before)==1299
|
||||
adopted=r.read(A/'p03-current1299-defense-empty-two-ref-source-adoption-r01/source-after.json')
|
||||
assert {n:v['sha256']for n,v in root_before.items()}==adopted
|
||||
refs=dict(root_before);refs[TEST]=seal['files']['writer.gd'];refs[READER]=seal['files']['reader.gd']
|
||||
for n,v in refs.items():assert Path(v['path']).stat().st_size==v['bytes'] and r.sha(v['path'])==v['sha256']
|
||||
docs={n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in ('IMPLEMENTATION_PLAN.md','PROGRESS_INTEGRATION.md','work_packages.json','progress_snapshot.json')}
|
||||
outer=module('bath_literal_owned_outer',r.SUPPORT/'owned_outer.py');assert not outer.native.helper['live_engines']()
|
||||
engine='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
out.mkdir();stage=out/'stage';stage.mkdir();(out/'starters').mkdir();(out/'bootstrap').mkdir()
|
||||
for n,v in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data=v['text'].encode();assert hashlib.sha256(data).hexdigest()==v['sha256'];(out/'bootstrap'/n).write_bytes(data)
|
||||
protected=r.default_player(R);expected={n:{'bytes':v['bytes'],'sha256':v['sha256']}for n,v in refs.items()}
|
||||
selected={'root_before':root_before,'map':{n:v['sha256']for n,v in refs.items()},'timeout':180}
|
||||
for n,v in refs.items():
|
||||
p=stage/n;p.parent.mkdir(parents=True,exist_ok=True);r.copy_source(Path(v['path']),p)
|
||||
assert r.inventory(stage,stage=True)==expected
|
||||
public=(stage/'project.godot').read_bytes();paths=['res://'+n for n in sorted(refs) if n.endswith('.gd')];r.write(out/'parse-paths.json',paths)
|
||||
markers=module('bath_literal_markers',R/'tools/strict_test_markers.py')
|
||||
contracts=markers.load_contracts(R/'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json')
|
||||
contracts[TEST]={'test':TEST,'template':'Rescue dimension formal write: <checks> checks, <failures> failures','required':True}
|
||||
contracts[READER]={'test':READER,'template':'Rescue dimension formal read: <checks> checks, <failures> failures','required':True}
|
||||
policy=r.read(r.SUPPORT/'suite-policy.json');assert TEST not in policy['suite_policies'] and READER not in policy['suite_policies']
|
||||
r.write(out/'runner-input.json',{'mode':mode,'owner_pid':os.getpid(),'wrapper_sha256':r.sha(__file__),'runner_sha256':r.sha(R/'tools/run_all_tests.py'),'selected_source_map':selected['map'],'source_before':root_before,'default_player':protected,'doc4_before':docs,'actual_full':False,'source_adoption':False})
|
||||
diagnostics=module('bath_literal_diagnostics',r.SUPPORT/'diagnostic_gate.py');owners=module('bath_literal_owners',r.SUPPORT/'ordinary_proof_gate.py');audio=module('bath_literal_audio',r.SUPPORT/'audio_evidence_gate.py')
|
||||
phases=[];previous={};error=None;formal_before=None
|
||||
try:
|
||||
for phase,test in [('import',None),('parse',None),('writer',TEST),('reader',READER)]:
|
||||
if phase=='writer':assert not (out/'migration-pair').exists()
|
||||
if phase=='reader':assert r.inventory(out/'migration-pair')==pair_before
|
||||
row=r.execute_phase(engine,stage,out,phase,test,selected,expected,previous,policy,contracts,paths,public,protected,R,outer,markers,diagnostics,owners,audio);phases.append(row)
|
||||
print(json.dumps({'phase':phase,'passed':row['passed'],'checks':row.get('reported_checks'),'error':row.get('validation_error'),'guard_error':row.get('guard_error')}),flush=True)
|
||||
r.require(row['passed'],'strict phase failure stops without retry')
|
||||
if phase=='writer':
|
||||
pair_before=r.inventory(out/'migration-pair');formal_before={n:v for n,v in pair_before.items()if '/formal/'in n}
|
||||
assert len(formal_before)==12
|
||||
r.write(out/'actual-formal-before-reader.json',formal_before)
|
||||
if phase=='reader':
|
||||
after=r.inventory(out/'migration-pair');assert {n:v for n,v in after.items()if '/formal/'in n}==formal_before
|
||||
assert all(after[n]==v for n,v in pair_before.items())
|
||||
r.write(out/'actual-formal-after-reader.json',{n:v for n,v in after.items()if '/formal/'in n})
|
||||
except BaseException as caught:error=type(caught).__name__+': '+str(caught)
|
||||
finally:cleanup,cleanup_errors=outer.finish_captured(outer.OWNED)
|
||||
passed=error is None and not cleanup_errors and len(phases)==4 and all(x['passed'] for x in phases) and all(x['engine_ended'] for x in cleanup)
|
||||
assert r.source_refs(R)==root_before and r.default_player(R)==protected
|
||||
assert {n:r.sha(R/'docs/plans/original-completion-2026-10-02'/n) for n in docs}==docs
|
||||
assert r.inventory(stage,stage=True)==dict(expected,**previous)
|
||||
r.write(out/'runner-ended.json',{'mode':mode,'passed':passed,'phases':phases,'cleanup':cleanup,'cleanup_errors':cleanup_errors,'error':error,'whole_source_unchanged':True,'whole_default_profile_unchanged':True,'doc4_unchanged':True,'source_adoption':False,'normal_GUI_accepted':False,'full_regression_accepted':False,'formal_cross_PID_accepted':False,'actual_captured_PIDs':[p.pid for p in outer.OWNED],'actual_native_processes':len(outer.OWNED),'actual_checks':sum(p.get('reported_checks',0)for p in phases if p['test']) if passed else None,'formal_reader_evidence_scope':'headless direct formal migration with actual rescue transport, patient and carrier references plus paid old-size concurrent construction; whole separate-PID continuation and backup; controlled initial injury, Operations OFF, no Main OS, changed-clinic destination, logistics or whole acceptance','native_Windows_accepted':False,'whole_goal_accepted':False})
|
||||
print(json.dumps({'mode':mode,'passed':passed,'error':error,'actual_native':len(phases),'actual_checks':phases[-1].get('reported_checks')}),flush=True)
|
||||
return 0 if passed else 1
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
# P08-02 diagnostic fixture
|
||||
|
||||
Controlled fixture inputs are diagnostic, not production balance values.
|
||||
Native collection and acceptance remain pending.
|
||||
|
||||
Seed: 42588. Registered construction costs for the 16 planned builds total
|
||||
gold 7110 / materials 88; Gina signing costs 150 and eight raw food units cost
|
||||
24. Initial resources are gold 5000 / materials 50. The previous fixture had
|
||||
no change_resources delta (zero), short by gold 2284 / materials 38.
|
||||
The fixture derives and records this deficit from the actual registry/catalogs
|
||||
in identity.diagnostic_budget before using the existing change_resources command.
|
||||
No price or production coefficient is changed.
|
||||
|
||||
Stair preparation proceeds from floor 1 through floor 3. Each pair finishes
|
||||
using the maximum registered stair build_minutes before the next floor is
|
||||
ordered. Ground landings use initialized world paths; upper landings are
|
||||
created by completed stairs through build_facility, with a local path check
|
||||
before each pair. Failed commands include kind, payload and result details.
|
||||
|
||||
The first legacy premium job progresses while the six actor/transport facets
|
||||
are prepared. The second is paid and reserved immediately before saving, with
|
||||
zero progress; the dormitory is already complete. All three stages share the
|
||||
same migration batch and whole-state writer/reader comparisons.
|
||||
Vendored
+241
@@ -0,0 +1,241 @@
|
||||
extends RefCounted
|
||||
## All seeds, actor IDs, positions, food quantities and schedules are diagnostic inputs.
|
||||
var checks := 0
|
||||
var failures := 0
|
||||
var runtime: Variant
|
||||
var clock: Variant
|
||||
var state: Variant
|
||||
var directory: String
|
||||
var mode: String
|
||||
var slot: String
|
||||
var serial := 0
|
||||
var events: Array = []
|
||||
var identity: Dictionary = {}
|
||||
const MEMBERS := [SaveService.WORLD_FILE, SaveService.MANIFEST_FILE, SaveService.THUMBNAIL_FILE, SaveService.JOURNAL_FILE]
|
||||
func expect(ok: bool, label: String) -> bool:
|
||||
checks += 1
|
||||
if not ok:
|
||||
failures += 1
|
||||
push_error("P08 mixed: " + label)
|
||||
return ok
|
||||
func command(kind: StringName, payload: Dictionary) -> bool:
|
||||
serial += 1
|
||||
var result: CommandResult = runtime.submit_command(kind, payload, &"player", &"", 0, -1, StringName("p08.%d" % serial))
|
||||
var label := String(kind) + ": " + result.message
|
||||
if not result.is_success(): label += " payload=" + var_to_str(payload) + " details=" + var_to_str(result.details)
|
||||
return expect(result.is_success(), label)
|
||||
func registry(old: bool) -> void:
|
||||
var paths: Array[String] = FacilityCatalog.FACILITY_PATHS + FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS + FacilityCatalog.RESCUE_FACILITY_PATHS
|
||||
paths.append_array(["res://tests/fixtures/legacy_premium_room.tres", "res://tests/fixtures/legacy_staff_dormitory.tres"] if old else ["res://data/facilities/expansion/premium_room.tres", "res://data/facilities/expansion/staff_dormitory.tres"])
|
||||
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"], "definition registry")
|
||||
func build(id: StringName, cell: Vector3i, complete := true) -> bool:
|
||||
if not command(&"build_facility", {&"definition_id":id, &"origin":cell}): return false
|
||||
if complete: clock.advance_minutes(runtime.definition_registry.get_facility(id).build_minutes)
|
||||
return true
|
||||
func instance(id: StringName) -> FacilityInstance:
|
||||
for room: FacilityInstance in runtime.facility_service.get_instances():
|
||||
if room.definition_id == id: return room
|
||||
return null
|
||||
## Scalar text avoids loss of integer precision; raw Variant bytes accompany JSON.
|
||||
func typed(value: Variant) -> Dictionary:
|
||||
var result := {"type":type_string(typeof(value))}
|
||||
if value is Dictionary:
|
||||
result["entries"] = []
|
||||
for key: Variant in value: result["entries"].append([typed(key),typed(value[key])])
|
||||
elif value is Array:
|
||||
result["element_type"] = value.get_typed_builtin()
|
||||
result["element_class"] = String(value.get_typed_class_name())
|
||||
result["items"] = []
|
||||
for item: Variant in value: result["items"].append(typed(item))
|
||||
else: result["text"] = var_to_str(value)
|
||||
return result
|
||||
func put(name: String, value: Variant) -> void:
|
||||
var path := directory.path_join(name)
|
||||
if not expect(not FileAccess.file_exists(path+".var") and not FileAccess.file_exists(path+".json"), "fresh proof "+name): return
|
||||
var file := FileAccess.open(path+".var",FileAccess.WRITE)
|
||||
if not expect(file != null,"Variant output"): return
|
||||
file.store_buffer(var_to_bytes(value)); file.close()
|
||||
file = FileAccess.open(path+".json",FileAccess.WRITE)
|
||||
if not expect(file != null,"typed output"): return
|
||||
file.store_string(JSON.stringify(typed(value))); file.close()
|
||||
func get_proof(name: String) -> Variant:
|
||||
return bytes_to_var(FileAccess.get_file_as_bytes(directory.path_join(name+".var")))
|
||||
func capture(name: String, value: Variant) -> void:
|
||||
put(mode+"-"+name,value)
|
||||
if mode == "reader": expect(var_to_bytes(value) == var_to_bytes(get_proof("writer-"+name)),"whole cross-PID "+name)
|
||||
func copy_package(source: String, destination: String) -> void:
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination) == OK,"package directory")
|
||||
for member: String in MEMBERS:
|
||||
var data := FileAccess.get_file_as_bytes(source.path_join(member))
|
||||
if not expect(not data.is_empty() and not FileAccess.file_exists(destination.path_join(member)),"fresh complete member "+member): continue
|
||||
var file := FileAccess.open(destination.path_join(member),FileAccess.WRITE)
|
||||
if not expect(file != null,"member writable"): continue
|
||||
file.store_buffer(data); file.close()
|
||||
expect(data == FileAccess.get_file_as_bytes(destination.path_join(member)),"whole member copy verified")
|
||||
func packages() -> Dictionary:
|
||||
var hashes := {}
|
||||
for suffix: String in ["",SaveService.MIGRATION_BACKUP_SUFFIX]:
|
||||
for member: String in MEMBERS: hashes[suffix+"/"+member] = FileAccess.get_sha256(ProjectSettings.globalize_path(slot+suffix).path_join(member))
|
||||
return hashes
|
||||
func observe(event: SimulationDomainEvent) -> void: events.append(event.to_dictionary())
|
||||
## Controlled diagnostic input; costs come only from registered domain definitions.
|
||||
func prepare_diagnostic_budget() -> bool:
|
||||
var planned: Array[StringName] = [&"warehouse",&"kitchen",&"infirmary",&"staff_door",&"reception",&"reception",&"guest_elevator",&"staff_dormitory",&"premium_room",&"premium_room",&"service_stairs",&"service_stairs",&"service_stairs",&"guest_stairs",&"guest_stairs",&"guest_stairs"]
|
||||
var needed := {&"gold":0,&"materials":0}
|
||||
var costs: Array = []
|
||||
for id: StringName in planned:
|
||||
var definition: FacilityDefinition = runtime.definition_registry.get_facility(id)
|
||||
if not expect(definition != null,"budget definition "+String(id)): return false
|
||||
costs.append({&"definition_id":id,&"cost":definition.construction_cost.duplicate(true)})
|
||||
for resource: StringName in needed: needed[resource] += int(definition.construction_cost.get(resource,0))
|
||||
var signing := int(runtime.mvp_content_catalog.staff_hire_payload(&"staff_gina").get(&"signing_cost",0))
|
||||
var food := 8 * int(SupplyCatalog.get_item(SupplyCatalog.RAW_FOOD)[&"unit_price"])
|
||||
needed[&"gold"] += signing + food
|
||||
var deltas := {}
|
||||
for resource: StringName in needed:
|
||||
var deficit: int = maxi(0,int(needed[resource])-state.get_resource(resource))
|
||||
if deficit > 0: deltas[resource] = deficit
|
||||
identity[&"diagnostic_budget"] = {&"seed":42588,&"costs":costs,&"signing":signing,&"food_quantity":8,&"food_cost":food,&"needed":needed,&"initial":state.resources.duplicate(true),&"previous_change_resources":{},&"deltas":deltas}
|
||||
return deltas.is_empty() or command(&"change_resources",{&"deltas":deltas})
|
||||
func setup(operations: bool) -> bool:
|
||||
registry(true)
|
||||
if not prepare_diagnostic_budget(): return false
|
||||
if operations and not expect(runtime.enable_production_operations().get(&"ok",false),"Operations enabled at Day 1 06:00"): return false
|
||||
for row: Array in [[&"warehouse",Vector3i(-8,0,1)],[&"kitchen",Vector3i(2,0,1)],[&"infirmary",Vector3i(6,0,1)],[&"staff_door",Vector3i(0,0,1)],[&"reception",Vector3i(-6,0,0)],[&"reception",Vector3i(5,0,0)],[&"guest_elevator",Vector3i.ZERO]]:
|
||||
if not build(row[0],row[1],false): return false
|
||||
clock.advance_minutes(180)
|
||||
# Completed stairs supply the next floor's landing through the domain projector.
|
||||
# Ground-floor landings come from the initialized world; never inject path cells.
|
||||
var stair_minutes: int = maxi(runtime.definition_registry.get_facility(&"service_stairs").build_minutes,runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
||||
for y: int in [1,2,3]:
|
||||
if not expect(runtime.path_service.has_cell(Vector3i(-9,y-1,1)) and runtime.path_service.has_cell(Vector3i(4,y-1,0)),"completed lower stair landings for floor %d" % y): return false
|
||||
if not build(&"service_stairs",Vector3i(-9,y,1),false) or not build(&"guest_stairs",Vector3i(4,y,0),false): return false
|
||||
clock.advance_minutes(stair_minutes)
|
||||
if not build(&"staff_dormitory",Vector3i(-8,2,1)): return false
|
||||
identity[&"dorm"] = instance(&"staff_dormitory").instance_id
|
||||
if not build(&"premium_room",Vector3i(-6,2,0),false): return false
|
||||
clock.advance_minutes(7)
|
||||
identity[&"jobs"] = []
|
||||
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if not job.is_terminal(): identity[&"jobs"].append(job.job_id)
|
||||
if not expect(identity[&"jobs"].size() == 1,"one paid progressing job"): return false
|
||||
var warehouse := instance(&"warehouse")
|
||||
var kitchen := instance(&"kitchen")
|
||||
if not expect(warehouse != null and kitchen != null,"completed logistics endpoints"): return false
|
||||
if not command(&"hire_staff_candidate",{&"candidate_id":&"staff_gina"}): return false
|
||||
if not command(&"set_staff_work_assignment",{&"staff_id":&"staff_gina",&"facility_id":warehouse.instance_id,&"template_id":&"DAY"}): return false
|
||||
if not command(&"purchase_supplies",{&"warehouse_id":warehouse.instance_id,&"item_id":SupplyCatalog.RAW_FOOD,&"quantity":8}): return false
|
||||
if not command(&"set_kitchen_production",{&"facility_id":kitchen.instance_id,&"enabled":true,&"target_stock":4}): return false
|
||||
var cargo_ready := false
|
||||
for minute: int in range(60):
|
||||
clock.advance_minutes(1)
|
||||
if not runtime.staff_service.get_staff(&"staff_gina").carried_inventory_id.is_empty(): cargo_ready = true; break
|
||||
if not expect(cargo_ready,"real purchased cargo picked up"): return false
|
||||
for id: StringName in [&"patient",&"carrier"]:
|
||||
if not command(&"register_staff",{&"staff_id":id,&"role_id":&"porter",&"options":{&"current_cell":Vector3i(-3,0,1) if id == &"patient" else Vector3i(-1,0,1),&"health":0 if id == &"patient" else 100,&"state":StaffRuntime.State.AVAILABLE,&"role_tags":[&"medic"],&"permitted_task_tags":[&"rescue"]}}): return false
|
||||
var carrying := false
|
||||
for minute: int in range(6):
|
||||
clock.advance_minutes(1)
|
||||
for task: StaffTask in runtime.staff_service.get_tasks():
|
||||
if task.task_type == &"rescue_transport" and task.state == StaffTask.State.MOVING:
|
||||
carrying = true; identity[&"rescue_task"] = task.task_id
|
||||
if carrying: break
|
||||
if not expect(carrying,"actual rescue transport"): return false
|
||||
for index: int in range(5):
|
||||
if not command(&"spawn_guest",{&"guest_id":StringName("p08.passenger.%d" % index),&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i.ZERO,&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"path_handle":{&"target_cell":Vector3i(0,1,0)}}}): return false
|
||||
clock.advance_minutes(1)
|
||||
if not command(&"spawn_guest",{&"guest_id":&"p08.walker",&"guest_type_id":&"traveler",&"gold":100,&"options":{&"current_cell":Vector3i(4,0,0),&"state":GuestRuntime.State.MOVING,&"state_entered_at":clock.absolute_minute-1,&"planned_exit_at":clock.absolute_minute+2000,&"path_handle":{&"target_cell":Vector3i(4,3,0)}}}): return false
|
||||
clock.advance_minutes(1)
|
||||
identity[&"ev_requests"] = []
|
||||
for trip: Dictionary in runtime.elevators.get_report()[&"trips"]: identity[&"ev_requests"].append(trip[&"request_id"])
|
||||
identity[&"logistics_requests"] = []
|
||||
for request: LogisticsRequest in runtime.logistics_requests.values():
|
||||
if not request.is_terminal(): identity[&"logistics_requests"].append(request.request_id)
|
||||
expect(not runtime.staff_service.get_staff(&"staff_gina").carried_inventory_id.is_empty(),"cargo in SAME save as patient and EV")
|
||||
expect(runtime.staff_service.get_staff(&"patient").health == 0,"patient remains untreated")
|
||||
var car: Dictionary = runtime.elevators.get_report()[&"shafts"][0]
|
||||
expect(car[&"passenger_count"] == 4 and car[&"waiting_count"] == 1,"passengers and queue coexist")
|
||||
expect(runtime.create_snapshot()[&"systems"][&"runtime"][&"movement_credits"].size() > 0,"fractional movement credit")
|
||||
if not build(&"premium_room",Vector3i(5,2,0),false): return false
|
||||
for candidate: ConstructionJob in runtime.construction_service.get_jobs():
|
||||
if not candidate.is_terminal() and not identity[&"jobs"].has(candidate.job_id): identity[&"jobs"].append(candidate.job_id)
|
||||
if not expect(identity[&"jobs"].size() == 2,"two paid active jobs"): return false
|
||||
identity[&"starting_job"] = identity[&"jobs"][1]
|
||||
for id: StringName in identity[&"jobs"]:
|
||||
var job: ConstructionJob = runtime.construction_service.get_job(id)
|
||||
expect(not job.is_terminal() and (job.progress == 0 if id == identity[&"starting_job"] else job.progress > 0) and not job.construction_cost.is_empty() and job.reserved_cells.size() == 6,"old-size paid starting/progressing jobs remain active")
|
||||
return failures == 0
|
||||
func invariant() -> void:
|
||||
expect(runtime.staff_service.validate_invariants()[&"ok"],"staff ownership")
|
||||
expect(SupplyLogisticsBridge.validate_crosslinks(runtime.logistics_requests,runtime.staff_service,runtime.inventory_service,runtime.facility_service),"cargo crosslinks")
|
||||
var snap: Dictionary = runtime.create_snapshot()
|
||||
expect(runtime.restore_snapshot(snap),"whole Runtime ownership/support/transport validation")
|
||||
expect(var_to_bytes(snap) == var_to_bytes(runtime.create_snapshot()),"whole canonical typed state")
|
||||
func run(tree: SceneTree, output: String, role: String, operations: bool, refusal: bool) -> Dictionary:
|
||||
directory = output; mode = role
|
||||
slot = "user://p08-%d/formal" % Time.get_ticks_usec()
|
||||
tree.root.get_node("GameClock").set_paused(true); tree.root.get_node("GameClock").set_process(false)
|
||||
tree.root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
||||
runtime = load("res://autoload/simulation_runtime.gd").new()
|
||||
clock = load("res://autoload/game_clock.gd").new(); state = load("res://autoload/game_state.gd").new()
|
||||
clock.reset(1,6,0); state.reset(); expect(runtime.initialize(clock,state,42588)[&"valid"],"current initialization")
|
||||
clock.set_paused(true); runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
||||
if mode == "writer":
|
||||
expect(DirAccess.make_dir_recursive_absolute(directory) == OK,"proof directory")
|
||||
if not setup(operations): return finish()
|
||||
registry(false)
|
||||
var baseline: Dictionary = runtime.create_snapshot()
|
||||
expect(SaveService.save_snapshot(slot,baseline)[&"ok"],"formal original saved")
|
||||
if refusal:
|
||||
var initial: Dictionary = runtime.migrate_facility_dimensions_at_path(slot)
|
||||
expect(initial.get(&"ok",false) and initial.get(&"backup_created",false),"real prior migration backup")
|
||||
expect(runtime.staff_service.create_task(&"maintenance",10,clock.absolute_minute,{&"target_entity_id":identity[&"dorm"],&"target_cell":Vector3i(-9,3,1),&"estimated_minutes":30},&"p08.late").is_success(),"later old entrance task")
|
||||
if not command(&"register_staff",{&"staff_id":&"maintainer",&"role_id":&"porter",&"options":{&"current_cell":Vector3i(-9,1,1),&"state":StaffRuntime.State.AVAILABLE}}): return finish()
|
||||
expect(runtime.staff_service.assign_task_to_staff(&"p08.late",&"maintainer",clock.absolute_minute).is_success(),"real task ownership")
|
||||
expect(SaveService.save_snapshot(slot,runtime.create_snapshot())[&"ok"],"obstructed source saved")
|
||||
put("identity",identity); put("original",runtime.create_snapshot())
|
||||
copy_package(ProjectSettings.globalize_path(slot),directory.path_join("original/formal"))
|
||||
var live: Dictionary = runtime.create_snapshot()
|
||||
var before := packages(); put("before-members",before)
|
||||
var first: Dictionary = runtime.prepare_facility_dimension_snapshot(identity[&"jobs"][0])
|
||||
expect(first.get(&"ok",false),"earlier candidate independently migratable")
|
||||
put("first-candidate",first)
|
||||
var preview: Dictionary = runtime.preview_facility_dimensions_at_path(slot); put("preview",preview)
|
||||
var result: Dictionary = runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest",""))); put("migration",result)
|
||||
expect(var_to_bytes(live) == var_to_bytes(runtime.create_snapshot()),"live unchanged")
|
||||
put("after-live",runtime.create_snapshot())
|
||||
if refusal:
|
||||
expect(not result.get(&"ok",true) and result.get(&"details",{}).get(&"rolled_back",false) and result.get(&"details",{}).get(&"facility_id",&"") == identity[&"dorm"],"later refusal rolls back earlier candidates")
|
||||
expect(before == packages(),"original and existing backup unchanged")
|
||||
else: expect(preview.get(&"ok",false) and result.get(&"ok",false) and result.get(&"backup_created",false),"positive whole batch")
|
||||
put("after-members",packages())
|
||||
copy_package(ProjectSettings.globalize_path(slot),directory.path_join("result/formal"))
|
||||
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),directory.path_join("backup/formal"))
|
||||
else:
|
||||
registry(false); identity = get_proof("identity")
|
||||
copy_package(directory.path_join("result/formal"),ProjectSettings.globalize_path(slot))
|
||||
copy_package(directory.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
||||
var loaded := SaveService.load_snapshot(slot)
|
||||
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"formal continuation restore")
|
||||
expect(runtime.get_operations_report().get(&"enabled",false) == operations,"actual Operations mode")
|
||||
invariant(); capture("checkpoint",runtime.create_snapshot())
|
||||
expect(runtime.domain_events.subscribe(&"*",&"p08.uncapped",Callable(self,"observe")),"uncapped events")
|
||||
for minute: int in range(160):
|
||||
clock.advance_minutes(1); capture("minute-%03d" % (minute+1),runtime.create_snapshot())
|
||||
capture("events",events)
|
||||
for id: StringName in identity[&"jobs"]:
|
||||
var job: ConstructionJob = runtime.construction_service.get_job(id)
|
||||
expect(job.state == ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(job.facility_instance_id).occupied_cells.size() == (6 if refusal else 4),"paid job completes once with expected shape")
|
||||
expect(runtime.staff_service.get_staff(&"patient").health == 100,"patient treated")
|
||||
for id: StringName in identity[&"logistics_requests"]: expect(runtime.logistics_requests[id].state == LogisticsRequest.State.COMPLETED,"original cargo delivered")
|
||||
for id: StringName in identity[&"ev_requests"]:
|
||||
var count := 0
|
||||
for event: Dictionary in events:
|
||||
if event["event_type"] == "ELEVATOR_ARRIVED" and event["payload"].get(&"request_id",&"") == id: count += 1
|
||||
expect(count == 1,"original EV request completes exactly once")
|
||||
invariant()
|
||||
put(mode+"-process",{&"pid":OS.get_process_id(),&"operations":operations,&"refusal":refusal,&"checks":checks,&"failures":failures})
|
||||
return finish()
|
||||
func finish() -> Dictionary:
|
||||
runtime.free(); clock.free(); state.free()
|
||||
return {"checks":checks,"failures":failures}
|
||||
+1
@@ -0,0 +1 @@
|
||||
uid://dg5n4yme6rk4p
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
extends SceneTree
|
||||
func _initialize() -> void: call_deferred("run")
|
||||
func run() -> void:
|
||||
var fixture := preload("res://tests/fixtures/p08-02/mixed_world.gd").new()
|
||||
var result: Dictionary = fixture.run(self,OS.get_environment("P08_PAIR_ROOT"),"reader",OS.get_environment("P08_OPERATIONS") == "on",OS.get_environment("P08_CASE") == "refusal")
|
||||
print("P08 mixed reader: %d checks, %d failures" % [result.checks,result.failures])
|
||||
quit(0 if result.failures == 0 else 1)
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
uid://741t47oxl3ct
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
extends SceneTree
|
||||
func _initialize() -> void: call_deferred("run")
|
||||
func run() -> void:
|
||||
var fixture := preload("res://tests/fixtures/p08-02/mixed_world.gd").new()
|
||||
var result: Dictionary = fixture.run(self,OS.get_environment("P08_PAIR_ROOT"),"writer",OS.get_environment("P08_OPERATIONS") == "on",OS.get_environment("P08_CASE") == "refusal")
|
||||
print("P08 mixed writer: %d checks, %d failures" % [result.checks,result.failures])
|
||||
quit(0 if result.failures == 0 else 1)
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
uid://csw2850g6gjct
|
||||
@@ -0,0 +1,15 @@
|
||||
extends SceneTree
|
||||
func _initialize() -> void: call_deferred("run")
|
||||
func run() -> void:
|
||||
var checks := 0
|
||||
var failures := 0
|
||||
for operations: bool in [false,true]:
|
||||
for refusal: bool in [false,true]:
|
||||
var output := ProjectSettings.globalize_path("user://p08-suite-%d-%s-%s" % [Time.get_ticks_usec(),operations,refusal])
|
||||
for role: String in ["writer","reader"]:
|
||||
var fixture := preload("res://tests/fixtures/p08-02/mixed_world.gd").new()
|
||||
var result: Dictionary = fixture.run(self,output,role,operations,refusal)
|
||||
checks += result.checks; failures += result.failures
|
||||
if result.failures > 0: break
|
||||
print("P08 combined migration: %d checks, %d failures" % [checks,failures])
|
||||
quit(0 if failures == 0 else 1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bq08mixed02wld
|
||||
@@ -0,0 +1,369 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read-only artifact integrity gate. Success NEVER accepts original P08-02."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
HERE = Path(__file__).resolve().parent
|
||||
CONTRACT = 'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json'
|
||||
SPEC_SHA = '19f02bb7912a4d7354e565186f02366fc1d4dd698468d26142e8204fd14ebfb0'
|
||||
CONDITIONS = ('mixed_construction','occupancy_change','actual_actor_positions',
|
||||
'combined_rescue_logistics_ev','no_overlap_orphan_loss','unsolvable_preservation')
|
||||
MEMBERS = ('world.bin','manifest.json','thumbnail.png','journal.log')
|
||||
CASES = ('off-positive','off-refusal','on-positive','on-refusal')
|
||||
LABELS = ['checkpoint'] + ['minute-%03d' % n for n in range(1,161)] + ['events']
|
||||
|
||||
def sha(path): return hashlib.sha256(Path(path).read_bytes()).hexdigest()
|
||||
def load(path): return json.loads(Path(path).read_bytes())
|
||||
def module(name, path):
|
||||
spec = importlib.util.spec_from_file_location(name,path)
|
||||
obj = importlib.util.module_from_spec(spec); spec.loader.exec_module(obj); return obj
|
||||
|
||||
def decode(node):
|
||||
"""Only decode for semantic checks; whole typed nodes remain comparison authority."""
|
||||
t = node['type']
|
||||
if t == 'Dictionary':
|
||||
pairs = [(decode(k),decode(v)) for k,v in node['entries']]
|
||||
keys = [json.dumps(k,sort_keys=True) for k,v in pairs]
|
||||
if len(keys) != len(set(keys)): raise ValueError('duplicate typed dictionary key')
|
||||
return {k:v for k,v in pairs}
|
||||
if t == 'Array': return [decode(n) for n in node['items']]
|
||||
text = node['text']
|
||||
if t in ('String','StringName'): return json.loads(text.removeprefix('&'))
|
||||
if t == 'int': return int(text)
|
||||
if t == 'float': return float(text)
|
||||
if t == 'bool':
|
||||
if text not in ('true','false'): raise ValueError('invalid bool')
|
||||
return text == 'true'
|
||||
if t == 'Nil': return None
|
||||
if t in ('Vector2i','Vector3i','Vector2','Vector3'):
|
||||
match = re.fullmatch(re.escape(t)+r'\(([^()]*)\)',text)
|
||||
parts = match.group(1).split(',') if match else []
|
||||
integer = t.endswith('i')
|
||||
number = r'[+-]?[0-9]+' if integer else r'[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?'
|
||||
if len(parts) != int(t[6]) or any(not re.fullmatch(number,x.strip()) for x in parts):
|
||||
raise ValueError('invalid typed vector '+t)
|
||||
values = [(int if integer else float)(x.strip()) for x in parts]
|
||||
if not integer and not all(math.isfinite(x) for x in values):
|
||||
raise ValueError('invalid typed vector '+t)
|
||||
return values
|
||||
# Preserve unfamiliar scalar types verbatim; never silently drop them.
|
||||
return (t,text)
|
||||
|
||||
def indexed(rows, key):
|
||||
result = {row[key]:row for row in rows}
|
||||
if len(result) != len(rows): raise ValueError('duplicate '+key)
|
||||
return result
|
||||
|
||||
def semantics(snapshot, identity, initial=False):
|
||||
"""Independent ID/cell/reference checks on actual serialized Runtime state."""
|
||||
r = snapshot['systems']['runtime']
|
||||
guests = indexed(r['guests']['guests'],'guest_id')
|
||||
staff = indexed(r['staff']['staff'],'staff_id')
|
||||
if set(guests) & set(staff): raise ValueError('duplicate actor across domains')
|
||||
jobs = indexed(r['construction']['jobs'],'job_id')
|
||||
facilities = indexed(r['construction']['facilities'],'instance_id')
|
||||
operational = indexed(r['facilities']['instances'],'instance_id')
|
||||
owners = {k:v['occupied_cells'] for k,v in facilities.items()}
|
||||
owners.update({k:v['reserved_cells'] for k,v in jobs.items() if v['state'] not in ('COMPLETED','CANCELLED')})
|
||||
occupied = indexed(r['world']['occupancies'],'entity_id')
|
||||
cells = set()
|
||||
for owner,row in occupied.items():
|
||||
actual = {tuple(c) for c in row['cells']}
|
||||
if len(actual) != len(row['cells']) or cells & actual: raise ValueError('overlap occupancy')
|
||||
cells |= actual
|
||||
if owner not in owners or actual != {tuple(c) for c in owners[owner]}: raise ValueError('orphan occupancy/ownership')
|
||||
if set(owners) != set(occupied): raise ValueError('lost occupancy owner')
|
||||
for fid,facility in operational.items():
|
||||
if fid not in facilities or facility['occupied_cells'] != facilities[fid]['occupied_cells']:
|
||||
raise ValueError('operational/construction ownership mismatch')
|
||||
for jid in identity['jobs']:
|
||||
if jid not in jobs: raise ValueError('lost paid job')
|
||||
starting = jid == identity['starting_job']
|
||||
stage_ok = (jobs[jid]['progress'] == 0 and jobs[jid]['state'] == 'PLANNED') if starting else (jobs[jid]['progress'] > 0 and jobs[jid]['state'] == 'BUILDING')
|
||||
if initial and (not stage_ok or not jobs[jid]['construction_cost'] or len(jobs[jid]['reserved_cells']) != 6):
|
||||
raise ValueError('missing paid old-size progress/reservation')
|
||||
if identity['starting_job'] not in identity['jobs']: raise ValueError('missing starting stage')
|
||||
budget = identity['diagnostic_budget']
|
||||
total = {key:sum(row['cost'].get(key,0) for row in budget['costs']) for key in ('gold','materials')}
|
||||
total['gold'] += budget['signing'] + budget['food_cost']
|
||||
deficit = {key:max(0,value-budget['initial'][key]) for key,value in total.items() if value > budget['initial'][key]}
|
||||
if budget['seed'] != 42588 or budget['food_quantity'] != 8 or total != budget['needed'] or deficit != budget['deltas']:
|
||||
raise ValueError('diagnostic resource derivation mismatch')
|
||||
if len(identity['jobs']) < 2 or identity['dorm'] not in facilities: raise ValueError('mixed jobs/completed facility missing')
|
||||
tasks = indexed(r['staff']['tasks'],'task_id')
|
||||
if 'patient' not in staff or 'carrier' not in staff: raise ValueError('lost patient/carrier')
|
||||
rescue = tasks[identity['rescue_task']]
|
||||
if rescue['target_entity_id'] != 'patient' or rescue['rescue_facility_id'] not in facilities:
|
||||
raise ValueError('rescue patient/destination reference')
|
||||
if initial and (rescue['state'] != 'MOVING' or rescue['assigned_staff_id'] != 'carrier' or staff['patient']['health'] != 0):
|
||||
raise ValueError('rescue is not actually in flight')
|
||||
inventories = indexed(r['inventory']['inventories'],'owner_inventory_id')
|
||||
requests = indexed(r['logistics_requests'],'request_id')
|
||||
reservations = indexed(r['inventory']['reservations'],'reservation_id')
|
||||
if not identity['logistics_requests']: raise ValueError('missing original food request')
|
||||
for rid in identity['logistics_requests']:
|
||||
req = requests[rid]
|
||||
for endpoint in ('source_inventory_id','destination_inventory_id'):
|
||||
value = req[endpoint]
|
||||
if not value.startswith('facility.inventory:') or value.removeprefix('facility.inventory:') not in operational:
|
||||
raise ValueError('orphan cargo endpoint')
|
||||
state = req['state']
|
||||
carrier_id = req['assigned_carrier_id']
|
||||
if state == 'RESERVED' and carrier_id:
|
||||
raise ValueError('RESERVED carrier contradiction')
|
||||
if state in ('RESERVED','DELIVERING'):
|
||||
ids = req['reservation_ids']
|
||||
if not ids or len(ids) != len(set(ids)) or any(x not in reservations for x in ids):
|
||||
raise ValueError(state+' missing/duplicate reservation')
|
||||
totals = {}
|
||||
for reservation_id in ids:
|
||||
row = reservations[reservation_id]
|
||||
if (row['requester_id'] != rid or row['owner_inventory_id'] != req['source_inventory_id']
|
||||
or row['stack_id'] not in req['reserved_stack_ids']
|
||||
or row['state'] != ('ACTIVE' if state == 'RESERVED' else 'CONSUMED')
|
||||
or type(row['quantity']) is not int or row['quantity'] <= 0):
|
||||
raise ValueError(state+' reservation crosslink mismatch')
|
||||
totals[row['item_id']] = totals.get(row['item_id'],0)+row['quantity']
|
||||
if totals != req['item_requirements'] or set(req['reserved_stack_ids']) != {reservations[x]['stack_id'] for x in ids}:
|
||||
raise ValueError(state+' reservation quantity mismatch')
|
||||
if state == 'RESERVED':
|
||||
source_stacks = indexed(inventories.get(req['source_inventory_id'],{}).get('stacks',[]),'stack_id')
|
||||
for reservation_id in ids:
|
||||
row = reservations[reservation_id]; stack = source_stacks.get(row['stack_id'],{})
|
||||
if (stack.get('item_id') != row['item_id'] or stack.get('quantity',0) < row['quantity']
|
||||
or stack.get('reserved_quantity',0) < row['quantity']):
|
||||
raise ValueError('RESERVED cargo/reservation mismatch')
|
||||
else:
|
||||
carrier = staff.get(carrier_id,{})
|
||||
cargo = inventories.get(carrier.get('carried_inventory_id'),{})
|
||||
cargo_totals = {}
|
||||
for stack in cargo.get('stacks',[]):
|
||||
cargo_totals[stack['item_id']] = cargo_totals.get(stack['item_id'],0)+stack['quantity']
|
||||
if not carrier or cargo_totals != totals:
|
||||
raise ValueError('DELIVERING carrier/cargo mismatch')
|
||||
trips = indexed(r['elevators']['trips'],'request_id')
|
||||
actors = set(guests) | set(staff)
|
||||
for trip in trips.values():
|
||||
actor = trip['actor_id']
|
||||
if actor not in actors and actor.removeprefix('guest:').removeprefix('staff:') not in actors:
|
||||
raise ValueError('orphan EV actor')
|
||||
if initial:
|
||||
if len(identity['ev_requests']) != 5 or not set(identity['ev_requests']) <= set(trips): raise ValueError('lost EV request')
|
||||
if sum(len(c['boarded']) for c in r['elevators']['shafts']) != 4: raise ValueError('EV passengers/queue absent')
|
||||
if 'p08.walker' not in guests or not r['movement_credits']: raise ValueError('mid-route guest/credit absent')
|
||||
return r
|
||||
|
||||
def typed_differences(a, b, path=()):
|
||||
if a == b: return []
|
||||
if a.get('type') != b.get('type'): return [path]
|
||||
if a['type'] == 'Dictionary':
|
||||
aa = {str(decode(k)):(k,v) for k,v in a['entries']}; bb = {str(decode(k)):(k,v) for k,v in b['entries']}
|
||||
if aa.keys() != bb.keys(): return [path]
|
||||
differences = []
|
||||
for k in aa:
|
||||
if aa[k][0] != bb[k][0]: differences.append(path+(k,'@key-type'))
|
||||
differences += typed_differences(aa[k][1],bb[k][1],path+(k,))
|
||||
return differences
|
||||
if a['type'] == 'Array' and a.get('element_type') == b.get('element_type') and a.get('element_class') == b.get('element_class'):
|
||||
if len(a['items']) != len(b['items']): return [path]
|
||||
return [p for i,(x,y) in enumerate(zip(a['items'],b['items'])) for p in typed_differences(x,y,path+(str(i),))]
|
||||
return [path]
|
||||
|
||||
def migration_revisions(before, after, refusal):
|
||||
"""WorldService._mark_dirty assigns domain counters the global epoch.
|
||||
|
||||
r04: (world, occupancy, support) (144,144,142) -> (150,150,150).
|
||||
Only an actual occupancy rewrite can justify the support epoch delta.
|
||||
Whole typed comparison still rejects every other unapproved field.
|
||||
"""
|
||||
old, new = before['world']['revisions'], after['world']['revisions']
|
||||
keys = ('world','occupancy','support')
|
||||
if any(type(row[k]) is not int or row[k] < 0 for row in (old,new) for k in keys):
|
||||
raise ValueError('invalid revision epoch')
|
||||
if refusal:
|
||||
if any(old[k] != new[k] for k in keys):
|
||||
raise ValueError('refusal revision changed')
|
||||
return
|
||||
changed = before['world']['occupancies'] != after['world']['occupancies']
|
||||
if (not changed or not old['support'] <= old['world'] or not old['occupancy'] <= old['world']
|
||||
or new['world'] <= old['world'] or new['occupancy'] != new['world']
|
||||
or new['support'] != new['world'] or new['support'] < old['support']):
|
||||
raise ValueError('support epoch/occupancy mismatch')
|
||||
|
||||
# Explicit geometry changes only. No actor, economy, request, event or route wildcard.
|
||||
# This fixture deliberately places actors away from removed cells: NO route changes approved.
|
||||
GEOMETRY = [
|
||||
r'systems/runtime/world/occupancies/\d+/cells(?:/.*)?',
|
||||
r'systems/runtime/world/dirty_cells(?:/.*)?',
|
||||
r'systems/runtime/world/revisions/(world|occupancy)',
|
||||
r'systems/runtime/construction/jobs/\d+/reserved_cells(?:/.*)?',
|
||||
r'systems/runtime/construction/facilities/\d+/occupied_cells(?:/.*)?',
|
||||
r'systems/runtime/facilities/instances/\d+/occupied_cells(?:/.*)?',
|
||||
]
|
||||
|
||||
def check(project_root, evidence_dir):
|
||||
root, evidence = Path(project_root).resolve(), Path(evidence_dir).resolve()
|
||||
deficits = []
|
||||
def need(ok, reason):
|
||||
if not ok: deficits.append(reason)
|
||||
def guarded(label, fn):
|
||||
try: return fn()
|
||||
except (KeyError,ValueError,TypeError,OSError,IndexError,AttributeError) as exc:
|
||||
deficits.append(label+': '+str(exc)); return None
|
||||
index = guarded('index',lambda:load(evidence/'index.json'))
|
||||
if not isinstance(index,dict): return deficits or ['index is not an object']
|
||||
def artifact(name):
|
||||
if not isinstance(name,str) or Path(name).is_absolute() or '..' in Path(name).parts: raise ValueError('unsafe artifact path')
|
||||
path = evidence/name
|
||||
if not path.is_file() or any(p.is_symlink() for p in [path,*path.parents] if p != evidence.parent): raise ValueError('missing/aliased artifact '+name)
|
||||
pin = index['artifacts'][name]
|
||||
if pin != {'bytes':path.stat().st_size,'sha256':sha(path)}: raise ValueError('artifact hash '+name)
|
||||
return path
|
||||
def document(name): return load(artifact(name))
|
||||
need(index.get('schema') == 'p08-evidence-v1','schema')
|
||||
need(index.get('acceptance') == 'pending','integrity is not unit acceptance')
|
||||
need(index.get('collection_error') is None,'collection failure')
|
||||
def source_gate():
|
||||
runner = module('p08_readonly_source',root/'tools/run_all_tests.py')
|
||||
actual = {n:p['sha256'] for n,p in runner.source_refs(root).items()}
|
||||
need(index['source_map'] == actual,'wrong/stale/incomplete final source map')
|
||||
spec = load(root/'docs/spec/acceptance/P08-02.json')
|
||||
need(index['spec_sha256'] == SPEC_SHA == hashlib.sha256((root/'docs/spec/acceptance/P08-02.json').read_text().strip().encode()).hexdigest(),'frozen spec SHA')
|
||||
for name,pin in spec['current_source_pins'].items(): need(actual.get(name) == pin,'frozen production source '+name)
|
||||
inputs = {str(p.relative_to(root)):sha(p) for p in (root/'docs/spec/inputs/p08-02').iterdir() if p.is_file()}
|
||||
need(index['inputs'] == inputs,'frozen input map')
|
||||
need(index['marker_contract_sha256'] == sha(root/CONTRACT),'marker contract source')
|
||||
need(re.fullmatch('[0-9a-f]{40}',index['commit']) is not None,'submitted commit identity')
|
||||
guarded('source',source_gate)
|
||||
for name in index.get('artifacts',{}): guarded('artifact '+name,lambda name=name:artifact(name))
|
||||
markers = module('p08_evidence_markers',root/'tools/strict_test_markers.py')
|
||||
contracts = markers.load_contracts(root/CONTRACT)
|
||||
pids = set()
|
||||
def phase(name, role):
|
||||
receipt = document(name); pid = receipt['actual_pid']
|
||||
need(type(pid) is int and pid > 0 and pid not in pids,'distinct native PID '+name); pids.add(pid)
|
||||
parent = str(Path(name).parent)
|
||||
prefix = '' if parent == '.' else parent+'/'
|
||||
folder = prefix+receipt['phase']+'/'
|
||||
start,end,outer = [document(folder+n) for n in ('started.json','ended.json','outer-owned-finally.json')]
|
||||
for row in (start,end):
|
||||
need(row['actual_pid'] == pid and row['command'] == receipt['command'],'raw lifecycle PID/argv '+name)
|
||||
need(end.get('exit_code') == 0 and end.get('engine_ended') is True,'ended exit '+name)
|
||||
need(start.get('live_identity_exact') is True or start.get('tracked_child_ended_before_initial_probe') is True,'native Popen identity '+name)
|
||||
need(outer['actual_captured_pids'] == [pid] and outer['all_captured_ended'] is True and not outer['outer_cleanup_errors'] and outer['foreign_process_or_group_signals'] == 0,'owned cleanup '+name)
|
||||
native = receipt['native_process']
|
||||
need(native['exit_code'] == 0 and native['helper_exit_code'] == 0 and native['timed_out'] is False and native['lifecycle_error'] is None,'native exit/errors '+name)
|
||||
need(receipt['exit_code'] == 0 and receipt['engine_ended'] is True,'phase ended '+name)
|
||||
if role:
|
||||
test = 'tests/fixtures/p08-02/'+role+'.gd'
|
||||
need(receipt['test'] == test and receipt['source_sha256'] == index['source_map'][test],'phase source '+name)
|
||||
raw = artifact(prefix+receipt['log']).read_text()
|
||||
parsed = markers.parse_raw(test,raw,{test:{'template':'P08 mixed '+role+': <checks> checks, <failures> failures'}},receipt['source_sha256'])
|
||||
need(not parsed['errors'],'strict completion '+name+': '+str(parsed['errors']))
|
||||
profile = receipt['actual_private_profile']['report']
|
||||
need(profile['fresh_before_parent_initialize'] is True and profile['profile_writes_before_guard'] == 0 and profile['actual_user_data_dir'] == profile['expected_user_data_dir'],'guarded fresh profile '+name)
|
||||
return receipt
|
||||
def case_gate(case):
|
||||
name = case['id']; prefix = case['directory']+'/'
|
||||
need(name == case['operations']+'-'+case['kind'],'case identity '+name)
|
||||
need(len(case['phases']) == 2,'writer and reader phases '+name)
|
||||
receipts = [phase(n,r) for n,r in zip(case['phases'],('writer','reader'))]
|
||||
def typed(name):
|
||||
artifact(prefix+name+'.var')
|
||||
return document(prefix+name+'.json')
|
||||
identity = decode(typed('identity'))
|
||||
original = typed('original'); after_live = typed('after-live')
|
||||
need(original == after_live,'live partial batch '+name)
|
||||
before_members,after_members = [decode(typed(n)) for n in ('before-members','after-members')]
|
||||
for package in ('original','result','backup'):
|
||||
for member in MEMBERS: artifact(prefix+package+'/formal/'+member)
|
||||
for member in MEMBERS:
|
||||
need(before_members['/'+member] == sha(artifact(prefix+'original/formal/'+member)),'original overwritten '+name+'/'+member)
|
||||
need(after_members['/'+member] == sha(artifact(prefix+'result/formal/'+member)),'result member '+name+'/'+member)
|
||||
need(after_members['.pre_migration.bak/'+member] == sha(artifact(prefix+'backup/formal/'+member)),'backup overwritten '+name+'/'+member)
|
||||
refusal = case['kind'] == 'refusal'
|
||||
if refusal: need(before_members == after_members,'refusal original/backup overwritten '+name)
|
||||
source = semantics(decode(original),identity,True)
|
||||
need(source['operations']['enabled'] == (case['operations']=='on'),'missing actual Operations mode '+name)
|
||||
for role,receipt in zip(('writer','reader'),receipts):
|
||||
proc = decode(typed(role+'-process'))
|
||||
need(proc['pid'] == receipt['actual_pid'] and proc['failures'] == 0 and proc['operations'] == (case['operations']=='on') and proc['refusal'] == refusal,'fixture/native binding '+name+'/'+role)
|
||||
checkpoint = typed('writer-checkpoint')
|
||||
migrated = decode(checkpoint)['systems']['runtime']
|
||||
migration_revisions(source,migrated,refusal)
|
||||
if refusal: need(original == checkpoint,'partial earlier candidate '+name)
|
||||
else:
|
||||
for path in typed_differences(original,checkpoint):
|
||||
support_epoch = path == ('systems','runtime','world','revisions','support')
|
||||
need(support_epoch or any(re.fullmatch(pattern,'/'.join(path)) for pattern in GEOMETRY),'unapproved typed migration delta '+name+'/'+ '/'.join(path))
|
||||
migrated = decode(checkpoint)['systems']['runtime']
|
||||
jobs = indexed(migrated['construction']['jobs'],'job_id')
|
||||
need(all(len(jobs[j]['reserved_cells']) == 4 for j in identity['jobs']),'positive batch not applied '+name)
|
||||
for label in LABELS:
|
||||
writer,reader = typed('writer-'+label),typed('reader-'+label)
|
||||
need(writer == reader,'cross-PID full typed state/events '+name+'/'+label)
|
||||
need(sha(artifact(prefix+'writer-'+label+'.var')) == sha(artifact(prefix+'reader-'+label+'.var')),'cross-PID raw Variant '+name+'/'+label)
|
||||
if label != 'events': semantics(decode(writer),identity)
|
||||
final = decode(typed('writer-minute-160'))['systems']['runtime']
|
||||
need(indexed(final['staff']['staff'],'staff_id')['patient']['health'] == 100,'patient lost/untreated '+name)
|
||||
final_requests = indexed(final['logistics_requests'],'request_id')
|
||||
need(all(final_requests[i]['state']=='COMPLETED' for i in identity['logistics_requests']),'original cargo completion '+name)
|
||||
events = decode(typed('writer-events'))
|
||||
for rid in identity['ev_requests']:
|
||||
need(sum(e['event_type']=='ELEVATOR_ARRIVED' and e['payload'].get('request_id')==rid for e in events)==1,'EV original request exactly once '+name+'/'+rid)
|
||||
cases = index.get('cases',[])
|
||||
need([c.get('id') for c in cases] == list(CASES),'missing/duplicate ON/OFF positive/refusal case')
|
||||
for case in cases: guarded('case '+str(case.get('id')),lambda case=case:case_gate(case))
|
||||
for condition in CONDITIONS:
|
||||
expected = [c for c in CASES if condition != 'unsolvable_preservation' or c.endswith('refusal')]
|
||||
need(index.get('conditions',{}).get(condition) == expected,'condition mapping '+condition)
|
||||
def os_gate():
|
||||
proof = document(index['os_proof'])
|
||||
need(proof['commit'] == index['commit'] and proof['source_map'] == index['source_map'],'OS current candidate')
|
||||
need(proof['input_method'] == 'native_os' and proof['setup'] == 'controlled_old_save','OS input provenance/setup')
|
||||
actions = proof['actions']
|
||||
need([a['action'] for a in actions] == ['preview','cancel','confirm','changed_source_rejection'],'OS actions missing')
|
||||
for action in actions:
|
||||
raw = document(action['input_receipt'])
|
||||
need(raw['method'] == 'native_os' and raw['event_type'] in ('mouse','keyboard') and type(raw['target_pid']) is int and raw['target_pid'] > 0 and raw['timestamp_ns'] > 0,'fake OS signal')
|
||||
for key in ('screen_before','screen_after','model_before','model_after','formal_before','formal_after'): artifact(action[key])
|
||||
if action['action'] in ('preview','cancel','changed_source_rejection'):
|
||||
need(document(action['formal_before']) == document(action['formal_after']),'OS formal preservation '+action['action'])
|
||||
guarded('OS proof',os_gate)
|
||||
def regression_gate():
|
||||
proof = document(index['regression']); run_input = document(proof['input']); ended = document(proof['ended'])
|
||||
need(run_input['selected_source_map'] == index['source_map'],'final regression source map')
|
||||
need(proof['commit'] == index['commit'],'final regression commit')
|
||||
need(not ended['error'] and not ended['cleanup_errors'] and not ended['guard_errors'],'regression failure')
|
||||
runner = module('p08_regression_roster',root/'tools/run_all_tests.py')
|
||||
roster = runner.roster(root)
|
||||
need(run_input['roster'] == roster,'full final roster')
|
||||
rows = [x for x in ended['phases'] if x.get('test')]
|
||||
need([x['test'] for x in rows] == roster,'full final regression receipt')
|
||||
for row in rows:
|
||||
raw = artifact(proof['directory']+'/'+row['log']).read_text()
|
||||
need(not markers.parse_raw(row['test'],raw,contracts,index['source_map'][row['test']])['errors'],'regression strict '+row['test'])
|
||||
need(row['exit_code'] == 0 and row['engine_ended'] is True,'regression native exit '+row['test'])
|
||||
guarded('final regression',regression_gate)
|
||||
return sorted(set(deficits))
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--verify-only',action='store_true',required=True)
|
||||
parser.add_argument('--project-root',type=Path,default=HERE.parent)
|
||||
args = parser.parse_args(argv)
|
||||
build = os.environ.get('BUILD_OUTPUT_DIR')
|
||||
deficits = ['BUILD_OUTPUT_DIR missing'] if not build else check(args.project_root,Path(build)/'p08-evidence')
|
||||
print(json.dumps({'integrity':'deficient' if deficits else 'verified','deficits':deficits,
|
||||
'acceptance':'pending','conditions':{c:'pending' for c in CONDITIONS}},ensure_ascii=False,indent=2))
|
||||
return 1 if deficits else 0
|
||||
|
||||
if __name__ == '__main__': raise SystemExit(main())
|
||||
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Root-only native collection. Does not run regression or claim acceptance."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
HERE = Path(__file__).resolve().parent
|
||||
CONTRACT = 'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json'
|
||||
CONDITIONS = ('mixed_construction', 'occupancy_change', 'actual_actor_positions',
|
||||
'combined_rescue_logistics_ev', 'no_overlap_orphan_loss', 'unsolvable_preservation')
|
||||
|
||||
def module(name, path):
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
obj = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(obj)
|
||||
return obj
|
||||
|
||||
def absolute(value):
|
||||
path = Path(value)
|
||||
if not path.is_absolute():
|
||||
raise argparse.ArgumentTypeError('absolute path required')
|
||||
return path.resolve()
|
||||
|
||||
def collect(args):
|
||||
root, out = args.project_root, args.output
|
||||
r = module('p08_standard_runner', root/'tools/run_all_tests.py')
|
||||
commit = subprocess.check_output(['git', '-C', str(root), 'rev-parse', 'HEAD'], text=True).strip()
|
||||
r.require(commit == args.commit, 'actual final submitted commit required')
|
||||
r.require(not out.exists(), 'fresh output; never overwrite earlier proof')
|
||||
refs = r.source_refs(root)
|
||||
outer = r.module('p08_owned_outer', r.SUPPORT/'owned_outer.py')
|
||||
r.require(not outer.native.helper['live_engines'](), 'one native engine')
|
||||
engine = shutil.which(args.godot)
|
||||
r.require(engine is not None, 'native engine exists')
|
||||
engine = str(Path(engine).resolve())
|
||||
out.mkdir(parents=True)
|
||||
stage = out/'stage'; stage.mkdir()
|
||||
(out/'starters').mkdir(); (out/'bootstrap').mkdir()
|
||||
for name, pin in r.read(r.SUPPORT/'bootstrap-scripts.json').items():
|
||||
data = pin['text'].encode()
|
||||
r.require(hashlib.sha256(data).hexdigest() == pin['sha256'], 'bootstrap pin')
|
||||
(out/'bootstrap'/name).write_bytes(data)
|
||||
for name, pin in refs.items():
|
||||
target = stage/name; target.parent.mkdir(parents=True, exist_ok=True)
|
||||
r.copy_source(Path(pin['path']), target)
|
||||
r.require(r.sha(target) == pin['sha256'], 'whole copied source '+name)
|
||||
expected = {n: {'bytes':v['bytes'], 'sha256':v['sha256']} for n,v in refs.items()}
|
||||
selected = {'root_before':refs, 'map':{n:v['sha256'] for n,v in refs.items()}, 'timeout':180}
|
||||
r.require(r.inventory(stage, stage=True) == expected, 'complete private source')
|
||||
protected = r.default_player(root); public = (stage/'project.godot').read_bytes()
|
||||
paths = ['res://'+n for n in sorted(refs) if n.endswith('.gd')]
|
||||
r.write(out/'parse-paths.json', paths)
|
||||
markers = r.module('p08_strict_markers', root/'tools/strict_test_markers.py')
|
||||
contracts = markers.load_contracts(root/CONTRACT)
|
||||
for role in ('writer','reader'):
|
||||
name = 'tests/fixtures/p08-02/'+role+'.gd'
|
||||
contracts[name] = {'test':name, 'template':'P08 mixed '+role+': <checks> checks, <failures> failures', 'required':True}
|
||||
policy = r.read(r.SUPPORT/'suite-policy.json')
|
||||
diagnostics = r.module('p08_diagnostics', r.SUPPORT/'diagnostic_gate.py')
|
||||
owners = r.module('p08_owners', r.SUPPORT/'ordinary_proof_gate.py')
|
||||
audio = r.module('p08_audio', r.SUPPORT/'audio_evidence_gate.py')
|
||||
r.write(out/'runner-input.json', {'protocol':'p08-mixed-v1', 'commit':commit,
|
||||
'selected_source_map':selected['map'], 'engine':engine, 'engine_sha256':r.sha(engine),
|
||||
'owner_pid':os.getpid(), 'default_player':protected, 'diagnostic_seed':42588})
|
||||
phases = []; previous = {}; cases = []; error = None
|
||||
deadline = time.monotonic()+900
|
||||
saved_env = {k:os.environ.get(k) for k in ('P08_PAIR_ROOT','P08_OPERATIONS','P08_CASE')}
|
||||
def phase(label, test):
|
||||
remaining = int(deadline-time.monotonic())
|
||||
r.require(remaining >= (180 if label == 'import' else 1), '900s collection deadline')
|
||||
selected['timeout'] = min(180,remaining)
|
||||
phase_out = out/'runs'/label
|
||||
phase_out.mkdir(parents=True)
|
||||
(phase_out/'starters').mkdir(); (phase_out/'bootstrap').mkdir()
|
||||
for original in (out/'bootstrap').iterdir():
|
||||
r.copy_source(original,phase_out/'bootstrap'/original.name)
|
||||
r.require(r.sha(original)==r.sha(phase_out/'bootstrap'/original.name),'bootstrap full copy')
|
||||
r.write(phase_out/'parse-paths.json',paths)
|
||||
row = r.execute_phase(engine, stage, phase_out, label, test, selected, expected, previous,
|
||||
policy, contracts, paths, public, protected, root, outer, markers, diagnostics, owners, audio)
|
||||
phases.append('runs/'+label+'/'+label+'-receipt.json')
|
||||
r.require(not row['failed'], 'strict phase failed: '+label)
|
||||
try:
|
||||
phase('import', None); phase('parse', None)
|
||||
for operations in ('off','on'):
|
||||
for case in ('positive','refusal'):
|
||||
name = operations+'-'+case; pair = out/'pairs'/name
|
||||
os.environ.update(P08_PAIR_ROOT=str(pair), P08_OPERATIONS=operations, P08_CASE=case)
|
||||
case_phases = []
|
||||
preserved = {}
|
||||
for role in ('writer','reader'):
|
||||
label = name+'-'+role
|
||||
test = 'tests/fixtures/p08-02/'+role+'.gd'
|
||||
phase(label, test)
|
||||
actual = r.inventory(pair)
|
||||
r.require(all(actual.get(n) == pin for n,pin in preserved.items()), 'reader preserved every writer byte')
|
||||
preserved = actual
|
||||
case_phases.append(phases[-1])
|
||||
cases.append({'id':name, 'operations':operations, 'kind':case,
|
||||
'directory':'pairs/'+name, 'phases':case_phases, 'files':preserved})
|
||||
except BaseException as caught:
|
||||
error = type(caught).__name__+': '+str(caught)
|
||||
finally:
|
||||
cleanup, cleanup_errors = outer.finish_captured(outer.OWNED)
|
||||
for key,value in saved_env.items():
|
||||
if value is None: os.environ.pop(key, None)
|
||||
else: os.environ[key] = value
|
||||
r.require(r.source_refs(root) == refs and r.default_player(root) == protected, 'protected root/profile unchanged')
|
||||
r.write(out/'runner-ended.json', {'error':error, 'cleanup':cleanup, 'cleanup_errors':cleanup_errors,
|
||||
'phases':phases, 'formal_acceptance':False, 'native_Windows':'pending'})
|
||||
inputs = {str(p.relative_to(root)):r.sha(p) for p in (root/'docs/spec/inputs/p08-02').iterdir() if p.is_file()}
|
||||
# The collector is intentionally incomplete until Root supplies OS and regression artifacts.
|
||||
r.write(out/'index.json', {'schema':'p08-evidence-v1', 'commit':commit,
|
||||
'source_map':selected['map'], 'inputs':inputs, 'marker_contract_sha256':r.sha(root/CONTRACT),
|
||||
'spec_sha256':hashlib.sha256((root/'docs/spec/acceptance/P08-02.json').read_text().strip().encode()).hexdigest(),
|
||||
'cases':cases, 'phases':phases, 'conditions':{c:[x['id'] for x in cases if c != 'unsolvable_preservation' or x['kind']=='refusal'] for c in CONDITIONS},
|
||||
'artifacts':{str(p.relative_to(out)):{'bytes':p.stat().st_size,'sha256':r.sha(p)}
|
||||
for p in out.rglob('*') if p.is_file() and 'stage' not in p.relative_to(out).parts},
|
||||
'os_proof':None, 'regression':None,
|
||||
'acceptance':'pending', 'collection_error':error})
|
||||
return 1 if error or cleanup_errors else 0
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--project-root', type=absolute, required=True)
|
||||
parser.add_argument('--output', type=absolute, required=True)
|
||||
parser.add_argument('--commit', required=True)
|
||||
parser.add_argument('--godot', default='godot')
|
||||
parser.add_argument('--collect', action='store_true', required=True)
|
||||
return collect(parser.parse_args(argv))
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,264 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Synthetic evidence ONLY: disposable end-to-end check() positives and corruptions.
|
||||
|
||||
No Godot/OS execution, no actual acceptance proof. Mutations update hashes so the
|
||||
semantic gate, not merely a stale digest, must reject invalid state.
|
||||
"""
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
import check_p08_migration_evidence as c
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
BANNER = 'Godot Engine v4.7.2.stable.official.ed1daf0bf - https://godotengine.org\n'
|
||||
R04 = json.loads((ROOT/'docs/plans/original-completion-2026-10-02/execution/p08-02/ROOT_REPAIR_INPUT-r04.json').read_text())
|
||||
ACTUAL = R04['actual_readonly_diagnostics']
|
||||
REQUESTS = ACTUAL['CARGO_ENDPOINT_READONLY_DIAGNOSTIC.json'][0]['requests']
|
||||
REVISIONS = ACTUAL['ACTUAL_WORLD_REVISION_DELTAS.json'][0]
|
||||
|
||||
def typed(value):
|
||||
if isinstance(value,tuple): return {'type':'Vector3i','text':'Vector3i('+', '.join(map(str,value))+')'}
|
||||
if isinstance(value,dict): return {'type':'Dictionary','entries':[[typed(k),typed(v)] for k,v in value.items()]}
|
||||
if isinstance(value,list): return {'type':'Array','element_type':0,'element_class':'','items':[typed(x) for x in value]}
|
||||
kind = 'Nil' if value is None else 'bool' if type(value) is bool else 'int' if type(value) is int else 'String'
|
||||
return {'type':kind,'text':json.dumps(value)}
|
||||
|
||||
class Proof:
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
runner = c.module('p08_synthetic_source',ROOT/'tools/run_all_tests.py')
|
||||
self.runner = runner
|
||||
source = {n:p['sha256'] for n,p in runner.source_refs(ROOT).items()}
|
||||
self.index = {'schema':'p08-evidence-v1','commit':'e196578c1a4ad2fdf84642565bd102e524be386f',
|
||||
'source_map':source,'spec_sha256':c.SPEC_SHA,'marker_contract_sha256':c.sha(ROOT/c.CONTRACT),
|
||||
'inputs':{str(p.relative_to(ROOT)):c.sha(p) for p in (ROOT/'docs/spec/inputs/p08-02').iterdir() if p.is_file()},
|
||||
'cases':[],'conditions':{k:[x for x in c.CASES if k!='unsolvable_preservation' or x.endswith('refusal')] for k in c.CONDITIONS},
|
||||
'artifacts':{},'acceptance':'pending','collection_error':None,'phases':[],
|
||||
'os_proof':'os.json','regression':'regression.json'}
|
||||
for number,name in enumerate(c.CASES): self.case(name,number)
|
||||
self.os(); self.regression(); self.save()
|
||||
def put(self,name,value):
|
||||
path = self.path/name; path.parent.mkdir(parents=True,exist_ok=True)
|
||||
path.write_bytes(value if isinstance(value,bytes) else json.dumps(value).encode())
|
||||
self.index['artifacts'][name] = {'bytes':path.stat().st_size,'sha256':c.sha(path)}
|
||||
def variant(self,prefix,name,value):
|
||||
node = typed(value)
|
||||
self.put(prefix+name+'.json',node)
|
||||
# Deliberately not a native Variant: this is an isolated Python proof fixture.
|
||||
self.put(prefix+name+'.var',json.dumps(node).encode())
|
||||
def save(self): (self.path/'index.json').write_text(json.dumps(self.index))
|
||||
def state(self,operations):
|
||||
jobs = [{'job_id':j,'state':'PLANNED' if j=='j2' else 'BUILDING','progress':0 if j=='j2' else 1266,'reserved_cells':[(x,2,0) for x in range(offset,offset+6)],'construction_cost':{'gold':1}}
|
||||
for j,offset in [('j1',0),('j2',10)]]
|
||||
facilities = [{'instance_id':'dorm','occupied_cells':[[30,0,1]]},{'instance_id':'clinic','occupied_cells':[[31,0,1]]}]
|
||||
facilities += [{'instance_id':'facility_00000005','occupied_cells':[(32,0,1)]},
|
||||
{'instance_id':'facility_00000006','occupied_cells':[(33,0,1)]}]
|
||||
guests = [{'guest_id':g} for g in ['p08.walker']+['g'+str(n) for n in range(5)]]
|
||||
staff = [{'staff_id':'patient','health':0},{'staff_id':'carrier'},{'staff_id':'staff_gina','carried_inventory_id':'cargo:staff_gina'}]
|
||||
r = {'operations':{'enabled':operations},'guests':{'guests':guests},'staff':{'staff':staff,'tasks':[
|
||||
{'task_id':'rescue','target_entity_id':'patient','rescue_facility_id':'clinic','state':'MOVING','assigned_staff_id':'carrier'}]},
|
||||
'construction':{'jobs':jobs,'facilities':facilities},'facilities':{'instances':copy.deepcopy(facilities)},
|
||||
'world':{'revisions':copy.deepcopy(REVISIONS['original_world_revisions']),'occupancies':[{'entity_id':j['job_id'],'cells':copy.deepcopy(j['reserved_cells'])} for j in jobs]+
|
||||
[{'entity_id':f['instance_id'],'cells':copy.deepcopy(f['occupied_cells'])} for f in facilities]},
|
||||
'inventory':{'inventories':[{'owner_inventory_id':owner,'stacks':[{'stack_id':stack,'item_id':'ingredient/raw_food','quantity':4,'reserved_quantity':reserved}]} for owner,stack,reserved in
|
||||
[('facility.inventory:facility_00000005','stack_00000001',4),('cargo:staff_gina','stack_00000002',0)]],
|
||||
'reservations':[{'reservation_id':req['reservation_ids'][0],'requester_id':req['request_id'],
|
||||
'owner_inventory_id':req['source_inventory_id'],'stack_id':'stack_00000001','item_id':'ingredient/raw_food',
|
||||
'quantity':4,'state':'CONSUMED' if req['state']=='DELIVERING' else 'ACTIVE'} for req in REQUESTS]},
|
||||
'logistics_requests':copy.deepcopy(REQUESTS),
|
||||
'movement_credits':[{'credit':1000}],
|
||||
'elevators':{'trips':[{'request_id':'ev'+str(n),'actor_id':'g'+str(n)} for n in range(5)],'shafts':[{'boarded':['g0','g1','g2','g3']}]}}
|
||||
return {'systems':{'runtime':r}}
|
||||
def phase(self,name,role,pid):
|
||||
folder = 'runs/'+name+'/'; test = 'tests/fixtures/p08-02/'+role+'.gd'
|
||||
command = ['synthetic-native','--script',test]
|
||||
start = {'actual_pid':pid,'command':command,'live_identity_exact':True,'event':'ENGINE_STARTED','owner_pid':1,'monotonic_ns':1}
|
||||
end = dict(start,event='ENGINE_ENDED',monotonic_ns=2,exit_code=0,engine_ended=True)
|
||||
self.put(folder+name+'/started.json',start); self.put(folder+name+'/ended.json',end)
|
||||
self.put(folder+name+'/outer-owned-finally.json',{'actual_captured_pids':[pid],'all_captured_ended':True,'outer_cleanup_errors':[],'foreign_process_or_group_signals':0})
|
||||
self.put(folder+'raw.log',(BANNER+'P08 mixed '+role+': 1 checks, 0 failures\n').encode())
|
||||
receipt = {'phase':name,'actual_pid':pid,'command':command,'exit_code':0,'engine_ended':True,'test':test,
|
||||
'source_sha256':self.index['source_map'][test],'log':'raw.log',
|
||||
'native_process':{'exit_code':0,'helper_exit_code':0,'timed_out':False,'lifecycle_error':None},
|
||||
'actual_private_profile':{'report':{'fresh_before_parent_initialize':True,'profile_writes_before_guard':0,'actual_user_data_dir':'diagnostic-private-'+name,'expected_user_data_dir':'diagnostic-private-'+name}}}
|
||||
self.put(folder+name+'-receipt.json',receipt)
|
||||
return folder+name+'-receipt.json'
|
||||
def case(self,name,number):
|
||||
operations = name.startswith('on-'); refusal = name.endswith('refusal'); prefix = 'pairs/'+name+'/'
|
||||
phases = [self.phase(name+'-'+role,role,100+2*number+i) for i,role in enumerate(('writer','reader'))]
|
||||
self.index['cases'].append({'id':name,'operations':'on' if operations else 'off','kind':'refusal' if refusal else 'positive','directory':prefix[:-1],'phases':phases})
|
||||
self.index['phases'] += phases
|
||||
identity = {'starting_job':'j2','diagnostic_budget':{'seed':42588,'food_quantity':8,'food_cost':24,'signing':1,'costs':[{'cost':{'gold':2,'materials':1}}],'initial':{'gold':0,'materials':0},'needed':{'gold':27,'materials':1},'deltas':{'gold':27,'materials':1}},'jobs':['j1','j2'],'dorm':'dorm','rescue_task':'rescue','logistics_requests':['food'],'ev_requests':['ev'+str(n) for n in range(5)]}
|
||||
identity['logistics_requests'] = [req['request_id'] for req in REQUESTS]
|
||||
original = self.state(operations)
|
||||
self.variant(prefix,'identity',identity); self.variant(prefix,'original',original); self.variant(prefix,'after-live',original)
|
||||
before = {}; after = {}
|
||||
for member in c.MEMBERS:
|
||||
raw = ('synthetic '+member).encode()
|
||||
for package in ('original','result','backup'): self.put(prefix+package+'/formal/'+member,raw)
|
||||
before['/'+member] = after['/'+member] = hashlib.sha256(raw).hexdigest()
|
||||
before['.pre_migration.bak/'+member] = after['.pre_migration.bak/'+member] = hashlib.sha256(raw).hexdigest()
|
||||
self.variant(prefix,'before-members',before); self.variant(prefix,'after-members',after)
|
||||
checkpoint = copy.deepcopy(original)
|
||||
if not refusal:
|
||||
r = checkpoint['systems']['runtime']
|
||||
r['world']['revisions'] = copy.deepcopy(REVISIONS['checkpoint_world_revisions'])
|
||||
for job in r['construction']['jobs']: job['reserved_cells'] = job['reserved_cells'][:4]
|
||||
for row in r['world']['occupancies'][:2]: row['cells'] = row['cells'][:4]
|
||||
events = [{'event_type':'ELEVATOR_ARRIVED','payload':{'request_id':rid}} for rid in identity['ev_requests']]
|
||||
for i,role in enumerate(('writer','reader')):
|
||||
self.variant(prefix,role+'-process',{'pid':100+2*number+i,'failures':0,'checks':1,'operations':operations,'refusal':refusal})
|
||||
for label in c.LABELS:
|
||||
state = copy.deepcopy(checkpoint)
|
||||
if label == 'minute-160':
|
||||
state['systems']['runtime']['staff']['staff'][0]['health'] = 100
|
||||
for req in state['systems']['runtime']['logistics_requests']: req['state'] = 'COMPLETED'
|
||||
self.variant(prefix,role+'-'+label,events if label=='events' else state)
|
||||
def os(self):
|
||||
proof = {'commit':self.index['commit'],'source_map':self.index['source_map'],'input_method':'native_os','setup':'controlled_old_save','actions':[]}
|
||||
for name in ('preview','cancel','confirm','changed_source_rejection'):
|
||||
row = {'action':name,'input_receipt':'os/'+name+'/input.json'}
|
||||
self.put(row['input_receipt'],{'method':'native_os','event_type':'mouse','target_pid':500,'timestamp_ns':1})
|
||||
for field in ('screen_before','screen_after','model_before','model_after','formal_before','formal_after'):
|
||||
row[field] = 'os/'+name+'/'+field+'.json'; self.put(row[field],{'synthetic':'diagnostic'})
|
||||
proof['actions'].append(row)
|
||||
self.put('os.json',proof)
|
||||
def regression(self):
|
||||
contracts = c.module('p08_synthetic_markers',ROOT/'tools/strict_test_markers.py').load_contracts(ROOT/c.CONTRACT)
|
||||
roster = self.runner.roster(ROOT); rows = []
|
||||
for i,test in enumerate(roster):
|
||||
contract = contracts[test]
|
||||
def marker(template):
|
||||
for key in ('checks','passed'): template = template.replace('<'+key+'>','1')
|
||||
for key in ('failures','failed','skipped'): template = template.replace('<'+key+'>','0')
|
||||
return template+'\n'
|
||||
raw = BANNER+marker(contract['template'])
|
||||
for auxiliary in contract.get('auxiliary',[]): raw += marker(auxiliary['template'])
|
||||
if contract.get('json_report'):
|
||||
raw += contract['json_report']['prefix']+json.dumps({'check_summary':{'total':1,'passed':1,'failed':0,'skipped':0},'status':'PASS','runtime_errors':[],'unmet_fixture_fields':[]})+'\n'
|
||||
log = str(i)+'.log'; self.put('regression/'+log,raw.encode())
|
||||
rows.append({'test':test,'log':log,'exit_code':0,'engine_ended':True})
|
||||
self.put('regression/input.json',{'selected_source_map':self.index['source_map'],'roster':roster})
|
||||
self.put('regression/ended.json',{'error':None,'cleanup_errors':[],'guard_errors':[],'phases':rows})
|
||||
self.put('regression.json',{'commit':self.index['commit'],'directory':'regression','input':'regression/input.json','ended':'regression/ended.json'})
|
||||
|
||||
class EvidenceTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.temp = tempfile.TemporaryDirectory(prefix='p08-checker-')
|
||||
cls.proof = Proof(Path(cls.temp.name))
|
||||
cls.baseline = copy.deepcopy(cls.proof.index)
|
||||
@classmethod
|
||||
def tearDownClass(cls): cls.temp.cleanup()
|
||||
def test_positive_reaches_whole_check(self):
|
||||
self.assertEqual(c.check(ROOT,self.proof.path),[])
|
||||
def test_strict_native_vectors(self):
|
||||
for kind,good,expected in (
|
||||
('Vector3i','Vector3i(0, -12, 6)',[0,-12,6]),
|
||||
('Vector2i','Vector2i(-2, 3)',[-2,3]),
|
||||
('Vector3','Vector3(1.5, -2e1, .25)',[1.5,-20,.25]),
|
||||
('Vector2','Vector2(0, 1e-3)',[0,.001])):
|
||||
with self.subTest(kind=kind):
|
||||
self.assertEqual(c.decode({'type':kind,'text':good}),expected)
|
||||
invalid = [good.replace(kind,'WrongVector'),good+'tail',good.replace(',',',,',1),
|
||||
good[:good.rfind(',')]+')',good.replace(')',', 4)')]
|
||||
if kind.endswith('i'): invalid += [good.replace('(', '(1.0,',1), kind+'(1.0, '+', '.join(['2']*(len(expected)-1))+')']
|
||||
for text in invalid:
|
||||
with self.subTest(text=text), self.assertRaisesRegex(ValueError,'invalid typed vector'):
|
||||
c.decode({'type':kind,'text':text})
|
||||
|
||||
def test_r04_local_deficits_through_whole_check(self):
|
||||
p = self.proof
|
||||
def mutate_state(node, change):
|
||||
state = c.decode(node); change(state['systems']['runtime']); return typed(state)
|
||||
def bad_vector(node):
|
||||
if node['type'] == 'Vector3i':
|
||||
node['text'] = 'Vector3i(0, , 1)'; return True
|
||||
children = ([n for pair in node['entries'] for n in pair] if node['type']=='Dictionary'
|
||||
else node.get('items',[]))
|
||||
return any(bad_vector(child) for child in children)
|
||||
corruptions = [
|
||||
('original','invalid typed vector',None),
|
||||
('original','orphan cargo endpoint',lambda r:r['logistics_requests'][0].update(destination_inventory_id='facility.inventory:absent')),
|
||||
('original','RESERVED missing/duplicate reservation',lambda r:r['inventory']['reservations'].pop()),
|
||||
('original','DELIVERING carrier/cargo mismatch',lambda r:r['logistics_requests'][0].update(assigned_carrier_id='patient')),
|
||||
('original','RESERVED carrier contradiction',lambda r:r['logistics_requests'][1].update(assigned_carrier_id='staff_gina')),
|
||||
('original','DELIVERING reservation quantity mismatch',lambda r:r['inventory']['reservations'][0].update(quantity=3)),
|
||||
('writer-checkpoint','support epoch/occupancy mismatch',lambda r:r['world']['revisions'].update(support=143)),
|
||||
]
|
||||
for label,message,change in corruptions:
|
||||
path = 'pairs/off-positive/'+label+'.json'
|
||||
original = (p.path/path).read_bytes()
|
||||
try:
|
||||
node = json.loads(original)
|
||||
if change: node = mutate_state(node,change)
|
||||
else: self.assertTrue(bad_vector(node))
|
||||
p.put(path,node); p.save()
|
||||
with self.subTest(message=message):
|
||||
self.assertTrue(any(message in deficit for deficit in c.check(ROOT,p.path)),message)
|
||||
finally:
|
||||
p.put(path,original); p.index = copy.deepcopy(self.baseline); p.save()
|
||||
for key in ('world','occupancy','support'):
|
||||
path = 'pairs/off-refusal/writer-checkpoint.json'
|
||||
original = (p.path/path).read_bytes()
|
||||
try:
|
||||
node = c.decode(json.loads(original)); revisions = node['systems']['runtime']['world']['revisions']
|
||||
revisions[key] += 1
|
||||
p.put(path,typed(node)); p.save()
|
||||
with self.subTest(refusal_revision=key):
|
||||
self.assertTrue(any('refusal revision changed' in deficit for deficit in c.check(ROOT,p.path)))
|
||||
finally:
|
||||
p.put(path,original); p.index = copy.deepcopy(self.baseline); p.save()
|
||||
|
||||
def test_corruptions_cannot_be_accepted(self):
|
||||
p = self.proof
|
||||
mutations = {
|
||||
'duplicate_actor':lambda r:r['guests']['guests'].append(copy.deepcopy(r['guests']['guests'][0])),
|
||||
'orphan_occupancy':lambda r:r['world']['occupancies'][0].update(entity_id='orphan'),
|
||||
'lost_patient':lambda r:r['staff']['staff'].pop(0),
|
||||
'lost_cargo':lambda r:r['inventory']['inventories'].pop(),
|
||||
'lost_ev':lambda r:r['elevators']['trips'].pop(),
|
||||
'missing_start_stage':lambda r:r['construction']['jobs'][1].update(state='BUILDING',progress=1),
|
||||
}
|
||||
path = 'pairs/off-positive/original.json'
|
||||
original = (p.path/path).read_bytes()
|
||||
for label,mutate in mutations.items():
|
||||
with self.subTest(label=label):
|
||||
node = c.decode(json.loads(original)); mutate(node['systems']['runtime'])
|
||||
p.put(path,typed(node)); p.save()
|
||||
self.assertTrue(c.check(ROOT,p.path),label)
|
||||
p.put(path,original); p.index = copy.deepcopy(self.baseline); p.save()
|
||||
path = 'pairs/off-positive/identity.json'
|
||||
original = (p.path/path).read_bytes()
|
||||
node = c.decode(json.loads(original)); node['diagnostic_budget']['deltas']['gold'] += 1
|
||||
p.put(path,typed(node)); p.save()
|
||||
self.assertTrue(c.check(ROOT,p.path),'resource_delta_mismatch')
|
||||
p.put(path,original); p.index = copy.deepcopy(self.baseline); p.save()
|
||||
paths = [('partial_batch','pairs/off-refusal/after-live.json'),('unequal_cross_pid','pairs/on-positive/reader-checkpoint.json'),
|
||||
('overwritten_original','pairs/off-refusal/original/formal/world.bin'),('overwritten_backup','pairs/off-refusal/backup/formal/world.bin')]
|
||||
for label,path in paths:
|
||||
with self.subTest(label=label):
|
||||
original = (p.path/path).read_bytes()
|
||||
p.put(path,b'{}'); p.save(); self.assertTrue(c.check(ROOT,p.path),label)
|
||||
p.put(path,original); p.index = copy.deepcopy(self.baseline); p.save()
|
||||
for label in ('missing_on','wrong_source','stale_source','fake_os_signal','missing_phase','duplicate_pid'):
|
||||
with self.subTest(label=label):
|
||||
changed = None
|
||||
if label=='missing_on': p.index['cases'] = p.index['cases'][:2]
|
||||
elif label=='wrong_source': p.index['source_map']['autoload/simulation_runtime.gd'] = '0'*64
|
||||
elif label=='stale_source': del p.index['source_map']['tools/check_p08_migration_evidence.py']
|
||||
elif label=='missing_phase': p.index['cases'][0]['phases'].pop()
|
||||
elif label=='fake_os_signal':
|
||||
changed = 'os/preview/input.json'; original = (p.path/changed).read_bytes()
|
||||
row = json.loads(original); row['method'] = 'signal_emitted'; p.put(changed,row)
|
||||
else:
|
||||
changed = p.index['cases'][0]['phases'][1]; original = (p.path/changed).read_bytes()
|
||||
row = json.loads(original); row['actual_pid'] = 100; p.put(changed,row)
|
||||
p.save(); self.assertTrue(c.check(ROOT,p.path),label)
|
||||
if changed: p.put(changed,original)
|
||||
p.index = copy.deepcopy(self.baseline); p.save()
|
||||
|
||||
if __name__ == '__main__': unittest.main()
|
||||
Reference in New Issue
Block a user