P08-02: 旧配置の安全な変更
This commit is contained in:
@@ -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 |
|
||||
|---|---|---|---|---|---|
|
||||
| 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 |
|
||||
| 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 |
|
||||
@@ -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.
|
||||
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.
|
||||
|
||||
File diff suppressed because one or more lines are too long
+12
-17699
File diff suppressed because it is too large
Load Diff
@@ -5,175 +5,120 @@
|
||||
"base_commit": "e196578c1a4ad2fdf84642565bd102e524be386f",
|
||||
"spec_sha256_stripped_utf8": "19f02bb7912a4d7354e565186f02366fc1d4dd698468d26142e8204fd14ebfb0",
|
||||
"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": [
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json",
|
||||
"sha256": "c4c6dbea08a92682c692a280dbc90702ccbe63702a4f2624519b18d42930e18f",
|
||||
"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",
|
||||
"sha256": "9284a8cfb478b4c8d69f6d8166eec6c41107e3902029289b3c0e9ba48c370855",
|
||||
"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",
|
||||
"sha256": "8c3a70d0ce619b8cb98dc003eb6c53a31f167a686179a3ffc105f7cd4d856da5",
|
||||
"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",
|
||||
"sha256": "bc76975e49e7761c2a3540a1e907ab2215ec315653a1d87df6919d1cebd779e0",
|
||||
"sha256": "8a6b8dcde00be86e1ff96b29b255b586366e759a561b03e060b28e8713e210e0",
|
||||
"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",
|
||||
"sha256": "889bc895888b8c6ad50659a3b23a3ee45e9edf8dde9168f5560792c292070d26",
|
||||
"sha256": "e084d7aa6baf122089bd6f717af7e1e62de3c9930288439e6f51cc524bb55dde",
|
||||
"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",
|
||||
"sha256": "a760d0e45979d747dbd1f8710033bdce13287b00eb879d947d8378ff920ed1be",
|
||||
"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",
|
||||
"sha256": "1a918b5509773b4b07a27d47ee44583b0eb5288138f7bf896088a7913773c260",
|
||||
"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",
|
||||
"sha256": "7e86737e6354a4734726ba8d3171ad5f58d6c0380aba5a0fa3c57879d580e579",
|
||||
"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",
|
||||
"sha256": "8d697c8e9a606bcff6a0a8c6ec55e0e9c434ca9682b7ce6915b5bcb1ea4ff3fd",
|
||||
"sha256": "c6edc43b114a64f5dedaafbfde47516baa265978c7aa836296c6bf5fe7a26857",
|
||||
"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",
|
||||
"sha256": "9924f4cb4f55b15caf9f9733d91f5095553abcf2861e4b335755531480b534a9",
|
||||
"sha256": "22e75b2d4e79e7b6f8d7990c1eb14917565ca0e60197435716588ebaef3e09ea",
|
||||
"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",
|
||||
"sha256": "ffe86cff6e06c2973bec5595fe18aefad62471cfec541c6f997942752bf2d754",
|
||||
"sha256": "6673051df9ae10f2df9b1812828e71ad9f5f24c433572defeef4e0978962a4e8",
|
||||
"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",
|
||||
"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",
|
||||
"disposition": "new documentation"
|
||||
"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": "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",
|
||||
"sha256": "3e68ce192d5770e3823df9699c5c99ebb618fe0a480b4d56913624941900b08a",
|
||||
"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",
|
||||
"sha256": "8f150654767de0c66329d7d9e84d306c4fa5a65c918e04fb520b626b39f68334",
|
||||
"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.",
|
||||
"commands_actually_run": [
|
||||
{
|
||||
"command": "cat docs/spec/acceptance/P08-02.json",
|
||||
"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",
|
||||
"command": "python3 -B AST parse of tools/run_p08_mixed_migration.py, tools/check_p08_migration_evidence.py, tools/test_p08_migration_evidence.py",
|
||||
"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",
|
||||
"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>",
|
||||
"command": "python3 -B tools/test_p08_migration_evidence.py",
|
||||
"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,
|
||||
"result": "2 tests in 34.947s, OK; whole-check positive and negative subtests, synthetic only"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
"result": "both references matched original raw SHA and 1082602 bytes"
|
||||
}
|
||||
],
|
||||
"local_checks": {
|
||||
"ast_parse": "passed, 3 files",
|
||||
"spec_stripped_sha": "matched",
|
||||
"single_public_marker": "matched, 1 entry",
|
||||
"checker_tests": "2 tests passed, synthetic only",
|
||||
"python_executable": "python3 -B because python unavailable",
|
||||
"ast_parse": "passed, three Python sources",
|
||||
"checker_tests": "2 tests passed in 34.514s; synthetic only, includes missing_start_stage and resource_delta_mismatch",
|
||||
"native_or_full_regression_run": false
|
||||
},
|
||||
"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.",
|
||||
"complete_example_generator": {
|
||||
"source": "tools/test_p08_migration_evidence.py",
|
||||
"source_raw_sha256": "9924f4cb4f55b15caf9f9733d91f5095553abcf2861e4b335755531480b534a9",
|
||||
"source_raw_sha256": "22e75b2d4e79e7b6f8d7990c1eb14917565ca0e60197435716588ebaef3e09ea",
|
||||
"class": "Proof",
|
||||
"constructor": "Proof(Path(fresh_temporary_directory))",
|
||||
"project_root_binding": "module ROOT resolved from unchanged generator inside this exact candidate source tree",
|
||||
@@ -279,13 +224,13 @@
|
||||
"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/README.md": "8a6b8dcde00be86e1ff96b29b255b586366e759a561b03e060b28e8713e210e0",
|
||||
"tests/fixtures/p08-02/mixed_world.gd": "e084d7aa6baf122089bd6f717af7e1e62de3c9930288439e6f51cc524bb55dde",
|
||||
"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"
|
||||
"tools/check_p08_migration_evidence.py": "c6edc43b114a64f5dedaafbfde47516baa265978c7aa836296c6bf5fe7a26857",
|
||||
"tools/test_p08_migration_evidence.py": "22e75b2d4e79e7b6f8d7990c1eb14917565ca0e60197435716588ebaef3e09ea"
|
||||
},
|
||||
"native_runner_input_shape": {
|
||||
"protocol": "p08-mixed-v1",
|
||||
@@ -305,18 +250,34 @@
|
||||
"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": "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."
|
||||
"purpose": "Synthetic Proof generator documents current schema. Historical reconstruction measurements are preserved in Git, not asserted for changed fixture."
|
||||
},
|
||||
"historical_record": {
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p08-02/implementation-historical-6c7c724.json",
|
||||
"sha256": "ab1fcf46ef73f2157f16f69394b4039a562c031fae8d407adca013a452226e2f",
|
||||
"classification": "Historical pre-r03 record; full prior example remains tied to commit 6c7c724, not the current canonical record"
|
||||
"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."
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+13
@@ -2,3 +2,16 @@
|
||||
|
||||
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.
|
||||
|
||||
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
+28
-3
@@ -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))
|
||||
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
|
||||
@@ -87,12 +107,12 @@ func setup(operations: bool) -> bool:
|
||||
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_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) 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)
|
||||
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() == 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 kitchen := instance(&"kitchen")
|
||||
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]
|
||||
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 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
|
||||
func invariant() -> void:
|
||||
expect(runtime.staff_service.validate_invariants()[&"ok"],"staff ownership")
|
||||
|
||||
@@ -76,8 +76,17 @@ def semantics(snapshot, identity, initial=False):
|
||||
raise ValueError('operational/construction ownership mismatch')
|
||||
for jid in identity['jobs']:
|
||||
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')
|
||||
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')
|
||||
|
||||
@@ -46,7 +46,7 @@ class Proof:
|
||||
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':'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)]]
|
||||
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)]]
|
||||
@@ -81,7 +81,7 @@ class Proof:
|
||||
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 = {'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)
|
||||
self.variant(prefix,'identity',identity); self.variant(prefix,'original',original); self.variant(prefix,'after-live',original)
|
||||
before = {}; after = {}
|
||||
@@ -151,6 +151,7 @@ class EvidenceTests(unittest.TestCase):
|
||||
'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()
|
||||
@@ -160,6 +161,12 @@ class EvidenceTests(unittest.TestCase):
|
||||
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:
|
||||
|
||||
Reference in New Issue
Block a user