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

This commit is contained in:
Agent Control Runner
2026-10-13 21:39:16 +09:00
parent e59206b9b2
commit bb34f443c4
8 changed files with 166 additions and 17806 deletions
@@ -12,7 +12,7 @@ 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 | | 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`: two paid old-size premium jobs plus completed dorm; `run`: progress/reservations and completion shape | All four pairs; positive applies batch, refusal continues old shape | `semantics` checks active paid old-size jobs and completed dorm; `case_gate` permits only explicit typed geometry deltas and requires four-cell positive jobs | `partial_batch`; unapproved typed changes are compared without dropping fields | Native runtime/save and distinct-PID continuation; normal OS flow; Root final verification pending | | 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 | | 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 | | 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 | | 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 |
@@ -33,3 +33,12 @@ independent Opus review, integration/current verification and ledger closure rem
Controlled old-save setup must be labelled controlled, never natural production. 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 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. 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.
File diff suppressed because one or more lines are too long
@@ -5,175 +5,120 @@
"base_commit": "e196578c1a4ad2fdf84642565bd102e524be386f", "base_commit": "e196578c1a4ad2fdf84642565bd102e524be386f",
"spec_sha256_stripped_utf8": "19f02bb7912a4d7354e565186f02366fc1d4dd698468d26142e8204fd14ebfb0", "spec_sha256_stripped_utf8": "19f02bb7912a4d7354e565186f02366fc1d4dd698468d26142e8204fd14ebfb0",
"spec_sha256_raw": "01b3600e8815b514ffd5c4d341d77a6a3e8341064796c1dae706062b746ba6aa", "spec_sha256_raw": "01b3600e8815b514ffd5c4d341d77a6a3e8341064796c1dae706062b746ba6aa",
"scope": "Repair 1 of 2: two documentation outputs only. Retained code and single marker reused. No production, Runner, config, caps, git writes or native execution.", "scope": "Repair r04: definition-derived diagnostic deficit, three construction stages in one batch, minimal checker mutations and compact verified history references; no production/native/Runner/git writes.",
"outputs": [ "outputs": [
{ {
"path": "docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json", "path": "docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json",
"sha256": "c4c6dbea08a92682c692a280dbc90702ccbe63702a4f2624519b18d42930e18f", "sha256": "c4c6dbea08a92682c692a280dbc90702ccbe63702a4f2624519b18d42930e18f",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/s1/test_p08_combined_migration.gd", "path": "tests/s1/test_p08_combined_migration.gd",
"sha256": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855", "sha256": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/s1/test_p08_combined_migration.gd.uid", "path": "tests/s1/test_p08_combined_migration.gd.uid",
"sha256": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5", "sha256": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/fixtures/p08-02/README.md", "path": "tests/fixtures/p08-02/README.md",
"sha256": "bc76975e49e7761c2a3540a1e907ab2215ec315653a1d87df6919d1cebd779e0", "sha256": "8a6b8dcde00be86e1ff96b29b255b586366e759a561b03e060b28e8713e210e0",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/fixtures/p08-02/mixed_world.gd", "path": "tests/fixtures/p08-02/mixed_world.gd",
"sha256": "889bc895888b8c6ad50659a3b23a3ee45e9edf8dde9168f5560792c292070d26", "sha256": "e084d7aa6baf122089bd6f717af7e1e62de3c9930288439e6f51cc524bb55dde",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/fixtures/p08-02/reader.gd", "path": "tests/fixtures/p08-02/reader.gd",
"sha256": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be", "sha256": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/fixtures/p08-02/writer.gd", "path": "tests/fixtures/p08-02/writer.gd",
"sha256": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260", "sha256": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tools/run_p08_mixed_migration.py", "path": "tools/run_p08_mixed_migration.py",
"sha256": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579", "sha256": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tools/check_p08_migration_evidence.py", "path": "tools/check_p08_migration_evidence.py",
"sha256": "8d697c8e9a606bcff6a0a8c6ec55e0e9c434ca9682b7ce6915b5bcb1ea4ff3fd", "sha256": "c6edc43b114a64f5dedaafbfde47516baa265978c7aa836296c6bf5fe7a26857",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tools/test_p08_migration_evidence.py", "path": "tools/test_p08_migration_evidence.py",
"sha256": "9924f4cb4f55b15caf9f9733d91f5095553abcf2861e4b335755531480b534a9", "sha256": "22e75b2d4e79e7b6f8d7990c1eb14917565ca0e60197435716588ebaef3e09ea",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "retained unchanged by this repair" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/CONDITION_MATRIX.md", "path": "docs/plans/original-completion-2026-10-02/execution/p08-02/CONDITION_MATRIX.md",
"sha256": "ffe86cff6e06c2973bec5595fe18aefad62471cfec541c6f997942752bf2d754", "sha256": "6673051df9ae10f2df9b1812828e71ad9f5f24c433572defeef4e0978962a4e8",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "new documentation" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation.json", "path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation.json",
"sha256": "1a3eddab886b5c652c47c46ddd22fc7c15e3b79dfcaca30a9e340afba296d51e", "sha256": "7783f882e49c86432ea286293fd691d7d0abbec3847a7759c814e67436645e62",
"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", "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": "new documentation" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/fixtures/p08-02/mixed_world.gd.uid", "path": "tests/fixtures/p08-02/mixed_world.gd.uid",
"sha256": "d7549f933b74f5e807cd2d3b3adcdd083af4a3bd331614314ff7bfd7b0903f31", "sha256": "d7549f933b74f5e807cd2d3b3adcdd083af4a3bd331614314ff7bfd7b0903f31",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "Root-supplied exact UID pinned in current source map" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/fixtures/p08-02/reader.gd.uid", "path": "tests/fixtures/p08-02/reader.gd.uid",
"sha256": "3e68ce192d5770e3823df9699c5c99ebb618fe0a480b4d56913624941900b08a", "sha256": "3e68ce192d5770e3823df9699c5c99ebb618fe0a480b4d56913624941900b08a",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "Root-supplied exact UID pinned in current source map" "disposition": "r04 current source; retained paths and UID/marker entries"
}, },
{ {
"path": "tests/fixtures/p08-02/writer.gd.uid", "path": "tests/fixtures/p08-02/writer.gd.uid",
"sha256": "8f150654767de0c66329d7d9e84d306c4fa5a65c918e04fb520b626b39f68334", "sha256": "8f150654767de0c66329d7d9e84d306c4fa5a65c918e04fb520b626b39f68334",
"hash_scope": "raw bytes", "hash_scope": "raw bytes",
"disposition": "Root-supplied exact UID pinned in current source map" "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.", "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": [ "commands_actually_run": [
{ {
"command": "cat docs/spec/acceptance/P08-02.json", "command": "python3 -B AST parse of tools/run_p08_mixed_migration.py, tools/check_p08_migration_evidence.py, tools/test_p08_migration_evidence.py",
"purpose": "frozen spec first"
},
{
"command": "git status --short; rg --files tests/fixtures/p08-02 docs/plans/original-completion-2026-10-02/execution/p08-02; wc -l tools/*p08* tests/s1/test_p08_combined_migration.gd",
"purpose": "read-only inventory"
},
{
"command": "cat tools/check_p08_migration_evidence.py tools/run_p08_mixed_migration.py tools/test_p08_migration_evidence.py",
"purpose": "retained Python reads"
},
{
"command": "cat tests/fixtures/p08-02/* tests/s1/test_p08_combined_migration.gd tests/s1/test_p08_combined_migration.gd.uid docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json",
"purpose": "retained fixture/suite/marker reads"
},
{
"command": "cat tools/run_p08_mixed_migration.py tools/test_p08_migration_evidence.py",
"purpose": "targeted reread after output truncation"
},
{
"command": "cat tests/fixtures/p08-02/README.md tests/fixtures/p08-02/writer.gd tests/fixtures/p08-02/reader.gd tests/s1/test_p08_combined_migration.gd; cat tests/fixtures/p08-02/mixed_world.gd",
"purpose": "targeted retained fixture reread"
},
{
"command": "python -B -c <AST/spec/marker assertions>",
"exit_code": 127,
"result": "python unavailable"
},
{
"command": "mkdir -p docs/plans/original-completion-2026-10-02/execution/p08-02/.local-tmp",
"exit_code": 0, "exit_code": 0,
"purpose": "all disposable proof files inside worktree" "result": "3 AST parses passed"
}, },
{ {
"command": "TMPDIR=\"$PWD/docs/plans/original-completion-2026-10-02/execution/p08-02/.local-tmp\" python -B tools/test_p08_migration_evidence.py", "command": "python3 -B tools/test_p08_migration_evidence.py",
"exit_code": 127,
"result": "python unavailable"
},
{
"command": "python3 -B -c <ast.parse three Python files; git show base:docs/spec/acceptance/P08-02.json stripped SHA; single marker assertion>",
"exit_code": 0, "exit_code": 0,
"result": "3 AST parses, frozen spec SHA and single marker matched" "result": "2 tests in 34.514s, OK, synthetic only"
}, },
{ {
"command": "TMPDIR=\"$PWD/docs/plans/original-completion-2026-10-02/execution/p08-02/.local-tmp\" python3 -B tools/test_p08_migration_evidence.py", "command": "git show fixed historical references (stdout SHA only; no Git writes)",
"exit_code": 0, "exit_code": 0,
"result": "2 tests in 34.947s, OK; whole-check positive and negative subtests, synthetic only" "result": "both references matched original raw SHA and 1082602 bytes"
},
{
"command": "TMPDIR=\"$PWD/docs/plans/original-completion-2026-10-02/execution/p08-02/.local-tmp\" python3 -B - <documentation generator>",
"exit_code": 1,
"result": "heredoc temp creation denied; switched to apply_patch"
},
{
"command": "python3 -B docs/plans/original-completion-2026-10-02/execution/p08-02/.generate_docs.py",
"purpose": "documentation generation from retained synthetic Proof; no native execution"
},
{
"command": "python3 -B -c <verify JSON, every raw output hash, normalized self hash and all six example condition IDs; record this verification>",
"exit_code": 0,
"result": "documentation JSON/hash/condition consistency verified"
},
{
"command": "rmdir docs/plans/original-completion-2026-10-02/execution/p08-02/.local-tmp",
"purpose": "remove empty worktree-local temporary directory"
} }
], ],
"local_checks": { "local_checks": {
"ast_parse": "passed, 3 files", "ast_parse": "passed, three Python sources",
"spec_stripped_sha": "matched", "checker_tests": "2 tests passed in 34.514s; synthetic only, includes missing_start_stage and resource_delta_mismatch",
"single_public_marker": "matched, 1 entry",
"checker_tests": "2 tests passed, synthetic only",
"python_executable": "python3 -B because python unavailable",
"native_or_full_regression_run": false "native_or_full_regression_run": false
}, },
"pending_root_conditions": [ "pending_root_conditions": [
@@ -236,7 +181,7 @@
"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.", "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": { "complete_example_generator": {
"source": "tools/test_p08_migration_evidence.py", "source": "tools/test_p08_migration_evidence.py",
"source_raw_sha256": "9924f4cb4f55b15caf9f9733d91f5095553abcf2861e4b335755531480b534a9", "source_raw_sha256": "22e75b2d4e79e7b6f8d7990c1eb14917565ca0e60197435716588ebaef3e09ea",
"class": "Proof", "class": "Proof",
"constructor": "Proof(Path(fresh_temporary_directory))", "constructor": "Proof(Path(fresh_temporary_directory))",
"project_root_binding": "module ROOT resolved from unchanged generator inside this exact candidate source tree", "project_root_binding": "module ROOT resolved from unchanged generator inside this exact candidate source tree",
@@ -279,13 +224,13 @@
"fixture_sources": { "fixture_sources": {
"tests/s1/test_p08_combined_migration.gd": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855", "tests/s1/test_p08_combined_migration.gd": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855",
"tests/s1/test_p08_combined_migration.gd.uid": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5", "tests/s1/test_p08_combined_migration.gd.uid": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5",
"tests/fixtures/p08-02/README.md": "bc76975e49e7761c2a3540a1e907ab2215ec315653a1d87df6919d1cebd779e0", "tests/fixtures/p08-02/README.md": "8a6b8dcde00be86e1ff96b29b255b586366e759a561b03e060b28e8713e210e0",
"tests/fixtures/p08-02/mixed_world.gd": "889bc895888b8c6ad50659a3b23a3ee45e9edf8dde9168f5560792c292070d26", "tests/fixtures/p08-02/mixed_world.gd": "e084d7aa6baf122089bd6f717af7e1e62de3c9930288439e6f51cc524bb55dde",
"tests/fixtures/p08-02/reader.gd": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be", "tests/fixtures/p08-02/reader.gd": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be",
"tests/fixtures/p08-02/writer.gd": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260", "tests/fixtures/p08-02/writer.gd": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260",
"tools/run_p08_mixed_migration.py": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579", "tools/run_p08_mixed_migration.py": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579",
"tools/check_p08_migration_evidence.py": "8d697c8e9a606bcff6a0a8c6ec55e0e9c434ca9682b7ce6915b5bcb1ea4ff3fd", "tools/check_p08_migration_evidence.py": "c6edc43b114a64f5dedaafbfde47516baa265978c7aa836296c6bf5fe7a26857",
"tools/test_p08_migration_evidence.py": "9924f4cb4f55b15caf9f9733d91f5095553abcf2861e4b335755531480b534a9" "tools/test_p08_migration_evidence.py": "22e75b2d4e79e7b6f8d7990c1eb14917565ca0e60197435716588ebaef3e09ea"
}, },
"native_runner_input_shape": { "native_runner_input_shape": {
"protocol": "p08-mixed-v1", "protocol": "p08-mixed-v1",
@@ -305,18 +250,34 @@
"timeouts": "unchanged: collection 900s, phase maximum 180s", "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" "formal_validation": "Root copies actual evidence into allocated build directory; --verify-only reads BUILD_OUTPUT_DIR/p08-evidence/index.json"
}, },
"exact_reconstruction_verification": { "purpose": "Synthetic Proof generator documents current schema. Historical reconstruction measurements are preserved in Git, not asserted for changed fixture."
"entire_index_equal": true,
"entire_representative_documents_equal": true,
"index_canonical_sha256": "45d6c9c60e368e1747471443175e8dc5b09fb9338b489c69d92f54565cce26dd",
"representative_canonical_sha256": "0d008b1801ff31c3a0f487e8e09e547c893985ca25905ef6083af07065c6c9b4",
"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."
}, },
"historical_record": { "historical_record": {
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation-historical-6c7c724.json", "path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation-historical-6c7c724.json",
"sha256": "ab1fcf46ef73f2157f16f69394b4039a562c031fae8d407adca013a452226e2f", "sha256": "94321c2e924ef509738c8c4302c9e68854b9ce305830352d2dbb51d43f9ff34c",
"classification": "Historical pre-r03 record; full prior example remains tied to commit 6c7c724, not the current canonical record" "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."
} }
} }
+13
View File
@@ -2,3 +2,16 @@
Controlled fixture inputs are diagnostic, not production balance values. Controlled fixture inputs are diagnostic, not production balance values.
Native collection and acceptance remain pending. Native collection and acceptance remain pending.
Seed: 42588. Registered construction costs for the 16 planned builds total
gold 7110 / materials 88; Gina signing costs 150 and eight raw food units cost
24. Initial resources are gold 5000 / materials 50. The previous fixture had
no change_resources delta (zero), short by gold 2284 / materials 38.
The fixture derives and records this deficit from the actual registry/catalogs
in identity.diagnostic_budget before using the existing change_resources command.
No price or production coefficient is changed.
The first legacy premium job progresses while the six actor/transport facets
are prepared. The second is paid and reserved immediately before saving, with
zero progress; the dormitory is already complete. All three stages share the
same migration batch and whole-state writer/reader comparisons.
+28 -3
View File
@@ -76,8 +76,28 @@ func packages() -> Dictionary:
for member: String in MEMBERS: hashes[suffix+"/"+member] = FileAccess.get_sha256(ProjectSettings.globalize_path(slot+suffix).path_join(member)) for member: String in MEMBERS: hashes[suffix+"/"+member] = FileAccess.get_sha256(ProjectSettings.globalize_path(slot+suffix).path_join(member))
return hashes return hashes
func observe(event: SimulationDomainEvent) -> void: events.append(event.to_dictionary()) 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: func setup(operations: bool) -> bool:
registry(true) 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 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]]: 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 if not build(row[0],row[1],false): return false
@@ -87,12 +107,12 @@ func setup(operations: bool) -> bool:
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes) clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
if not build(&"staff_dormitory",Vector3i(-8,2,1)): return false if not build(&"staff_dormitory",Vector3i(-8,2,1)): return false
identity[&"dorm"] = instance(&"staff_dormitory").instance_id identity[&"dorm"] = instance(&"staff_dormitory").instance_id
if not build(&"premium_room",Vector3i(-6,2,0),false) or not build(&"premium_room",Vector3i(5,2,0),false): return false if not build(&"premium_room",Vector3i(-6,2,0),false): return false
clock.advance_minutes(7) clock.advance_minutes(7)
identity[&"jobs"] = [] identity[&"jobs"] = []
for job: ConstructionJob in runtime.construction_service.get_jobs(): for job: ConstructionJob in runtime.construction_service.get_jobs():
if not job.is_terminal(): identity[&"jobs"].append(job.job_id) if not job.is_terminal(): identity[&"jobs"].append(job.job_id)
if not expect(identity[&"jobs"].size() == 2,"two paid active jobs"): return false if not expect(identity[&"jobs"].size() == 1,"one paid progressing job"): return false
var warehouse := instance(&"warehouse") var warehouse := instance(&"warehouse")
var kitchen := instance(&"kitchen") var kitchen := instance(&"kitchen")
if not expect(warehouse != null and kitchen != null,"completed logistics endpoints"): return false if not expect(warehouse != null and kitchen != null,"completed logistics endpoints"): return false
@@ -130,9 +150,14 @@ func setup(operations: bool) -> bool:
var car: Dictionary = runtime.elevators.get_report()[&"shafts"][0] var car: Dictionary = runtime.elevators.get_report()[&"shafts"][0]
expect(car[&"passenger_count"] == 4 and car[&"waiting_count"] == 1,"passengers and queue coexist") 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") 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"]: for id: StringName in identity[&"jobs"]:
var job: ConstructionJob = runtime.construction_service.get_job(id) var job: ConstructionJob = runtime.construction_service.get_job(id)
expect(not job.is_terminal() and job.progress > 0 and job.reserved_cells.size() == 6,"old-size paid jobs remain active") expect(not job.is_terminal() and (job.progress == 0 if id == identity[&"starting_job"] else job.progress > 0) and not job.construction_cost.is_empty() and job.reserved_cells.size() == 6,"old-size paid starting/progressing jobs remain active")
return failures == 0 return failures == 0
func invariant() -> void: func invariant() -> void:
expect(runtime.staff_service.validate_invariants()[&"ok"],"staff ownership") expect(runtime.staff_service.validate_invariants()[&"ok"],"staff ownership")
+10 -1
View File
@@ -76,8 +76,17 @@ def semantics(snapshot, identity, initial=False):
raise ValueError('operational/construction ownership mismatch') raise ValueError('operational/construction ownership mismatch')
for jid in identity['jobs']: for jid in identity['jobs']:
if jid not in jobs: raise ValueError('lost paid job') if jid not in jobs: raise ValueError('lost paid job')
if initial and (jobs[jid]['progress'] <= 0 or jobs[jid]['state'] != 'BUILDING' or len(jobs[jid]['reserved_cells']) != 6): 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') 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') 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') tasks = indexed(r['staff']['tasks'],'task_id')
if 'patient' not in staff or 'carrier' not in staff: raise ValueError('lost patient/carrier') if 'patient' not in staff or 'carrier' not in staff: raise ValueError('lost patient/carrier')
+9 -2
View File
@@ -46,7 +46,7 @@ class Proof:
self.put(prefix+name+'.var',json.dumps(node).encode()) self.put(prefix+name+'.var',json.dumps(node).encode())
def save(self): (self.path/'index.json').write_text(json.dumps(self.index)) def save(self): (self.path/'index.json').write_text(json.dumps(self.index))
def state(self,operations): def state(self,operations):
jobs = [{'job_id':j,'state':'BUILDING','progress':466,'reserved_cells':[[x,2,0] for x in range(offset,offset+6)],'construction_cost':{'gold':1}} jobs = [{'job_id':j,'state':'PLANNED' if j=='j2' else 'BUILDING','progress':0 if j=='j2' else 466,'reserved_cells':[[x,2,0] for x in range(offset,offset+6)],'construction_cost':{'gold':1}}
for j,offset in [('j1',0),('j2',10)]] 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':'dorm','occupied_cells':[[30,0,1]]},{'instance_id':'clinic','occupied_cells':[[31,0,1]]}]
guests = [{'guest_id':g} for g in ['p08.walker']+['g'+str(n) for n in range(5)]] guests = [{'guest_id':g} for g in ['p08.walker']+['g'+str(n) for n in range(5)]]
@@ -81,7 +81,7 @@ class Proof:
phases = [self.phase(name+'-'+role,role,100+2*number+i) for i,role in enumerate(('writer','reader'))] 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['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 self.index['phases'] += phases
identity = {'jobs':['j1','j2'],'dorm':'dorm','rescue_task':'rescue','logistics_requests':['food'],'ev_requests':['ev'+str(n) for n in range(5)]} 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)]}
original = self.state(operations) original = self.state(operations)
self.variant(prefix,'identity',identity); self.variant(prefix,'original',original); self.variant(prefix,'after-live',original) self.variant(prefix,'identity',identity); self.variant(prefix,'original',original); self.variant(prefix,'after-live',original)
before = {}; after = {} before = {}; after = {}
@@ -151,6 +151,7 @@ class EvidenceTests(unittest.TestCase):
'lost_patient':lambda r:r['staff']['staff'].pop(0), 'lost_patient':lambda r:r['staff']['staff'].pop(0),
'lost_cargo':lambda r:r['inventory']['inventories'].pop(), 'lost_cargo':lambda r:r['inventory']['inventories'].pop(),
'lost_ev':lambda r:r['elevators']['trips'].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' path = 'pairs/off-positive/original.json'
original = (p.path/path).read_bytes() original = (p.path/path).read_bytes()
@@ -160,6 +161,12 @@ class EvidenceTests(unittest.TestCase):
p.put(path,typed(node)); p.save() p.put(path,typed(node)); p.save()
self.assertTrue(c.check(ROOT,p.path),label) self.assertTrue(c.check(ROOT,p.path),label)
p.put(path,original); p.index = copy.deepcopy(self.baseline); p.save() 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'), 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')] ('overwritten_original','pairs/off-refusal/original/formal/world.bin'),('overwritten_backup','pairs/off-refusal/backup/formal/world.bin')]
for label,path in paths: for label,path in paths: