P08-03: 配置の通常操作受入
This commit is contained in:
@@ -31,6 +31,32 @@ and a budget report explicitly tagged diagnostic. No production costs,
|
||||
services, balance values or definitions are changed. New art is unnecessary;
|
||||
the demolition button reuses Main's existing styling and audio.
|
||||
|
||||
## r01 fixture repair (current candidate)
|
||||
|
||||
The only failure authorities used are `NATIVE_R01_FAILURE_AND_SCOPE.json`
|
||||
and `native-r01-writer-stderr.log`. The r01 writer failed 13 expectations;
|
||||
its full SaveService return Dictionaries were not captured and remain absent.
|
||||
No past Dictionary was reconstructed and no historical raw evidence was edited.
|
||||
|
||||
The handler now changes a toggle button's pressed state, emitting the real
|
||||
production `toggled` connection before `pressed`. Repeated `choose(id)` leaves
|
||||
an already selected ID active. Production wiring is unchanged.
|
||||
Initial and normal saves use private `user://saves/p08_initial` and
|
||||
`user://saves/manual_ui`; separate handler readers SHA-copy the exported input
|
||||
into their own private profile before normal-menu load. The initial diagnostic
|
||||
package seeds the normal slot, so the actual normal save creates its backup.
|
||||
Exports retain all four members, the backup, and verbatim manifest slot
|
||||
metadata with SHA/byte lengths and actual paths. An absent initial backup is
|
||||
explicitly recorded. Every observed Runtime save/load result and direct
|
||||
SaveService diagnostic return is recorded as typed JSON and SHA-pinned raw
|
||||
Variant, with PID, requested/absolute paths and user-data directory.
|
||||
|
||||
The 35 local checker tests remain synthetic controls. Their negative cases
|
||||
also cover missing backup members, slot metadata SHA, failed actual returns,
|
||||
and saves outside private profiles. The mock collector supplies a controlled
|
||||
disk-space input; the production disk-admission gate is unchanged.
|
||||
Current native/OS/full regression/review/integration remain pending.
|
||||
|
||||
## Evidence boundary
|
||||
|
||||
`placement.gd` contains the shared finite scenario and handler endpoints.
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"unit": "P08-03",
|
||||
"submitted_commit": "7dd450c64c897fc8e9e6bbd9fa242f28f42cb1af",
|
||||
"actual_local_final": {
|
||||
"source_input_hash_mismatches": 0,
|
||||
"synthetic_checker_tests": 35,
|
||||
"passed": true,
|
||||
"native_acceptance": false
|
||||
},
|
||||
"native_output": "artifacts/original-completion-2026-10-02/p08-03-native-os-r01",
|
||||
"phases": [
|
||||
{
|
||||
"phase": "import",
|
||||
"pid": 45015,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"phase": "parse",
|
||||
"pid": 45110,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"phase": "writer",
|
||||
"pid": 45149,
|
||||
"passed": false,
|
||||
"assert_failures": 13
|
||||
}
|
||||
],
|
||||
"failure": "strict writer diagnostics; fixture methods do not match actual toggle/save API",
|
||||
"observed": {
|
||||
"build_report": "can_build=false with cells/error_codes/reasons empty",
|
||||
"status": "initial UI help, no build results",
|
||||
"formal_member_hashes": "empty because no formal save was created"
|
||||
},
|
||||
"source_diagnosis": [
|
||||
{
|
||||
"fixture": "button() only emits pressed",
|
||||
"production": "build buttons connect toggled to _on_build_button_toggled",
|
||||
"scope": "repair fixture; no evidence to change production button wiring"
|
||||
},
|
||||
{
|
||||
"fixture": "formal and initial-formal paths outside private user://",
|
||||
"production": "SaveService only accepts paths under current user://",
|
||||
"scope": "use legitimate private profile saves and SHA-copy formal members; preserve SaveService protection",
|
||||
"certainty": "UNSAFE_PATH is source/path inference; full returned save Dictionary must be recorded next"
|
||||
}
|
||||
],
|
||||
"cleanup_errors": [],
|
||||
"all_owned_children_ended": true,
|
||||
"OS_input_performed": false,
|
||||
"full_regression_performed": false,
|
||||
"registered_copy": {
|
||||
"files": 2047,
|
||||
"whole_file_hashes_match": true
|
||||
},
|
||||
"registered_validation": {
|
||||
"passed": false,
|
||||
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p08-03-code/runs/ac8ca67c94324f719a327d98b5e833c3-validation.json"
|
||||
},
|
||||
"acceptance_credit": 0,
|
||||
"next": "Actual Opus request-repair judgment for same worktree, narrow fixture fixes",
|
||||
"updated_utc": "2026-10-13T18:33:26.998526+00:00"
|
||||
}
|
||||
@@ -31,6 +31,16 @@ All four formal members are copied and SHA-checked. The staged project gets
|
||||
only private-profile settings and is restored in finally. Only captured
|
||||
Popen children are cleaned by `owned_outer.finish_captured`.
|
||||
|
||||
The repaired handler also saves only inside its private `user://` profile,
|
||||
then exports `initial-formal` and `formal` to the evidence directory.
|
||||
`formal.bak`, `*-slot-metadata.json` (verbatim manifest), and `*-export.json`
|
||||
retain backup/metadata bytes, source paths and SHA pins. Initial backup absence
|
||||
is recorded explicitly. Each role's `*-save-results.json` references actual
|
||||
typed result JSON and SHA-pinned raw Variant files, including failed returns.
|
||||
Inspect the full returned dictionaries and paths on the next native run.
|
||||
The r01 dictionaries were never captured; do not reconstruct them or append
|
||||
new results to the historical r01 raw evidence.
|
||||
|
||||
Actual argv is `[engine, --path, stage, --script, passive_os.gd]`, with no
|
||||
headless flag or headless proof gate. `started.json`, `process-started.json`,
|
||||
`ended.json`, raw engine log, actual profile/engine report, source/stage/default
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"P08-03"
|
||||
],
|
||||
"base_commit": "12430ba89970bda349781e51157e72e48a4ac06f",
|
||||
"actual_worktree_HEAD": "12430ba89970bda349781e51157e72e48a4ac06f",
|
||||
"actual_worktree_HEAD": "7dd450c64c897fc8e9e6bbd9fa242f28f42cb1af",
|
||||
"worker_committed": false,
|
||||
"final_commit": null,
|
||||
"final_commit_note": "Root must freeze and record the submitted candidate; worker git writes are prohibited.",
|
||||
@@ -18,27 +18,27 @@
|
||||
},
|
||||
"final_local_files_sha256": {
|
||||
"docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json": "f59f01f65c795057117fda753706a6200928d4954af901fc965cf1a7c09232b5",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/CONDITION_MATRIX.md": "656400d0f9028ff7cf272b8e02be9c329f25adb6ff2039708ca04d0251be611c",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/ROOT_COLLECTION.md": "d2a0da74c3b469350e9130fbd8a024be49b4c8cc9ed09154c3966bf7642c38cc",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/CONDITION_MATRIX.md": "3cbdc2bd8eccb8cf1f060fb237072dc5b935e8cd147c74884c8c1abb2c810c81",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/ROOT_COLLECTION.md": "ed1d3978bba78a9ffe68808ec1f1f1990ae180630b5eace9587b8dd1719b43ef",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/passive_os_placement_recorder.gd": "21855e3b32263eb98127202467b770cb1334fa70c6b357825a122db385ffa8d6",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/passive_os_placement_recorder.gd.uid": "d7f97560c8bbdfdaed173b2b48261e65b92847bd0493dd1cc2ebb309d0622314",
|
||||
"scenes/main/main.gd": "e015e18fee8c114ddce39e46a04be139e694a4e3569855065576c0c909b94fc6",
|
||||
"scenes/main/world_preview.gd": "2f0e417ae2ff1745062bdbdcec74b3b058cfcffbbd9001ca3e6a62cd23efb47d",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "56f80f0e8a44a707c2c59e385c2fa5bd3949f1dd95d4cbf40f480870aca08d45",
|
||||
"tests/fixtures/p08-03/passive_placement.gd": "f070c93000d0eceef8cc9e518fefa2ba9c7608883ab5bf9198dff224b60d4da1",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "c6dd2471f408a790f174e5ab73bbdbd899838f51a0dcde91bd0655da63238c46",
|
||||
"tests/fixtures/p08-03/passive_placement.gd": "c17a1874fa585ec1ea892b51860f0997176df084b08751ea41e27ea5bc1189e8",
|
||||
"tests/fixtures/p08-03/passive_placement.gd.uid": "f75e3f2d9555c30cee3a1de882f32225fc624565a78a7ef3f5c604325c578ce3",
|
||||
"tests/fixtures/p08-03/placement.gd": "95d46b329d5b08954915a4f80b06b7774eeaf4976ef9c687e8c61433bf0d14eb",
|
||||
"tests/fixtures/p08-03/placement.gd": "84296f340e26daff3e7cff50ae6e1d5ef8f717a39d9dfa9ff1b590059fa00a81",
|
||||
"tests/fixtures/p08-03/placement.gd.uid": "5caca08c1e627e0ca07e2ab7b13bd82b24a22f77513fe87e30b79023568e1987",
|
||||
"tests/ui/test_p08_normal_placement_ops.gd": "734f4f85d0b0fc45dc31fc23502425b911635667dabc0341ba0d88b0107f4405",
|
||||
"tests/ui/test_p08_normal_placement_ops.gd.uid": "7d168ac50ca82ae1979da31c467f9a5020ca5ec7616b5bf99294413d85b3b299",
|
||||
"tools/check_p08_normal_placement_evidence.py": "d79df59d4434afd5219aca9aeb4581119859d08a71c9df73ae25f01e70ab59f5",
|
||||
"tools/check_p08_normal_placement_evidence.py": "9805c595b95172926f515e5600aaa14e19c83f0e9a2f88406b17656076b0e82c",
|
||||
"tools/regression/suite-policy.json": "e875e6b05bbac8dfb98c2af007221436fa558ddb8806b6214689830295b32e8d",
|
||||
"tools/run_p08_normal_placement.py": "191831b4f684bdd7e99b3be6038c15a6830f544d17c941869b1c2a8fbe4a2aa3",
|
||||
"tools/test_p08_normal_placement_evidence.py": "5a4a859817b7764a07d215c4811d2912c7f502de7219d57b11c3e3158dc177eb"
|
||||
"tools/test_p08_normal_placement_evidence.py": "2c493349de1d72d1eae383356f8bf3904096c810550f9de373816a25d5ae54c8"
|
||||
},
|
||||
"executed_source_manifest": {
|
||||
"path": "local-source-manifest.json",
|
||||
"sha256": "63cd7079a4e9fb4966d829b5edcccdaedd82154c3afa2ea715622cb3d0b437b5",
|
||||
"sha256": "f3b5d4edb152c685bd10efa4ccbdb87fda5e3bdbb26a60c66bc12c1780a41003",
|
||||
"source_file_count": 1326,
|
||||
"contains": "Complete local execution source map and immutable/fixture input map; no material-size omission"
|
||||
},
|
||||
@@ -50,19 +50,21 @@
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/passive_os_placement_recorder.gd.uid": "d7f97560c8bbdfdaed173b2b48261e65b92847bd0493dd1cc2ebb309d0622314",
|
||||
"docs/spec/acceptance/P08-03.json": "37a6a581b5a9bbe03c07a3a266b03df1f740ff488da33ecd9bd60f5b32f1efe1",
|
||||
"docs/traceability/original/BASELINE.txt": "75e4bdbdeb379c9269553f0c776bdb9cc96e01f2d6aa5ca650d132c63a8aeb1a",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "56f80f0e8a44a707c2c59e385c2fa5bd3949f1dd95d4cbf40f480870aca08d45",
|
||||
"tests/fixtures/p08-03/passive_placement.gd": "f070c93000d0eceef8cc9e518fefa2ba9c7608883ab5bf9198dff224b60d4da1",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "c6dd2471f408a790f174e5ab73bbdbd899838f51a0dcde91bd0655da63238c46",
|
||||
"tests/fixtures/p08-03/passive_placement.gd": "c17a1874fa585ec1ea892b51860f0997176df084b08751ea41e27ea5bc1189e8",
|
||||
"tests/fixtures/p08-03/passive_placement.gd.uid": "f75e3f2d9555c30cee3a1de882f32225fc624565a78a7ef3f5c604325c578ce3",
|
||||
"tests/fixtures/p08-03/placement.gd": "95d46b329d5b08954915a4f80b06b7774eeaf4976ef9c687e8c61433bf0d14eb",
|
||||
"tests/fixtures/p08-03/placement.gd.uid": "5caca08c1e627e0ca07e2ab7b13bd82b24a22f77513fe87e30b79023568e1987"
|
||||
"tests/fixtures/p08-03/placement.gd": "84296f340e26daff3e7cff50ae6e1d5ef8f717a39d9dfa9ff1b590059fa00a81",
|
||||
"tests/fixtures/p08-03/placement.gd.uid": "5caca08c1e627e0ca07e2ab7b13bd82b24a22f77513fe87e30b79023568e1987",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/NATIVE_R01_FAILURE_AND_SCOPE.json": "afc8dada6451e7e61d6d57abb0d7d040f5abcdb93432c8431c1c920dc4984515",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/native-r01-writer-stderr.log": "07fe6cccad7305b2ec88cb91fa79fa22ec9269d7c99d62a1f69971f7c5d22686"
|
||||
},
|
||||
"actual_local_validation": {
|
||||
"path": "local-validation.json",
|
||||
"sha256": "09701dcb7ef6a6da695f1c9b1060107e64666a8f8f0256c3caf1da9cf2d8f487",
|
||||
"python_syntax": "pass: four changed/new Python sources compiled in memory",
|
||||
"sha256": "531616ae3151b7a506978e43b754e1d6a372508515510da65c0fccffbbfff1c0",
|
||||
"python_syntax": "pass: four final Python sources compiled in memory",
|
||||
"checker_mock_tests": 35,
|
||||
"checker_mock_exit_code": 0,
|
||||
"log_sha256": "c542a3079ac31374dd3fce5bc96ccb44ca8ccfc765f78fe9f18413c259c5f67b",
|
||||
"log_sha256": "0779ddd3305f3a2c6c719240e036bb1d7f0d10f97ce21854a0f946feefcace93",
|
||||
"git_diff_check": "pass"
|
||||
},
|
||||
"conditions": {
|
||||
@@ -138,5 +140,20 @@
|
||||
},
|
||||
"whole_P08_complete": false,
|
||||
"P08_01_all30_claimed": false,
|
||||
"formal_acceptance": false
|
||||
"formal_acceptance": false,
|
||||
"repair": {
|
||||
"prior_submitted_commit": "7dd450c64c897fc8e9e6bbd9fa242f28f42cb1af",
|
||||
"failure_authorities": [
|
||||
"NATIVE_R01_FAILURE_AND_SCOPE.json",
|
||||
"native-r01-writer-stderr.log"
|
||||
],
|
||||
"changes": [
|
||||
"fixture toggled signal and idempotent choose",
|
||||
"private user:// formal and initial saves; SHA exports of members/backup/slot metadata",
|
||||
"actual returned Dictionaries and paths captured prospectively"
|
||||
],
|
||||
"production_changes": false,
|
||||
"historical_r01_dicts": "absent; not reconstructed or appended",
|
||||
"worker_git_writes": false
|
||||
}
|
||||
}
|
||||
|
||||
+16
-14
@@ -3678,20 +3678,20 @@
|
||||
"sha256": "8f150654767de0c66329d7d9e84d306c4fa5a65c918e04fb520b626b39f68334"
|
||||
},
|
||||
"tests/fixtures/p08-03/checker_fixture.py": {
|
||||
"bytes": 20189,
|
||||
"sha256": "56f80f0e8a44a707c2c59e385c2fa5bd3949f1dd95d4cbf40f480870aca08d45"
|
||||
"bytes": 22311,
|
||||
"sha256": "c6dd2471f408a790f174e5ab73bbdbd899838f51a0dcde91bd0655da63238c46"
|
||||
},
|
||||
"tests/fixtures/p08-03/passive_placement.gd": {
|
||||
"bytes": 9121,
|
||||
"sha256": "f070c93000d0eceef8cc9e518fefa2ba9c7608883ab5bf9198dff224b60d4da1"
|
||||
"bytes": 8799,
|
||||
"sha256": "c17a1874fa585ec1ea892b51860f0997176df084b08751ea41e27ea5bc1189e8"
|
||||
},
|
||||
"tests/fixtures/p08-03/passive_placement.gd.uid": {
|
||||
"bytes": 20,
|
||||
"sha256": "f75e3f2d9555c30cee3a1de882f32225fc624565a78a7ef3f5c604325c578ce3"
|
||||
},
|
||||
"tests/fixtures/p08-03/placement.gd": {
|
||||
"bytes": 13792,
|
||||
"sha256": "95d46b329d5b08954915a4f80b06b7774eeaf4976ef9c687e8c61433bf0d14eb"
|
||||
"bytes": 17684,
|
||||
"sha256": "84296f340e26daff3e7cff50ae6e1d5ef8f717a39d9dfa9ff1b590059fa00a81"
|
||||
},
|
||||
"tests/fixtures/p08-03/placement.gd.uid": {
|
||||
"bytes": 20,
|
||||
@@ -5218,8 +5218,8 @@
|
||||
"sha256": "928353233bf85436a5aaf8c4f77f3f82472d94b8ad2646cb1b030baf92b3b5dc"
|
||||
},
|
||||
"tools/check_p08_normal_placement_evidence.py": {
|
||||
"bytes": 31120,
|
||||
"sha256": "d79df59d4434afd5219aca9aeb4581119859d08a71c9df73ae25f01e70ab59f5"
|
||||
"bytes": 34820,
|
||||
"sha256": "9805c595b95172926f515e5600aaa14e19c83f0e9a2f88406b17656076b0e82c"
|
||||
},
|
||||
"tools/check_p24_selection_evidence.py": {
|
||||
"bytes": 14622,
|
||||
@@ -5298,8 +5298,8 @@
|
||||
"sha256": "fd9ef7ec63f53dfd5e04e261606c9303d01a2e6590e22a35fef2e35df1429280"
|
||||
},
|
||||
"tools/test_p08_normal_placement_evidence.py": {
|
||||
"bytes": 12374,
|
||||
"sha256": "5a4a859817b7764a07d215c4811d2912c7f502de7219d57b11c3e3158dc177eb"
|
||||
"bytes": 13526,
|
||||
"sha256": "2c493349de1d72d1eae383356f8bf3904096c810550f9de373816a25d5ae54c8"
|
||||
},
|
||||
"tools/verify_exported_opening.py": {
|
||||
"bytes": 1519,
|
||||
@@ -5314,10 +5314,12 @@
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/passive_os_placement_recorder.gd.uid": "d7f97560c8bbdfdaed173b2b48261e65b92847bd0493dd1cc2ebb309d0622314",
|
||||
"docs/spec/acceptance/P08-03.json": "37a6a581b5a9bbe03c07a3a266b03df1f740ff488da33ecd9bd60f5b32f1efe1",
|
||||
"docs/traceability/original/BASELINE.txt": "75e4bdbdeb379c9269553f0c776bdb9cc96e01f2d6aa5ca650d132c63a8aeb1a",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "56f80f0e8a44a707c2c59e385c2fa5bd3949f1dd95d4cbf40f480870aca08d45",
|
||||
"tests/fixtures/p08-03/passive_placement.gd": "f070c93000d0eceef8cc9e518fefa2ba9c7608883ab5bf9198dff224b60d4da1",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "c6dd2471f408a790f174e5ab73bbdbd899838f51a0dcde91bd0655da63238c46",
|
||||
"tests/fixtures/p08-03/passive_placement.gd": "c17a1874fa585ec1ea892b51860f0997176df084b08751ea41e27ea5bc1189e8",
|
||||
"tests/fixtures/p08-03/passive_placement.gd.uid": "f75e3f2d9555c30cee3a1de882f32225fc624565a78a7ef3f5c604325c578ce3",
|
||||
"tests/fixtures/p08-03/placement.gd": "95d46b329d5b08954915a4f80b06b7774eeaf4976ef9c687e8c61433bf0d14eb",
|
||||
"tests/fixtures/p08-03/placement.gd.uid": "5caca08c1e627e0ca07e2ab7b13bd82b24a22f77513fe87e30b79023568e1987"
|
||||
"tests/fixtures/p08-03/placement.gd": "84296f340e26daff3e7cff50ae6e1d5ef8f717a39d9dfa9ff1b590059fa00a81",
|
||||
"tests/fixtures/p08-03/placement.gd.uid": "5caca08c1e627e0ca07e2ab7b13bd82b24a22f77513fe87e30b79023568e1987",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/NATIVE_R01_FAILURE_AND_SCOPE.json": "afc8dada6451e7e61d6d57abb0d7d040f5abcdb93432c8431c1c920dc4984515",
|
||||
"docs/plans/original-completion-2026-10-02/execution/p08-03/native-r01-writer-stderr.log": "07fe6cccad7305b2ec88cb91fa79fa22ec9269d7c99d62a1f69971f7c5d22686"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"task_id": "P08-03",
|
||||
"started_at": "2026-10-13T18:21:21.344634+00:00",
|
||||
"ended_at": "2026-10-13T18:21:42.345749+00:00",
|
||||
"started_at": "2026-10-13T18:51:54.296622+00:00",
|
||||
"ended_at": "2026-10-13T18:52:13.521432+00:00",
|
||||
"syntax": {
|
||||
"method": "compile(source, filename, exec); no pyc",
|
||||
"files": {
|
||||
"tools/run_p08_normal_placement.py": "191831b4f684bdd7e99b3be6038c15a6830f544d17c941869b1c2a8fbe4a2aa3",
|
||||
"tools/check_p08_normal_placement_evidence.py": "d79df59d4434afd5219aca9aeb4581119859d08a71c9df73ae25f01e70ab59f5",
|
||||
"tools/test_p08_normal_placement_evidence.py": "5a4a859817b7764a07d215c4811d2912c7f502de7219d57b11c3e3158dc177eb",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "56f80f0e8a44a707c2c59e385c2fa5bd3949f1dd95d4cbf40f480870aca08d45"
|
||||
"tools/check_p08_normal_placement_evidence.py": "9805c595b95172926f515e5600aaa14e19c83f0e9a2f88406b17656076b0e82c",
|
||||
"tools/test_p08_normal_placement_evidence.py": "2c493349de1d72d1eae383356f8bf3904096c810550f9de373816a25d5ae54c8",
|
||||
"tests/fixtures/p08-03/checker_fixture.py": "c6dd2471f408a790f174e5ab73bbdbd899838f51a0dcde91bd0655da63238c46"
|
||||
},
|
||||
"passed": true
|
||||
},
|
||||
@@ -19,13 +19,13 @@
|
||||
"tools/test_p08_normal_placement_evidence.py"
|
||||
],
|
||||
"exit_code": 0,
|
||||
"log": "local-checker-tests.log",
|
||||
"log_sha256": "c542a3079ac31374dd3fce5bc96ccb44ca8ccfc765f78fe9f18413c259c5f67b",
|
||||
"log": "repair-local-checker-tests.log",
|
||||
"log_sha256": "0779ddd3305f3a2c6c719240e036bb1d7f0d10f97ce21854a0f946feefcace93",
|
||||
"synthetic_only": true,
|
||||
"test_count": 35
|
||||
},
|
||||
"local_source_manifest": "local-source-manifest.json",
|
||||
"local_source_manifest_sha256": "63cd7079a4e9fb4966d829b5edcccdaedd82154c3afa2ea715622cb3d0b437b5",
|
||||
"local_source_manifest_sha256": "f3b5d4edb152c685bd10efa4ccbdb87fda5e3bdbb26a60c66bc12c1780a41003",
|
||||
"source_and_inputs_unchanged_during_tests": true,
|
||||
"native_engines_started": 0,
|
||||
"OS_operations": 0,
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
ERROR: P08 placement: diagnostic initial formal save
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] save_initial_fixture (res://tests/fixtures/p08-03/placement.gd:306)
|
||||
[2] writer (res://tests/fixtures/p08-03/placement.gd:208)
|
||||
[3] run (res://tests/fixtures/p08-03/placement.gd:261)
|
||||
[4] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: unsupported preview refusal
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:115)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: out_of_bounds preview refusal
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:115)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: supported_connected accepted
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:111)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: overlap preview refusal
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:115)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: missing_connection domain refusal
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:113)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: lower_stair accepted
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:111)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: upper_stair accepted
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:111)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: refused_demolition result code
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] demolish (res://tests/fixtures/p08-03/placement.gd:145)
|
||||
[2] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: refused_demolition result reason
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] demolish (res://tests/fixtures/p08-03/placement.gd:146)
|
||||
[2] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: demolition result code
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] demolish (res://tests/fixtures/p08-03/placement.gd:145)
|
||||
[2] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: rebuild accepted
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] build (res://tests/fixtures/p08-03/placement.gd:111)
|
||||
[2] click (res://tests/fixtures/p08-03/placement.gd:94)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
ERROR: P08 placement: normal save
|
||||
at: push_error (core/variant/variant_utility.cpp:1023)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] expect (res://tests/fixtures/p08-03/placement.gd:33)
|
||||
[1] writer (res://tests/fixtures/p08-03/placement.gd:223)
|
||||
[2] button (res://tests/fixtures/p08-03/placement.gd:73)
|
||||
[3] frames (res://tests/fixtures/p08-03/placement.gd:65)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
...................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 35 tests in 18.245s
|
||||
|
||||
OK
|
||||
+26
@@ -241,6 +241,24 @@ def make(base, source, checker):
|
||||
formal = folder/'formal'
|
||||
formal.mkdir()
|
||||
for member in checker.MEMBERS: (formal/member).write_text('synthetic '+member+'\n')
|
||||
shutil.copytree(formal, folder/'formal.bak')
|
||||
shutil.copyfile(formal/'manifest.json', folder/'formal-slot-metadata.json')
|
||||
profile = '/synthetic-private-profile'
|
||||
absolute = profile+'/saves/manual_ui'
|
||||
put(folder/'formal-export.json', {'pid':pids[0], 'requested_path':'user://saves/manual_ui',
|
||||
'absolute_path':absolute, 'user_data_dir':profile,
|
||||
'packages':{name:{'present':True, 'source_path':absolute+suffix,
|
||||
'members':{n:{'sha256':sha(folder/name/n),'bytes':(folder/name/n).stat().st_size} for n in checker.MEMBERS}}
|
||||
for name,suffix in [('formal',''),('formal.bak','.bak')]},
|
||||
'slot_metadata':{'file':'formal-slot-metadata.json','sha256':sha(formal/'manifest.json')}})
|
||||
for role,pid,op in [('writer',pids[0],'save'),('reader',pids[1],'load')]:
|
||||
stem = role+'-save-result-0001'
|
||||
(folder/(stem+'.var')).write_bytes(b'synthetic raw Dictionary stand-in')
|
||||
put(folder/(stem+'.json'), {'pid':pid,'operation':'runtime_operation',
|
||||
'requested_path':'user://saves/manual_ui','absolute_path':absolute,'user_data_dir':profile,
|
||||
'result':typed({'ok':True,'operation':op,'save_path':'user://saves/manual_ui'}),
|
||||
'raw_sha256':sha(folder/(stem+'.var'))})
|
||||
put(folder/(role+'-save-results.json'), {'pid':pid,'records':[stem]})
|
||||
put(folder/'save.json', {'members': {n: sha(formal/n) for n in checker.MEMBERS},
|
||||
'pid': pids[0], 'cell': target, 'instance_id': 'f4'})
|
||||
row = {'id': 'resume_overlap', 'kind': 'build', 'position': position(target),
|
||||
@@ -259,6 +277,14 @@ def make(base, source, checker):
|
||||
pair('pair', [101, 102], 'handler')
|
||||
pair('os-pair', [201, 202], 'native_os')
|
||||
shutil.copytree(out/'pair/formal', out/'pair/initial-formal')
|
||||
initial = copy.deepcopy(json.loads((out/'pair/formal-export.json').read_text()))
|
||||
initial.update(requested_path='user://saves/p08_initial',absolute_path='/synthetic-private-profile/saves/p08_initial')
|
||||
initial['packages'] = {'initial-formal':initial['packages']['formal'],
|
||||
'initial-formal.bak':{'present':False,'source_path':initial['absolute_path']+'.bak','members':{}}}
|
||||
initial['packages']['initial-formal']['source_path'] = initial['absolute_path']
|
||||
shutil.copyfile(out/'pair/initial-formal/manifest.json',out/'pair/initial-formal-slot-metadata.json')
|
||||
initial['slot_metadata']['file'] = 'initial-formal-slot-metadata.json'
|
||||
put(out/'pair/initial-formal-export.json',initial)
|
||||
for role, pid in (('writer',201),('reader',202)):
|
||||
prefix = 'os-runs/'+role+'/'
|
||||
folder = out/prefix
|
||||
|
||||
+2
-6
@@ -73,6 +73,7 @@ func setup() -> void:
|
||||
if role == "writer":
|
||||
await load_menu(main.find_child("SaveLoadMenu", true, false))
|
||||
var stored: Dictionary = SaveService.inspect_snapshot(ProjectSettings.globalize_path(String(main.manual_save_path)))
|
||||
record_save_result("initial_inspect", String(main.manual_save_path), stored)
|
||||
expect(bool(stored.get("ok", false)), "read-only initial formal inspection")
|
||||
expect(runtime.create_snapshot() == stored.get("snapshot", {}), "OS initial formal model exact")
|
||||
expect(clock.paused, "diagnostic formal fixture starts paused")
|
||||
@@ -154,12 +155,7 @@ func load_menu(menu: MenuButton) -> void:
|
||||
await request(action)
|
||||
|
||||
func archive_formal() -> void:
|
||||
DirAccess.make_dir_recursive_absolute(directory.path_join("formal"))
|
||||
for member: String in MEMBERS:
|
||||
var source := ProjectSettings.globalize_path(String(main.manual_save_path)).path_join(member)
|
||||
var destination := directory.path_join("formal/" + member)
|
||||
expect(DirAccess.copy_absolute(source, destination) == OK, "archive formal " + member)
|
||||
expect(FileAccess.get_sha256(source) == FileAccess.get_sha256(destination), "archive formal SHA " + member)
|
||||
export_package(String(main.manual_save_path), "formal")
|
||||
|
||||
func finish_observations() -> void:
|
||||
json_file(role + "-requests.json", {"pid": OS.get_process_id(), "requests": all_requests})
|
||||
|
||||
Vendored
+74
-4
@@ -18,6 +18,9 @@ var target := Vector3i(-8, 0, 0)
|
||||
var budget: Dictionary = {}
|
||||
var input_method := "handler"
|
||||
var observed_cell: Variant = null
|
||||
var save_serial := 0
|
||||
var save_records: Array = []
|
||||
const INITIAL_SAVE := "user://saves/p08_initial"
|
||||
|
||||
func annotate(row: Dictionary) -> void:
|
||||
row["input_method"] = input_method
|
||||
@@ -69,6 +72,8 @@ func button(node: BaseButton) -> void:
|
||||
expect(node != null and not node.disabled, "available production button")
|
||||
if node == null or node.disabled:
|
||||
return
|
||||
if node.toggle_mode:
|
||||
node.button_pressed = not node.button_pressed
|
||||
node.pressed.emit()
|
||||
await frames()
|
||||
|
||||
@@ -77,7 +82,9 @@ func choose(id: StringName) -> void:
|
||||
await button(main.palette_toggle_button)
|
||||
var node: Button = main.build_buttons[id]
|
||||
await reveal(node)
|
||||
await button(node)
|
||||
if not node.button_pressed:
|
||||
await button(node)
|
||||
expect(node.button_pressed and main._selected_definition_id == id, "chosen production definition")
|
||||
|
||||
func click(cell: Vector3i) -> Dictionary:
|
||||
var view: WorldPreview = main.world_preview
|
||||
@@ -253,6 +260,7 @@ func run(p_tree: SceneTree, output: String, requested_role: String) -> Dictionar
|
||||
expect(DirAccess.make_dir_recursive_absolute(directory) == OK, "diagnostic directory")
|
||||
runtime = tree.root.get_node("SimulationRuntime")
|
||||
clock = tree.root.get_node("GameClock")
|
||||
runtime.save_operation_completed.connect(record_save_operation)
|
||||
await setup()
|
||||
runtime.command_completed.connect(observe)
|
||||
main.world_preview.cell_clicked.connect(selected_cell)
|
||||
@@ -265,10 +273,12 @@ func run(p_tree: SceneTree, output: String, requested_role: String) -> Dictionar
|
||||
if requested_role == "standalone":
|
||||
role = "reader"
|
||||
actions = []
|
||||
save_records = []
|
||||
await reader(false)
|
||||
json_file(role + "-actions.json", {"setup": "diagnostic", "input_method": input_method, "actions": actions})
|
||||
finish_observations()
|
||||
runtime.command_completed.disconnect(observe)
|
||||
runtime.save_operation_completed.disconnect(record_save_operation)
|
||||
var cleanup: Dictionary = await Cleanup.free_owner_and_wait(tree, main)
|
||||
expect(cleanup.get(&"passed", false), "ordinary Main/audio cleanup")
|
||||
json_file(role + "-process.json", {"pid": OS.get_process_id(), "engine": Engine.get_version_info(), "checks": checks, "failures": failures, "role": requested_role, "setup": "diagnostic"})
|
||||
@@ -296,18 +306,78 @@ func setup() -> void:
|
||||
clock.set_paused(true)
|
||||
tree.root.size = Vector2i(1440, 810)
|
||||
main = load("res://scenes/main/main.tscn").instantiate()
|
||||
main.manual_save_path = directory.path_join("formal")
|
||||
main.manual_save_path = "user://saves/manual_ui"
|
||||
if role == "reader":
|
||||
import_package(directory.path_join("formal"), String(main.manual_save_path))
|
||||
tree.root.add_child(main)
|
||||
runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
|
||||
|
||||
func save_initial_fixture() -> void:
|
||||
# Explicit diagnostic input, not an OS action or natural-play save.
|
||||
var saved: Dictionary = SaveService.save_snapshot(directory.path_join("initial-formal"), runtime.create_snapshot())
|
||||
var saved: Dictionary = SaveService.save_snapshot(INITIAL_SAVE, runtime.create_snapshot())
|
||||
record_save_result("initial_save", INITIAL_SAVE, saved)
|
||||
expect(bool(saved.get("ok", false)), "diagnostic initial formal save")
|
||||
export_package(INITIAL_SAVE, "initial-formal")
|
||||
# Seed the private normal slot, so its later normal save produces a backup.
|
||||
import_package(ProjectSettings.globalize_path(INITIAL_SAVE), String(main.manual_save_path))
|
||||
json_file("diagnostic-budget.json", budget)
|
||||
|
||||
func archive_formal() -> void:
|
||||
pass
|
||||
export_package(String(main.manual_save_path), "formal")
|
||||
|
||||
func record_save_operation(result: Dictionary) -> void:
|
||||
record_save_result("runtime_operation", String(main.manual_save_path), result)
|
||||
|
||||
func record_save_result(operation: String, path: String, result: Dictionary) -> void:
|
||||
save_serial += 1
|
||||
var stem := "%s-save-result-%04d" % [role, save_serial]
|
||||
var raw := FileAccess.open(directory.path_join(stem + ".var"), FileAccess.WRITE)
|
||||
expect(raw != null, "raw save result")
|
||||
if raw != null:
|
||||
raw.store_buffer(var_to_bytes(result))
|
||||
raw.close()
|
||||
json_file(stem + ".json", {"pid": OS.get_process_id(), "operation": operation,
|
||||
"requested_path": path, "absolute_path": ProjectSettings.globalize_path(path),
|
||||
"user_data_dir": OS.get_user_data_dir(), "result": Codec.new().typed(result),
|
||||
"raw_sha256": FileAccess.get_sha256(directory.path_join(stem + ".var"))})
|
||||
save_records.append(stem)
|
||||
json_file(role + "-save-results.json", {"pid": OS.get_process_id(), "records": save_records})
|
||||
|
||||
func import_package(source: String, destination: String) -> void:
|
||||
var absolute := ProjectSettings.globalize_path(destination)
|
||||
expect(DirAccess.make_dir_recursive_absolute(absolute) == OK, "private save directory")
|
||||
for member: String in MEMBERS:
|
||||
var origin := source.path_join(member)
|
||||
var copy := absolute.path_join(member)
|
||||
expect(DirAccess.copy_absolute(origin, copy) == OK, "private save input " + member)
|
||||
expect(FileAccess.get_sha256(origin) == FileAccess.get_sha256(copy), "private save input SHA " + member)
|
||||
|
||||
func export_package(path: String, name: String) -> void:
|
||||
var absolute := ProjectSettings.globalize_path(path)
|
||||
var pins := {}
|
||||
for suffix: String in ["", ".bak"]:
|
||||
var source := absolute + suffix
|
||||
var present := DirAccess.dir_exists_absolute(source)
|
||||
pins[name + suffix] = {"source_path": source, "present": present, "members": {}}
|
||||
if not present:
|
||||
expect(not suffix.is_empty(), "formal package exists")
|
||||
continue
|
||||
var destination := directory.path_join(name + suffix)
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination) == OK, "export directory")
|
||||
for member: String in MEMBERS:
|
||||
var origin := source.path_join(member)
|
||||
var copy := destination.path_join(member)
|
||||
expect(DirAccess.copy_absolute(origin, copy) == OK, "export " + member)
|
||||
var digest := FileAccess.get_sha256(origin)
|
||||
expect(not digest.is_empty() and digest == FileAccess.get_sha256(copy), "export SHA " + member)
|
||||
pins[name + suffix]["members"][member] = {"sha256": digest, "bytes": FileAccess.get_file_as_bytes(copy).size()}
|
||||
# Slot metadata lives in the existing manifest; copy it verbatim.
|
||||
var metadata := absolute.path_join("manifest.json")
|
||||
var metadata_copy := directory.path_join(name + "-slot-metadata.json")
|
||||
expect(DirAccess.copy_absolute(metadata, metadata_copy) == OK, "slot metadata export")
|
||||
json_file(name + "-export.json", {"pid": OS.get_process_id(), "requested_path": path,
|
||||
"absolute_path": absolute, "user_data_dir": OS.get_user_data_dir(), "packages": pins,
|
||||
"slot_metadata": {"file": name + "-slot-metadata.json", "sha256": FileAccess.get_sha256(metadata_copy)}})
|
||||
|
||||
func finish_observations() -> void:
|
||||
pass
|
||||
|
||||
@@ -316,6 +316,20 @@ def check(project_root, evidence_dir):
|
||||
process = document(directory+'/'+role+'-process.json')
|
||||
require(process['pid'] == pid and process['failures'] == 0 and process['checks'] > 0, 'process attribution')
|
||||
require(bool(process['engine']['hash']) and bool(process['engine']['string']), 'engine version')
|
||||
save_log = document(directory+'/'+role+'-save-results.json')
|
||||
require(save_log['pid'] == pid and save_log['records'], 'missing actual save results')
|
||||
operations = []
|
||||
for stem in save_log['records']:
|
||||
record = document(directory+'/'+stem+'.json')
|
||||
raw = artifact(directory+'/'+stem+'.var')
|
||||
require(record['pid'] == pid and record['raw_sha256'] == sha(raw), 'save result attribution/SHA')
|
||||
path = record['requested_path']
|
||||
require(path.startswith('user://') and record['absolute_path'] == str(Path(record['user_data_dir'])/path[7:]), 'save outside private user profile')
|
||||
result = decode(record['result'])
|
||||
require(isinstance(result, dict) and result.get('ok') is True, 'actual save/load failed')
|
||||
if record['operation'] == 'runtime_operation':
|
||||
operations.append(result.get('operation'))
|
||||
require(('save' in operations) if role == 'writer' else any(op in ('load','recovery','recovery_candidate') for op in operations), 'missing actual normal save/load result')
|
||||
doc = document(directory+'/'+role+'-actions.json')
|
||||
require(doc['setup'] == 'diagnostic', 'unlabelled diagnostic')
|
||||
expected = WRITER if role == 'writer' else ['resume_overlap']
|
||||
@@ -361,6 +375,30 @@ def check(project_root, evidence_dir):
|
||||
require(set(saved['members']) == set(MEMBERS) and saved['pid'] == expected_pids[0], 'missing formal members/writer')
|
||||
for member in MEMBERS:
|
||||
require(saved['members'][member] == sha(artifact(directory+'/formal/'+member)), 'formal member changed')
|
||||
exported = document(directory+'/formal-export.json')
|
||||
require(exported['pid'] == expected_pids[0] and exported['requested_path'] == 'user://saves/manual_ui', 'formal export attribution')
|
||||
absolute = str(Path(exported['user_data_dir'])/'saves/manual_ui')
|
||||
require(exported['absolute_path'] == absolute, 'save outside private user profile')
|
||||
for name in ('formal','formal.bak'):
|
||||
package = exported['packages'][name]
|
||||
require(package['present'] and package['source_path'] == absolute+('.bak' if name.endswith('.bak') else '') and set(package['members']) == set(MEMBERS), 'missing formal backup export')
|
||||
for member, pin in package['members'].items():
|
||||
file = artifact(directory+'/'+name+'/'+member)
|
||||
require(pin == {'sha256':sha(file),'bytes':file.stat().st_size}, 'formal export SHA')
|
||||
metadata = exported['slot_metadata']
|
||||
require(metadata['file'] == 'formal-slot-metadata.json' and metadata['sha256'] == sha(artifact(directory+'/'+metadata['file'])) == saved['members']['manifest.json'], 'slot metadata SHA')
|
||||
if not native_os:
|
||||
initial = document(directory+'/initial-formal-export.json')
|
||||
initial_absolute = str(Path(initial['user_data_dir'])/'saves/p08_initial')
|
||||
require(initial['pid'] == expected_pids[0] and initial['requested_path'] == 'user://saves/p08_initial' and initial['absolute_path'] == initial_absolute, 'initial formal private path')
|
||||
package = initial['packages']['initial-formal']
|
||||
require(package['present'] and package['source_path'] == initial_absolute and set(package['members']) == set(MEMBERS), 'initial formal members')
|
||||
for member, pin in package['members'].items():
|
||||
file = artifact(directory+'/initial-formal/'+member)
|
||||
require(pin == {'sha256':sha(file),'bytes':file.stat().st_size}, 'initial formal SHA')
|
||||
require(initial['packages']['initial-formal.bak'] == {'present':False,'source_path':initial_absolute+'.bak','members':{}}, 'unexpected initial backup')
|
||||
metadata = initial['slot_metadata']
|
||||
require(metadata['file'] == 'initial-formal-slot-metadata.json' and metadata['sha256'] == sha(artifact(directory+'/'+metadata['file'])) == package['members']['manifest.json']['sha256'], 'initial slot metadata SHA')
|
||||
facilities = keyed(decode(checkpoint)['systems']['runtime']['construction']['facilities'], 'instance_id')
|
||||
require(saved['instance_id'] in facilities and facilities[saved['instance_id']]['origin'] == saved['cell'], 'wrong resume instance')
|
||||
by_id = {r['id']: r for r in rows}
|
||||
|
||||
@@ -124,15 +124,27 @@ class EvidenceTests(unittest.TestCase):
|
||||
|
||||
def test_wrong_resume(self):
|
||||
path = 'pair/reader-checkpoint.json'
|
||||
original = (self.out/path).read_bytes()
|
||||
model = C.decode(json.loads((self.out/path).read_text()))
|
||||
model['clock']['absolute_minute'] += 1
|
||||
F.put(self.out/path, F.typed(model)); F.repin(self.out)
|
||||
self.reject('wrong resume model')
|
||||
(self.out/path).write_bytes(original); F.repin(self.out)
|
||||
self.edit('pair/reader-save-result-0001.json', lambda d: d.update(result=F.typed({'ok':False,'operation':'load','code':'UNSAFE_PATH'})))
|
||||
self.reject('actual save/load failed')
|
||||
self.edit('pair/reader-save-result-0001.json', lambda d: d.update(result=F.typed({'ok':True,'operation':'load'}), requested_path='/outside/formal'))
|
||||
self.reject('save outside private user profile')
|
||||
|
||||
def test_missing_formal_member(self):
|
||||
(self.out/'pair/formal/journal.log').unlink()
|
||||
F.repin(self.out)
|
||||
self.reject('journal.log')
|
||||
for name in ('formal','formal.bak'):
|
||||
with self.subTest(package=name):
|
||||
file = self.out/('pair/'+name+'/journal.log')
|
||||
original = file.read_bytes()
|
||||
file.unlink(); F.repin(self.out)
|
||||
self.reject('journal.log')
|
||||
file.write_bytes(original); F.repin(self.out)
|
||||
self.edit('pair/formal-export.json', lambda d: d['slot_metadata'].update(sha256='0'*64))
|
||||
self.reject('slot metadata SHA')
|
||||
|
||||
def test_missing_model_member(self):
|
||||
path = 'pair/writer-unsupported-before.json'
|
||||
@@ -238,7 +250,9 @@ class EvidenceTests(unittest.TestCase):
|
||||
private_project=C.runner.private_project, fresh_environment=C.runner.fresh_environment,
|
||||
SUPPORT=ROOT/'tools/regression', module=lambda *a:SimpleNamespace(ordinary_gate=lambda *a:{'mock':True}))
|
||||
outer = SimpleNamespace(native=SimpleNamespace(helper={'live_engines':lambda:[]}),finish_captured=cleanup)
|
||||
with patch.object(D.subprocess,'Popen',side_effect=spawn), contextlib.redirect_stdout(io.StringIO()):
|
||||
# Disk admission is an environmental input to this fully mocked collector.
|
||||
# Preserve the real collector's gate; make this fixture independent of host free space.
|
||||
with patch.object(D.shutil,'disk_usage',return_value=SimpleNamespace(free=1024**3)), patch.object(D.subprocess,'Popen',side_effect=spawn), contextlib.redirect_stdout(io.StringIO()):
|
||||
if fail_wait:
|
||||
with self.assertRaisesRegex(AssertionError,'native OS collection failed'):
|
||||
D.collect_os(r,self.root,output,stage,str(Path(self.temp.name)/'synthetic-engine-not-executable'),'1'*40,refs,protected,outer)
|
||||
|
||||
Reference in New Issue
Block a user