P04-01: 同時発生の更新規約
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# REPAIR38 — superseded by REPAIR39_STATUS.md
|
||||
|
||||
The shared-helper constraint below is historical and was explicitly resolved
|
||||
by the REPAIR39 direction: generalize `_queue` and `_reader` through one
|
||||
CASE_TABLE while preserving S5A/S5B behavior. It is no longer an open question.
|
||||
See REPAIR39_STATUS.md for the current batch status and missing source context.
|
||||
|
||||
## Historical REPAIR38 record
|
||||
|
||||
No implementation or acceptance is submitted by this attempt. No Python or
|
||||
GDScript source was changed. The A–F batch remains outstanding, not complete
|
||||
or admitted for native execution.
|
||||
|
||||
The direction both freezes `_queue` and `_reader` as shared helpers and asks
|
||||
for new reservation-bearing cases with before/boundary/next/replay points.
|
||||
The existing helpers contain case-specific assertions and replay dispatch:
|
||||
|
||||
- `s5/p04_s5_power_probe.gd::_queue` requires exactly one reserved inventory ID
|
||||
only when `_case == "S5B_DEPENDENCY"`; every other case must have zero.
|
||||
Using this unchanged helper for the required reservation-bearing S5C/S5F
|
||||
queued request would fail its assertion even with correct runtime behavior.
|
||||
- `_reader` unconditionally calls `_assert_stopped` after loading boundary,
|
||||
then replays the literal labels `held`, `recovered`, `duplicate_guard`.
|
||||
Per-case `_labels` does not control that replay loop. New next/replay points
|
||||
cannot be independently replayed through this loop as written.
|
||||
|
||||
Required clarification: does “shared helpers stay unchanged” allow replacing
|
||||
these case-specific predicates/dispatch with case-table lookups while keeping
|
||||
S5A/S5B behavior and every existing assertion equivalent? Alternatively, are
|
||||
separate new-case queue/replay helpers authorized while the existing helpers
|
||||
remain exclusively the power-case implementation? No selection between these
|
||||
interpretations was silently made. This is an implementation-constraint
|
||||
question, not a request to reopen D05 or A01.
|
||||
|
||||
Read context includes AGENTS.md, REPAIR37_STATUS.md, the existing S5 probe and
|
||||
wrapper, S5_ROOT_RUN.md, PENDING.md, D05_REMAINING_APPROVAL.json, Root's local
|
||||
q37-remaining-source-map/SOURCE_MAP.json and referenced facility and automatic
|
||||
defense sources. Root's M runtime reference is present; the worktree runtime
|
||||
is a different version and must not substitute for that reference.
|
||||
|
||||
Only read-only source inspection and this status documentation were performed.
|
||||
No pure controls, py_compile, AST validation, probe_guard, engine, Git, Runner,
|
||||
native run, other agent, integration or /tmp operation was performed. No
|
||||
REPAIR38_STATIC_CHECKS.json claiming validation is supplied because no source
|
||||
checks were run. PENDING.md is not marked superseded: cases remain unimplemented.
|
||||
|
||||
r35/r36 remain FAILED; Q37 remains a successful local diagnostic only. M
|
||||
c0ea009, original 30/88, formal 16/88 and P04 credit 0 remain unchanged. The
|
||||
15+EV requirements, seven domains, all six D05 decisions and A01 are unchanged.
|
||||
After clarification and completion of the entire source batch, Root's required
|
||||
order remains pure controls, check-only S1–S5 plan, focused fresh native S1–S5,
|
||||
fresh collect, full184/329 on final Q, index, --verify-only, independent review,
|
||||
and normal gates with Root join. None of these steps is authorized or claimed
|
||||
as performed by this worker status record.
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"task_id": "P04-01",
|
||||
"repair": 39,
|
||||
"status": "blocked",
|
||||
"source_files_modified": [],
|
||||
"checks_run": [],
|
||||
"reason": "Documentation-only blocked record; required exact-version source context missing. No py_compile, AST, probe_guard or functional validation executed.",
|
||||
"accepted": false,
|
||||
"native_admissible": false,
|
||||
"unit_accepted": false
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
# REPAIR39 — blocked: required exact-version source context unavailable
|
||||
|
||||
The REPAIR38 engineering constraint is resolved. The authorized implementation
|
||||
choice is one CASE_TABLE with reserved-ID counts, replay labels and per-case
|
||||
dispatch; `_queue` and `_reader` may be generalized without forking them.
|
||||
No private-refactor or policy question remains open.
|
||||
|
||||
The complete A–F batch remains unimplemented in this attempt. No executable
|
||||
source was changed, no partial batch is submitted, and no native admission or
|
||||
acceptance is claimed. PENDING.md and S5_ROOT_RUN.md remain unchanged because
|
||||
the cases and whole-batch prerequisites have not been implemented.
|
||||
|
||||
## Required context gap
|
||||
|
||||
REPAIR38 records reading Root's `q37-remaining-source-map/SOURCE_MAP.json`
|
||||
and an M runtime reference, explicitly distinguishing that reference from
|
||||
the worker runtime. Those materials are not present in this checkout or the
|
||||
registered runtime directory in this session. Recursive file enumeration used
|
||||
hidden and ignored files as well. The checkout has no `.review-material`.
|
||||
The previous owner-handoff references documented in REPAIR36/37 are likewise
|
||||
absent from the enumerated runtime files.
|
||||
|
||||
Direct reads establish:
|
||||
|
||||
| Available input | SHA256 / result |
|
||||
| --- | --- |
|
||||
| checkout autoload/simulation_runtime.gd | d52a995ae715542bbc550f68d35889540658275d12e04ae0b21ac276f5843f39 |
|
||||
| relocated R17 product autoload/simulation_runtime.gd | 7f01b2dcdf28bc965c7588173c2dc70054633faf7204b1ac38ba0f4369331b47 |
|
||||
| tools/run_all_tests.py in both locations | 320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4 |
|
||||
| tools/run_p13_reference_tests.py in both locations | missing |
|
||||
|
||||
The matching runner file is available; it is not itself a missing dependency.
|
||||
Neither available runtime is established here as the frozen M c0ea009 source.
|
||||
The phase facts in the direction do not supply the missing function bodies,
|
||||
exact source mapping or UID helper contract. Substituting the historical R17
|
||||
product or the worker runtime would not meet exact-version grounding.
|
||||
|
||||
Required to resume the same full batch: restore the locally readable,
|
||||
hash-bound M source map and its referenced source bodies (including runtime,
|
||||
facility and defense dependencies), and the Q UID helper reference used by
|
||||
REPAIR36/37. Restore the q36-writer-contract INDEX and its referenced typed
|
||||
materials for the existing adapter-control dependency. These are context
|
||||
requirements, not requests for a new policy, acceptance waiver or native run.
|
||||
|
||||
## Work and validation actually performed
|
||||
|
||||
Read-only file discovery, relevant existing status/probe/wrapper inspection,
|
||||
local input inspection and SHA256 computation were performed. Only this status,
|
||||
REPAIR39_STATIC_CHECKS.json and the REPAIR38 supersession notice were written.
|
||||
No Python or GDScript was modified, so no py_compile, AST or probe_guard check
|
||||
was run. No controls, engine, Git, Runner, native execution, other agent,
|
||||
integration or /tmp operation was performed.
|
||||
|
||||
r35 and r36 remain FAILED; Q37 remains a successful local diagnostic only.
|
||||
M c0ea009, formal 16/88, original 30/88, P04 credit 0, the 15+EV membership
|
||||
and thresholds, seven domains, six D05 decisions, A01 and allowed_paths remain
|
||||
unchanged. No original-unit completion is asserted.
|
||||
|
||||
After the complete source batch, Root's order remains: pure controls;
|
||||
check-only S1–S5 plan; one heavy lease for fresh S1–S5 with capacity/PID checks
|
||||
and verified restore manifest; fresh collect; full184/329 once on final Q;
|
||||
index; --verify-only; independent review; normal prepare/final and Root join.
|
||||
This blocked attempt does not authorize starting that sequence.
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"task_id": "P04-01",
|
||||
"repair": 40,
|
||||
"scope": "static only; no execution of probes, wrappers, adapters, controls, engine or Runner",
|
||||
"python": [
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s1/run_s1_native.py",
|
||||
"sha256": "bb7afc6cabc4f515318c30adcce5ab30a8932a893d1d358b8c05ff4750f4688f",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s2/run_s2a_native.py",
|
||||
"sha256": "101431b3a84eeb9aaf8d6a1171a4ebdbba884ffb10fee32a709f04a28b8a1547",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s2b/run_s2b_native.py",
|
||||
"sha256": "13398072583f9be02a2db3182298f572d77782ab39da8123c503ae8b951c9851",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s3/run_s3_native.py",
|
||||
"sha256": "118843aa5bc69548634f958cb31f359777577239b54351e59df367f7d0a5e409",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py",
|
||||
"sha256": "cb43895ee8ee5b22e81aca633dbe9621000f14aaa6999d4e0b77ca8eb0b5602f",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py",
|
||||
"sha256": "9cfd1b7a4db638c65c0a66a4350b8acae5237d3aee568e72f8fe9fd3c451d2ad",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_power_adapter.py",
|
||||
"sha256": "307438660ec5ffbbb24e7a12a87374ddf3b0d0db7d0c0fd06e4841622e677525",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_order_adapter.py",
|
||||
"sha256": "abe02702027946778717aa0139b99d6986d3d03605c1afcd38763c65424b3c01",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_order_adapter_controls.py",
|
||||
"sha256": "58a13df13f01c5d46268c68a7e969cc38608f97f9990f79b1b77d56b1712736a",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py",
|
||||
"sha256": "2155e697a08bc5f4c38f320a08aedb4ded1fb6c5fcb046482312e1819829da98",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/collect_p04_native.py",
|
||||
"sha256": "662387af72d2bd7681b81ffff7ec2e54a0019c50e981f86c7cfcf1ed61440e04",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/full_suite_verifier.py",
|
||||
"sha256": "df3768b7755d603fc079e899da8f06ae4ebb529ae531824a30add0f4d6773a6e",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/build_p04_index.py",
|
||||
"sha256": "d9be9e773d84bf30f086cc25c157c089025896279e30c8db2eb2995d6616715c",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_series_fixtures.py",
|
||||
"sha256": "5ec725ad77313287f4f86ab30332012e2092caccafde2d91594ddd2013d8f418",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
},
|
||||
{
|
||||
"path": "tools/check_p04_order_evidence.py",
|
||||
"sha256": "8f288c127217a9586ddaeba9b97d21351ee4b3dfc6c199632f66e4cdc0554042",
|
||||
"AST": "passed",
|
||||
"py_compile": "passed"
|
||||
}
|
||||
],
|
||||
"gdscript": {
|
||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/p04_s5_power_probe.gd",
|
||||
"sha256": "496dc6a9c828ae355fc129c4886ec83c6c6dcc9a9cd5e484b42060517059b1de",
|
||||
"probe_guard_regexes": [
|
||||
"\\bvar\\s+\\w+\\s*=",
|
||||
"\\bfor\\s+\\w+\\s+in\\b",
|
||||
"\\.(?:patience_remaining|elapsed_minutes|power_available|capacity|hold_until)\\s*=(?!=)"
|
||||
],
|
||||
"result": "passed",
|
||||
"case_table_static_dispatch": "passed"
|
||||
},
|
||||
"not_run": [
|
||||
"pure controls",
|
||||
"Godot parse/native",
|
||||
"S1-S5 check-only plans",
|
||||
"fresh collection",
|
||||
"full suite",
|
||||
"index/verify-only",
|
||||
"independent review"
|
||||
],
|
||||
"formal_acceptance": false
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
# REPAIR40 status
|
||||
|
||||
Step 0: context index SHA-256 verified: 6f0ee990b95a5a897511425cd86ae57ba0364c5b326afdeb9f556fabfea6915c.
|
||||
|
||||
| Absolute path | Expected SHA-256 | Observed SHA-256 |
|
||||
| --- | --- | --- |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_ABSOLUTE_CONTEXT_INDEX.json | 6f0ee990b95a5a897511425cd86ae57ba0364c5b326afdeb9f556fabfea6915c | 6f0ee990b95a5a897511425cd86ae57ba0364c5b326afdeb9f556fabfea6915c |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ACTUAL_OPUS_NEXT_P04_PLAN.json | 217d9bf4ef593fb95a5e726fee0e4497863a0b06663d27ba20e742d81bb9c049 | 217d9bf4ef593fb95a5e726fee0e4497863a0b06663d27ba20e742d81bb9c049 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ACTUAL_OPUS_REPAIR30_DIRECT_CHECKER_PLAN.json | 77801cc6db2a4deb9f76118a746b32eb5e629b2d6980850b8813a12b45016806 | 77801cc6db2a4deb9f76118a746b32eb5e629b2d6980850b8813a12b45016806 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ACTUAL_OPUS_REPAIR30_RUN_DECISION.json | be7be3bfaa5a5ab412db8aecd1d951c213894e485b7869fcc12ab1c75b037c7f | be7be3bfaa5a5ab412db8aecd1d951c213894e485b7869fcc12ab1c75b037c7f |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ACTUAL_OPUS_REPAIR31_CONCRETE_PLAN.json | 857e1acaed2093de56afdd851e69b3129bf9edce72b5da3cdd160ce4b7bfc18a | 857e1acaed2093de56afdd851e69b3129bf9edce72b5da3cdd160ce4b7bfc18a |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ACTUAL_OPUS_REPAIR32_CONCRETE_PLAN.json | 5b69f850f835bd7af37e9c728c484c236c28efb0bd32113bb53bcbaf7d252c0a | 5b69f850f835bd7af37e9c728c484c236c28efb0bd32113bb53bcbaf7d252c0a |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/CURRENT_ROOT_P04_RESUME_FACTS.json | c826726368844a823c54c1df1cdaff43fde5a94a17e638bfc60d8fb2559f8d85 | c826726368844a823c54c1df1cdaff43fde5a94a17e638bfc60d8fb2559f8d85 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/D05_ACTUAL_HUMAN_APPROVAL.json | cd365ded1b777a0327d090709f0a4161f5005562819183455d9f2e106fba3e96 | cd365ded1b777a0327d090709f0a4161f5005562819183455d9f2e106fba3e96 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_FRESH_Q_INPUT_APPROACH_AFTER34.json | 7a7b91cbf04bb84cdef8e7a99ca2140a9eac2ac6a385570b4f0aa0d474e7da92 | 7a7b91cbf04bb84cdef8e7a99ca2140a9eac2ac6a385570b4f0aa0d474e7da92 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_P04_PRESERVED_TO_CURRENT_SOURCE_AUDIT.json | 6bb86959b06acb62d5cd3c5fd00bb6802a80b66184e69abca3f75c46ddeb7a12 | 6bb86959b06acb62d5cd3c5fd00bb6802a80b66184e69abca3f75c46ddeb7a12 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_PLAN_VERSION_NOTES.json | b4336f900a87f9bf0daa1e86728c3a913aed7c09425569e104cc01290be1c62f | b4336f900a87f9bf0daa1e86728c3a913aed7c09425569e104cc01290be1c62f |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/INDEX.json | b2ad602b7bd22dbc4778b60b4a015b1d2f8f06b71278959fb52910f2ee1af57a | b2ad602b7bd22dbc4778b60b4a015b1d2f8f06b71278959fb52910f2ee1af57a |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_CHECK_ONLY.json | aab7dcbfcc934f3bda7d937feb4e7638109ddf645da6ebd57f6190588b55287c | aab7dcbfcc934f3bda7d937feb4e7638109ddf645da6ebd57f6190588b55287c |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_NEGATIVE_GIT.json | e63b1b27244cd042f522a63b4392dea8c7211ce5ca5a927e91856115dfaa9f56 | e63b1b27244cd042f522a63b4392dea8c7211ce5ca5a927e91856115dfaa9f56 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_NEGATIVE_dirty.log | 3ad8ef5d71175bc265f93395fe64a39b05ab65252ad509abc108de15a2b9ab53 | 3ad8ef5d71175bc265f93395fe64a39b05ab65252ad509abc108de15a2b9ab53 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_NEGATIVE_untracked.log | 3ad8ef5d71175bc265f93395fe64a39b05ab65252ad509abc108de15a2b9ab53 | 3ad8ef5d71175bc265f93395fe64a39b05ab65252ad509abc108de15a2b9ab53 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_NEGATIVE_wrong-main.log | 006b9e83c3e106bada560371dda1fb9b4326e3f31fa48fa0c46e7d4903a91e55 | 006b9e83c3e106bada560371dda1fb9b4326e3f31fa48fa0c46e7d4903a91e55 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_NEGATIVE_wrong-submission.log | 6fefa0256b2dbc1596043fbff65fbaf87279baaa770a04d65a5fe70a6476671d | 6fefa0256b2dbc1596043fbff65fbaf87279baaa770a04d65a5fe70a6476671d |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_NEGATIVE_wrong-tree.log | 7fb7a1e4f00f201b7008b6d72957b3d4db450be156a1174b26a22c36d48b5e8f | 7fb7a1e4f00f201b7008b6d72957b3d4db450be156a1174b26a22c36d48b5e8f |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_RESOURCE_ADMISSION.json | 18ef80f33f36cdd6ab664c862a9ae651a649a532bd32c4c35a81640cb4f078a0 | 18ef80f33f36cdd6ab664c862a9ae651a649a532bd32c4c35a81640cb4f078a0 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_STAGE.json | f143045846cf06d79b81a0e52035300251fa576cde9a2d5eeda97d6610fd8591 | f143045846cf06d79b81a0e52035300251fa576cde9a2d5eeda97d6610fd8591 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_check-only.log | 4418f4b6bbe3d88cbf7f0b988084e05b5f0f52c15fe0f466ba82e584408427ce | 4418f4b6bbe3d88cbf7f0b988084e05b5f0f52c15fe0f466ba82e584408427ce |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_Q35_LOCAL_DIAGNOSTIC_INPUTS/ROOT_Q35_pure.log | f77640e0629497389baefc6424cf164d164fb96bbbd48cee6c4d83ed96c253c1 | f77640e0629497389baefc6424cf164d164fb96bbbd48cee6c4d83ed96c253c1 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_REPAIR30_EXECUTION_ORDER_FACTS.json | e18b031e790622929ec2c80ab9a6d5c3d883a364d625b58372fe33fd280ca93f | e18b031e790622929ec2c80ab9a6d5c3d883a364d625b58372fe33fd280ca93f |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/ROOT_REPAIR31_ACTUAL_FACTS.json | 0ea352b442e88263b899d28d58422afed39855393233c35ed3a962fcab67e136 | 0ea352b442e88263b899d28d58422afed39855393233c35ed3a962fcab67e136 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/INDEX.json | ff43786d898ef3475c267cf22758074a001b3d46dbc2bea52782a3782dd5571e | ff43786d898ef3475c267cf22758074a001b3d46dbc2bea52782a3782dd5571e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/autoload/simulation_runtime.gd | 45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0 | 45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/scenes/main/main.gd | 92677e4ac57ed8d418a4a716bf0874cbbaea79cff893e5163c82ad1f75e7140a | 92677e4ac57ed8d418a4a716bf0874cbbaea79cff893e5163c82ad1f75e7140a |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/scenes/main/world_preview.gd | 4bc49a19a38b9c3b4d6bfc243ddf46f1f25469a8273adb5e812911ef9424a1f2 | 4bc49a19a38b9c3b4d6bfc243ddf46f1f25469a8273adb5e812911ef9424a1f2 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/scripts/core/save_service.gd | f4c270632225dd046bbff92f9472761d64d63740e93f274828c92dcf912db6a9 | f4c270632225dd046bbff92f9472761d64d63740e93f274828c92dcf912db6a9 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/scripts/relationship/relationship_service.gd | d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3 | d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/scripts/ui/guest_observation_panel.gd | f5de1004fce5445bbfd3ee8d6ec37b325e7a9813d47c19beaeeeb411f27a50a5 | f5de1004fce5445bbfd3ee8d6ec37b325e7a9813d47c19beaeeeb411f27a50a5 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/scripts/ui/room_presentation.gd | 2eda851534777575298ea005e2e6d0ee90785a81357d5b9c34cfb95f615a8181 | 2eda851534777575298ea005e2e6d0ee90785a81357d5b9c34cfb95f615a8181 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/tests/business/test_required_kitchen.gd | 3a9c92f80c24064ef0858fba10bd7caab63203932942837f7e142349578f6b2f | 3a9c92f80c24064ef0858fba10bd7caab63203932942837f7e142349578f6b2f |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/tools/regression/suite-policy.json | 7eb085d7e7a383785b4faedb503d0f6002bcad431e3188785aef901ce123769f | 7eb085d7e7a383785b4faedb503d0f6002bcad431e3188785aef901ce123769f |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/full-standard-schema-example/INDEX.json | a7a3299c4d70ea033368a707882856fd5c7f7f4d5a0d5f86bf2fb9b2fe2e53d1 | a7a3299c4d70ea033368a707882856fd5c7f7f4d5a0d5f86bf2fb9b2fe2e53d1 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/full-standard-schema-example/controller-input.json | 24d10b3a91553df54b3b2fd4b1a57dce683cc72a55576e0c73c9e142b335ad40 | 24d10b3a91553df54b3b2fd4b1a57dce683cc72a55576e0c73c9e142b335ad40 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/full-standard-schema-example/controller.py | 9e03ecba1819c449c83a9dfba0f60c0e01f94aad728c46f60dd1db179224a89b | 9e03ecba1819c449c83a9dfba0f60c0e01f94aad728c46f60dd1db179224a89b |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/full-standard-schema-example/run/003-receipt.json | 4ce015c160859612c89e215517826aa1da3582534d27c4688af6a44e37f1b641 | 4ce015c160859612c89e215517826aa1da3582534d27c4688af6a44e37f1b641 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/full-standard-schema-example/run/parse-receipt.json | 1ad82022669a3f197f53ed1e23f23aadc927220f0ba1f857c41f80721bafa443 | 1ad82022669a3f197f53ed1e23f23aadc927220f0ba1f857c41f80721bafa443 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/full-standard-schema-example/run/runner-ended.json | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/full-standard-schema-example/run/runner-input.json | 2a76506e923a3a95288ce826b81ed9eab49d4ecee613a2c82ae35e970c68f961 | 2a76506e923a3a95288ce826b81ed9eab49d4ecee613a2c82ae35e970c68f961 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/normal-candidate-example/INDEX.json | 942181cc3efc8207e728233f89626b66eb0c34b582e5c9b0fae294dcf1600c00 | 942181cc3efc8207e728233f89626b66eb0c34b582e5c9b0fae294dcf1600c00 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/normal-candidate-example/ROOT_EXACT_NORMAL_CANDIDATE_72A50A4A.json | 5614c9b1c9eb222dbbcfd9ae1c3b438cc4129c779deba2841d660a8c96b6cfe6 | 5614c9b1c9eb222dbbcfd9ae1c3b438cc4129c779deba2841d660a8c96b6cfe6 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/normal-candidate-example/ROOT_NORMAL_FINAL_72A50A4A.json | b41069126e029c30ab644a62a54cb45ca2e0e504add150020500acba4e249469 | b41069126e029c30ab644a62a54cb45ca2e0e504add150020500acba4e249469 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/normal-candidate-example/ROOT_NORMAL_INTEGRATION_72A50A4A.json | 2f47d39d3f05b3735f0fb3e01adaabf1c66c6a784d60af247063bd90e5ec0d5c | 2f47d39d3f05b3735f0fb3e01adaabf1c66c6a784d60af247063bd90e5ec0d5c |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/INDEX.json | a23f17336a5e701100c224ebcb69f37a8de95aca82658675b692d503798a5232 | a23f17336a5e701100c224ebcb69f37a8de95aca82658675b692d503798a5232 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/OWNER_CLI_REFERENCE.json | 1e360ad1d8057ef649fabe97ac3e98263d2f8c1c4d976d8b6e0a907a49e9158e | 1e360ad1d8057ef649fabe97ac3e98263d2f8c1c4d976d8b6e0a907a49e9158e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/ROOT_SOURCE_REVIEW_REJECTION_20D0AE5.json | d028dd3862ae663586d49b5843e88d9da82ad7985fa082551438e4a81311073e | d028dd3862ae663586d49b5843e88d9da82ad7985fa082551438e4a81311073e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/SOURCE_REWORK_ADAPTER_LOCAL_CHECKS.json | 580f2f19d680a23ee4efe6beab68a1aad69e067bc551f623cc7531c6915d7a78 | 580f2f19d680a23ee4efe6beab68a1aad69e067bc551f623cc7531c6915d7a78 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/SOURCE_REWORK_CURRENT_REFERENCE_INDEX.json | b0ecce7ae523527fdc6272e9784eba6109d67c0cd3745a8aaab64d913ca8adbd | b0ecce7ae523527fdc6272e9784eba6109d67c0cd3745a8aaab64d913ca8adbd |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/core.py.reference | 4c6067bbd57034764873a468ff161a6882d232503043d5640fc83dea0b455856 | 4c6067bbd57034764873a468ff161a6882d232503043d5640fc83dea0b455856 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/current-owner-cli.py.reference | 0cfd9634e4a59755b89d2927d60b6092368529f2ca7188d949da7f88080359aa | 0cfd9634e4a59755b89d2927d60b6092368529f2ca7188d949da7f88080359aa |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/owner-cli.py.reference | 52c327e624334b51612ea3cb1653aeff4a7a192502d1ba9407ce874af1d92410 | 52c327e624334b51612ea3cb1653aeff4a7a192502d1ba9407ce874af1d92410 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/owner-normal-gates-reference/owner-source-rework-20d0ae5.py.reference | 9ecf7bebf666a67a8f13357d66e9c1d8d76940ef8212f0055537b728c75e0cbc | 9ecf7bebf666a67a8f13357d66e9c1d8d76940ef8212f0055537b728c75e0cbc |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/FAILED_EXECUTION.json | 6e48da89ce852dacdbff2d0f93a8903583dccd9e05f5e34bb68be0d63f540332 | 6e48da89ce852dacdbff2d0f93a8903583dccd9e05f5e34bb68be0d63f540332 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/FAILED_IMPORT_COMBINED.log | cd39b1711f530454b0ec263ab2d076d714f674d5a36e26f9ef16788799b76764 | cd39b1711f530454b0ec263ab2d076d714f674d5a36e26f9ef16788799b76764 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/FAILED_OUTER_OWNED_FINALLY.json | ee14a347724aedb2ae8afecc0775250b1e014c17e726210e2535d6108e57edc0 | ee14a347724aedb2ae8afecc0775250b1e014c17e726210e2535d6108e57edc0 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/INDEX.json | 0e4334442ce89b0388e10a4b62b5e00acbce2013e3ef1967508a3c48d72dc9c1 | 0e4334442ce89b0388e10a4b62b5e00acbce2013e3ef1967508a3c48d72dc9c1 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/P13_CONTROLLER_REFERENCE_INDEX.json | 48434362232d6b58cca720868c6d87f2af48675f365855b8a4a97eb5071dfee3 | 48434362232d6b58cca720868c6d87f2af48675f365855b8a4a97eb5071dfee3 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/P13_FULL_CONTROLLER_PATTERN.py.reference | 9e03ecba1819c449c83a9dfba0f60c0e01f94aad728c46f60dd1db179224a89b | 9e03ecba1819c449c83a9dfba0f60c0e01f94aad728c46f60dd1db179224a89b |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/ROOT_Q35_DIAGNOSTIC_IMPORT_SOURCE_DELTA.json | 1994e59a498f3dbca1fd589b16b5bc6305d2786c0fa730ac489590469f08b05d | 1994e59a498f3dbca1fd589b16b5bc6305d2786c0fa730ac489590469f08b05d |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/ROOT_Q35_FAILED_IMPORT_UID_CLASSIFICATION.json | bc0a863e52db4f98b4b2ee4bc0b513c73f841726789a2ca99521c1b8618dc6c3 | bc0a863e52db4f98b4b2ee4bc0b513c73f841726789a2ca99521c1b8618dc6c3 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/run_all_tests.py.reference | 320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4 | 320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/run_p13_reference_tests.py.reference | 9adc8aa2a7662df8dd70386ddb0bff34574e44d7411de3b6128ddd15eb24675c | 9adc8aa2a7662df8dd70386ddb0bff34574e44d7411de3b6128ddd15eb24675c |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/INDEX.json | cef78b200268e27a6e73ccd926ac95d0b2b6e30b9338a8412da9ab48b68ca82a | cef78b200268e27a6e73ccd926ac95d0b2b6e30b9338a8412da9ab48b68ca82a |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/SAFETY_REAUDIT.json | 8edf11fe7893ced7c6450feb1ee3db45ab0a145db572254d2102ee70e26ac26e | 8edf11fe7893ced7c6450feb1ee3db45ab0a145db572254d2102ee70e26ac26e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/TYPED_AUDIT.json | e1800e1679b570ecdd9d7537e87e0730c089fa3b4c6197d3e279e60959aad016 | e1800e1679b570ecdd9d7537e87e0730c089fa3b4c6197d3e279e60959aad016 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/command_queue.gd.reference | 09b22e6212fa3ce1bf08f5d6b52224a2d3362b3bc63f03a8c98e89af1c6f5895 | 09b22e6212fa3ce1bf08f5d6b52224a2d3362b3bc63f03a8c98e89af1c6f5895 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/facility_instance.gd.reference | 0c6aa493f3299611e05dd26aa429dda8cf7b5c479e4d09632036fb862f79a324 | 0c6aa493f3299611e05dd26aa429dda8cf7b5c479e4d09632036fb862f79a324 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5A_PURE-before.json | af7b1f0099b37298b1bf0d683f98c0ec84fae96b74f16c33af310cab2efa955b | af7b1f0099b37298b1bf0d683f98c0ec84fae96b74f16c33af310cab2efa955b |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5A_PURE-before.var | 61f749b6a10ddc8e70f6e5b1d6378fcf1c0ae5127161a10c9704d76bcf64813a | 61f749b6a10ddc8e70f6e5b1d6378fcf1c0ae5127161a10c9704d76bcf64813a |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5A_PURE-resource-replay.json | 56a7fc36e0972eb64abb19189f1664b87d6a058511bbec0ef7e1497abd2c511e | 56a7fc36e0972eb64abb19189f1664b87d6a058511bbec0ef7e1497abd2c511e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5A_PURE-resource-replay.var | 92aa8694939e2b8b678b556227cce1cf4cda661b6fb1f5a478ac37deba1a072e | 92aa8694939e2b8b678b556227cce1cf4cda661b6fb1f5a478ac37deba1a072e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5B_DEPENDENCY-before.json | 0f821748eb7f12a8ac196c61bca34a7fe55af6adb3ab43d1acf8748fd2be8652 | 0f821748eb7f12a8ac196c61bca34a7fe55af6adb3ab43d1acf8748fd2be8652 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5B_DEPENDENCY-before.var | 06b03c6a50a8832a9cab621b908332199e9ab4d10d4e547111a8860c70535bd2 | 06b03c6a50a8832a9cab621b908332199e9ab4d10d4e547111a8860c70535bd2 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5B_DEPENDENCY-resource-replay.json | 49fb4df6bdaadd9c5146f716a108902c533b137427e2f90f86116393f12c6ea0 | 49fb4df6bdaadd9c5146f716a108902c533b137427e2f90f86116393f12c6ea0 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q36-writer-contract/writer-S5B_DEPENDENCY-resource-replay.var | 464b589fa206427a1becd6dd484fc9be05da1b619ffb26ca559dde83e7b09309 | 464b589fa206427a1becd6dd484fc9be05da1b619ffb26ca559dde83e7b09309 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-power-result/INDEX.json | a8f44235dc8a74e67c3463698619611131224de5048868259a729791614cf9a9 | a8f44235dc8a74e67c3463698619611131224de5048868259a729791614cf9a9 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-power-result/ROOT_Q36_REJECTED_ENQUEUE_STATIC_PATH.json | e8adc79d506491973289084c5ade7c3affe9e3e517896ef191f01cad6dcaed92 | e8adc79d506491973289084c5ade7c3affe9e3e517896ef191f01cad6dcaed92 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-power-result/ROOT_Q37_DIAGNOSTIC_SAFETY_REAUDIT.json | 4d4b059576b3b6d28f71d054eeaf367ead54a74bb499d64bf450d625a137cfa5 | 4d4b059576b3b6d28f71d054eeaf367ead54a74bb499d64bf450d625a137cfa5 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-power-result/ROOT_Q37_POWER_ADAPTER_RESULT.json | cce1132503457675b50d566ad1afc3f67e902a28135550a8e72b647dacd7d70d | cce1132503457675b50d566ad1afc3f67e902a28135550a8e72b647dacd7d70d |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-power-result/ROOT_Q37_PREFLIGHT.json | 3554d8f246c0d117c774ecfabcd9eb48eed311155e3a5a3b15413f3e663b6fd7 | 3554d8f246c0d117c774ecfabcd9eb48eed311155e3a5a3b15413f3e663b6fd7 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-power-result/ROOT_R37_ADAPTER_CONTROLS.json | f62fc981f3935bd969ea5c6fafa5d44a111b1264ad0d04fdb08b07fe4f27429e | f62fc981f3935bd969ea5c6fafa5d44a111b1264ad0d04fdb08b07fe4f27429e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/ROOT_MANA_ADOPTION_CURRENT_APPLICABILITY_C0.json | 57ba42e1c92db194a5ddcb8dc80c8e0249bbab817e35a3ae00bd12b0f4c57731 | 57ba42e1c92db194a5ddcb8dc80c8e0249bbab817e35a3ae00bd12b0f4c57731 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/ROOT_Q37_FULL_ROSTER_PREPARE_ONLY.json | c547dcff95184d04bf7089e7c9f6a2cda800a91359c9ec318f48ad4ecf2887c0 | c547dcff95184d04bf7089e7c9f6a2cda800a91359c9ec318f48ad4ecf2887c0 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/SOURCE_MAP.json | d1333fc891342be5cc16795973fa71e7910a8c8af06ef4a3e51662537fed63c3 | d1333fc891342be5cc16795973fa71e7910a8c8af06ef4a3e51662537fed63c3 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/core/simulation_kernel.gd | 341c0c878c4894adbac628d0db6362ff69fc3347bdd9e61e50936e15dc2d1edb | 341c0c878c4894adbac628d0db6362ff69fc3347bdd9e61e50936e15dc2d1edb |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/economy/economy_service.gd | 95aedd0a0421c93e8fa39f0f76fa890cd0a46905d9a25c88c8b17c4d6d47728e | 95aedd0a0421c93e8fa39f0f76fa890cd0a46905d9a25c88c8b17c4d6d47728e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/facility/facility_service.gd | ceb4a3e9224587423f273cdb2b56e6843ab176ac1fc4fe79dd498b5ed5c33b77 | ceb4a3e9224587423f273cdb2b56e6843ab176ac1fc4fe79dd498b5ed5c33b77 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/guest/guest_service.gd | 56880410e9a00816f9a95d30821982955532de8dd976980934e12016a9f2b21e | 56880410e9a00816f9a95d30821982955532de8dd976980934e12016a9f2b21e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/operations/operations_coordinator.gd | 871a248ee101b6df543fd5cf0440b5d4b0f02c21fa145a99f0687888c1bc6f90 | 871a248ee101b6df543fd5cf0440b5d4b0f02c21fa145a99f0687888c1bc6f90 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/tests/s5/test_runtime_defense_autonomy.gd | 28ca81ddde4da49442b427ed4c55ddcf213ecb389712db585b64cd416636c403 | 28ca81ddde4da49442b427ed4c55ddcf213ecb389712db585b64cd416636c403 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/tests/s5/test_runtime_defense_cycle.gd | a909e2af73aae43590cdd91d07ed2548f4fd2f675d26fa63aa74f6a5cda34357 | a909e2af73aae43590cdd91d07ed2548f4fd2f675d26fa63aa74f6a5cda34357 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/tools/run_all_tests.py | 320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4 | 320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/core/simulation_kernel.gd | 341c0c878c4894adbac628d0db6362ff69fc3347bdd9e61e50936e15dc2d1edb | 341c0c878c4894adbac628d0db6362ff69fc3347bdd9e61e50936e15dc2d1edb |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/current-main-source/autoload/simulation_runtime.gd | 45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0 | 45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/facility/facility_service.gd | ceb4a3e9224587423f273cdb2b56e6843ab176ac1fc4fe79dd498b5ed5c33b77 | ceb4a3e9224587423f273cdb2b56e6843ab176ac1fc4fe79dd498b5ed5c33b77 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/economy/economy_service.gd | 95aedd0a0421c93e8fa39f0f76fa890cd0a46905d9a25c88c8b17c4d6d47728e | 95aedd0a0421c93e8fa39f0f76fa890cd0a46905d9a25c88c8b17c4d6d47728e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/operations/operations_coordinator.gd | 871a248ee101b6df543fd5cf0440b5d4b0f02c21fa145a99f0687888c1bc6f90 | 871a248ee101b6df543fd5cf0440b5d4b0f02c21fa145a99f0687888c1bc6f90 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/scripts/guest/guest_service.gd | 56880410e9a00816f9a95d30821982955532de8dd976980934e12016a9f2b21e | 56880410e9a00816f9a95d30821982955532de8dd976980934e12016a9f2b21e |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/tests/s5/test_runtime_defense_autonomy.gd | 28ca81ddde4da49442b427ed4c55ddcf213ecb389712db585b64cd416636c403 | 28ca81ddde4da49442b427ed4c55ddcf213ecb389712db585b64cd416636c403 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/run_all_tests.py.reference | 320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4 | 320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q37-remaining-source-map/source/tests/s5/test_runtime_defense_cycle.gd | a909e2af73aae43590cdd91d07ed2548f4fd2f675d26fa63aa74f6a5cda34357 | a909e2af73aae43590cdd91d07ed2548f4fd2f675d26fa63aa74f6a5cda34357 |
|
||||
| /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/owner-handoff/p04-after-p26-closure-r01/q35-uid-diagnostic/run_p13_reference_tests.py.reference | 9adc8aa2a7662df8dd70386ddb0bff34574e44d7411de3b6128ddd15eb24675c | 9adc8aa2a7662df8dd70386ddb0bff34574e44d7411de3b6128ddd15eb24675c |
|
||||
|
||||
## Source batch and helper choice
|
||||
|
||||
REPAIR38's helper restriction and REPAIR39's missing-context blocker text are
|
||||
superseded for this attempt: the exact absolute context was readable and every
|
||||
hash matched. The old status files and their stops are retained unchanged.
|
||||
|
||||
A: one CASE_TABLE dispatches all six S5 cases with reserved-ID counts and ordered
|
||||
labels. _queue generalizes only its count predicate. _reader loads each boundary,
|
||||
dispatches its stop assertion, then replays table labels. A/B keep recovery,
|
||||
duplicate_guard and resource replay. C–F share private preparation/advancement
|
||||
helpers using public commands, including the operations-enabled paid-midnight
|
||||
path and the automatic-breach source fixture. No forced guest transition is used.
|
||||
New-case receipt buffers are restored after formal load; _fresh/_cmd/_capture,
|
||||
write/read, phase observation and resource replay implementations stay unchanged.
|
||||
|
||||
B: wrapper cases/labels/slots derive from the table. New order adapter reuses
|
||||
Raw, typed parsing, staff_check, duplicate_check and series.variant by file spec;
|
||||
its output records dependency SHA values. The typed mutation control program
|
||||
uses explicit absent BUILD scratch and requires actual Root raw for positives.
|
||||
The existing wrapper/UID controls do not read CASES and were left unchanged.
|
||||
|
||||
C: five wrappers select fresh Q through CLI arguments and shared S5 helpers.
|
||||
UID policies preserve the original execute_phase code object. Historical mode
|
||||
is read-only. FreshSeries verifies actual Root receipt pins, complete source,
|
||||
UID/engine/PID/cleanup/formal material and recomputes existing semantic adapters.
|
||||
Historical RUNS/NATIVE_PINS remain unchanged. Fresh collection is exclusive.
|
||||
|
||||
D: full_suite_verifier imports actual Q run_all_tests.py, derives the roster and
|
||||
parse paths, rejoins raw markers/PIDs/logs/cleanup/source/settings/policy/engine
|
||||
and UID seals, and binds required-kitchen separately. No totals imply original
|
||||
acceptance. Its condition entries remain boundary-pending; checker uses fresh
|
||||
boundary derivations. Normal C provenance is not an input to this verifier.
|
||||
|
||||
E: checker/index consume all FRESH_RUNS, enforce S5 approved-order gates and full
|
||||
suite verification, and retain historical collection separately without union.
|
||||
The index uses the fresh tested Q and fresh runner material descriptors.
|
||||
The series fixture retains its existing negatives and adds the fresh roster.
|
||||
|
||||
F: this status, REPAIR40_STATIC_CHECKS.json, S5_ROOT_RUN.md and the narrowly
|
||||
superseded PENDING.md describe the actual batch and Root's unchanged order.
|
||||
|
||||
## Verification and remaining evidence
|
||||
|
||||
Only static Python AST/py_compile and existing GDScript probe_guard regex checks
|
||||
are permitted here. See REPAIR40_STATIC_CHECKS.json for checks actually executed.
|
||||
No pure controls, engine, Git, Runner, native, integration or other agent was run.
|
||||
The first shell here-document attempt was rejected before execution because the
|
||||
shell could not create its temporary file; subsequent reads used python -c.
|
||||
No /tmp file was created or used.
|
||||
|
||||
Native behavior, mutation controls, full suite, index verification and independent
|
||||
review remain unexecuted. No required condition receives credit from this source
|
||||
submission. In particular, absent fresh shift_completion/same_minute_replay/
|
||||
paused_midnight evidence remains a failing gate rather than historical reuse.
|
||||
S5 patience_release and paused_midnight remain pending unless actually observed.
|
||||
A failed alignment, restore or typed assertion must remain a native failure.
|
||||
|
||||
Frozen: M c0ea009; formal 16/88; original 30/88; P04 credit 0; counters 40/unlimited;
|
||||
seven domains; six D05 decisions and A01; REQUIRED membership/thresholds; product,
|
||||
Clock, API, values and tests; allowed_paths; permissions, billing and policy.
|
||||
r35/r36 are FAILED; Q37 is only local diagnostic evidence. No old proof relabelled.
|
||||
@@ -35,36 +35,29 @@ def payload(build, gate=None):
|
||||
native = build / 'audit-support/native-first-current'
|
||||
c = gate.verify_native(native)
|
||||
raw = gate.combine_native_series(build, c)
|
||||
tested = c['production_commit']
|
||||
series_spec = importlib.util.spec_from_file_location('p04_index_series', Path(__file__).with_name('p04_native_series.py'))
|
||||
series_module = importlib.util.module_from_spec(series_spec)
|
||||
series_spec.loader.exec_module(series_module)
|
||||
fresh_bindings = series_module.fresh_bindings(build)
|
||||
tested = fresh_bindings['Q_tree']
|
||||
source = gate.selected_manifest(gate.tree_entries(tested))
|
||||
source_map = {p: v['sha256'] for p, v in source.items()}
|
||||
# Resolve content from supplied roots only; never open original provenance
|
||||
# paths, never omit required source/config/input/environment material.
|
||||
supplied = {}
|
||||
roots = [build / 'audit-support' / name for name in
|
||||
('native-first-current', 'p04-whole-closure-r01', 'p04-current-native-series-r01',
|
||||
'p04-r17-full-inputs-r01')]
|
||||
for root in roots:
|
||||
if not root.exists():
|
||||
continue
|
||||
for path in sorted(root.rglob('*')):
|
||||
if path.is_file():
|
||||
gate.safe(root, path.relative_to(root).as_posix())
|
||||
pin = descriptor(path)
|
||||
supplied.setdefault(pin['sha256'], pin)
|
||||
runners = []
|
||||
for run in gate.NATIVE_RUNS:
|
||||
path = native / run / 'runner-input.json'
|
||||
for name in series_module.FRESH_RUNS:
|
||||
run_binding = fresh_bindings['series'][name]
|
||||
path = gate.safe(build, run_binding['run'] + '/runner-input.json')
|
||||
inputs = gate.load(path)
|
||||
row = descriptor(path)
|
||||
row['materials'] = {}
|
||||
for pin in inputs.get('fixed_input_pins', []) + [inputs['QA']]:
|
||||
gate.require(pin['sha256'] in supplied, 'missing supplied runner material: ' + pin['path'])
|
||||
actual = supplied[pin['sha256']]
|
||||
gate.require(actual['bytes'] == pin['bytes'], 'runner material length')
|
||||
row['materials'][pin['path']] = actual
|
||||
gate.require(inputs['wrapper_sha256'] in supplied, 'missing supplied native wrapper')
|
||||
row['wrapper'] = supplied[inputs['wrapper_sha256']]
|
||||
material = descriptor(Path(pin['path']))
|
||||
gate.require(material['bytes'] == pin['bytes'] and material['sha256'] == pin['sha256'],
|
||||
'fresh material changed')
|
||||
gate.supplied_file(build, material)
|
||||
row['materials'][pin['path']] = material
|
||||
wrapper = next(p for p in inputs['fixed_input_pins']
|
||||
if p['sha256'] == inputs['wrapper_sha256'])
|
||||
row['wrapper'] = descriptor(Path(wrapper['path']))
|
||||
runners.append(row)
|
||||
# C references retain every lifecycle, raw phase, source, environment and
|
||||
# formal member mapping; Stage R retains its complete original->relocated map.
|
||||
@@ -74,8 +67,8 @@ def payload(build, gate=None):
|
||||
for row in gate.load(native / 'OWNERSHIP_RAW_PROVENANCE.json')['copied']:
|
||||
references['C/' + row['target']] = descriptor(gate.safe(native, row['target']))
|
||||
series = {}
|
||||
collection = build / 'audit-support/p04-raw-collect-r22'
|
||||
for name in ('s1', 's2a', 's2b', 's3', 's4'):
|
||||
collection = build / raw['fresh_collection']
|
||||
for name in series_module.FRESH_RUNS:
|
||||
series[name] = gate.load(collection / (name + '.json'))
|
||||
relocation = gate.load(build / 'audit-support/p04-r17-full-inputs-r01/MANIFEST.json')
|
||||
authorities = {}
|
||||
@@ -119,7 +112,8 @@ def payload(build, gate=None):
|
||||
gate.boundary_conditions(r['path'], r['function'])} for r in delta},
|
||||
'domains': domains, 'authority': authorities, 'conditions': conditions,
|
||||
'reachability': reachability, 'raw_conditions': raw, 'raw_references': references,
|
||||
'series': series, 'source_config_input_environment_and_formal': relocation,
|
||||
'series': series, 'fresh_run_bindings': fresh_bindings,
|
||||
'historical_source_config_input_environment_and_formal': relocation,
|
||||
'native_bundle': descriptor(native / 'OWNERSHIP_RAW_PROVENANCE.json'),
|
||||
'original_audit': {'sha256': gate.sha(gate.ROOT / gate.DOC_SCOPE / 'order-audit.json'),
|
||||
'content': gate.load(gate.ROOT / gate.DOC_SCOPE / 'order-audit.json')},
|
||||
|
||||
@@ -19,6 +19,9 @@ import p04_native_series as s
|
||||
|
||||
def run(build):
|
||||
results = []
|
||||
assert set(s.FRESH_RUNS) == {'s1', 's2a', 's2b', 's3', 's4', 's5'}
|
||||
assert all(callable(getattr(s, 'verify_fresh_' + name)) for name in s.FRESH_RUNS)
|
||||
results.append({'series': 'fresh', 'class': 'fresh_roster_and_entrypoints', 'result': 'pass'})
|
||||
|
||||
def reject(series, name, action):
|
||||
try:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"""Deterministic reference-only Stage R collector; never writes the final index."""
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import sys
|
||||
@@ -14,28 +15,35 @@ def encoded(value):
|
||||
return (json.dumps(value, sort_keys=True, indent=2, ensure_ascii=False) + '\n').encode()
|
||||
|
||||
|
||||
def collect(build):
|
||||
def collect(build, fresh=None):
|
||||
build = Path(build).absolute()
|
||||
destination = build / 'audit-support/p04-raw-collect-r22'
|
||||
if fresh is not None:
|
||||
series.require(re.fullmatch(r'q[0-9]+', fresh) is not None, 'fresh collection must be q<N>')
|
||||
destination = build / ('audit-support/p04-raw-collect-' + fresh if fresh else 'audit-support/p04-raw-collect-r22')
|
||||
series.require(not destination.exists() and not destination.is_symlink(), 'collection destination already exists')
|
||||
for p in (destination.parent, *destination.parents):
|
||||
series.require(not p.is_symlink(), 'collection parent symlink')
|
||||
payloads = {}
|
||||
bindings = {}
|
||||
for name in series.RUNS:
|
||||
result = getattr(series, 'verify_' + name)(build)
|
||||
for name in (series.FRESH_RUNS if fresh else series.RUNS):
|
||||
result = getattr(series, ('verify_fresh_' if fresh else 'verify_') + name)(build)
|
||||
result['verifier_sha256'] = series.digest(Path(series.__file__).read_bytes())
|
||||
data = encoded(result)
|
||||
filename = name + '.json'
|
||||
payloads[filename] = data
|
||||
bindings[name] = {'path': filename, 'bytes': len(data), 'sha256': series.digest(data),
|
||||
'relocation_manifest_sha256': series.MANIFEST_SHA256}
|
||||
**({} if fresh else {'relocation_manifest_sha256': series.MANIFEST_SHA256})}
|
||||
manifest = {'protocol': 'p04-native-series-collection-v1', 'formal_acceptance': False,
|
||||
'stage_A': 'candidate binding stage A pending', 'series': bindings,
|
||||
'relocation_manifest_sha256': series.MANIFEST_SHA256,
|
||||
'relocation_manifest': 'audit-support/p04-r17-full-inputs-r01/MANIFEST.json',
|
||||
'collector_sha256': series.digest(Path(__file__).read_bytes()),
|
||||
'large_payloads_copied': 0}
|
||||
if fresh:
|
||||
manifest = {'protocol': 'p04-fresh-native-series-collection-v1', 'series': bindings,
|
||||
'collection': fresh, 'formal_acceptance': False,
|
||||
'collector_sha256': series.digest(Path(__file__).read_bytes()),
|
||||
'historical_merged': False, 'large_payloads_copied': 0}
|
||||
payloads['MANIFEST.json'] = encoded(manifest)
|
||||
estimate = sum(len(v) for v in payloads.values())
|
||||
# The estimate precedes all writes. Reserve extra directory/allocation space.
|
||||
@@ -54,8 +62,10 @@ def collect(build):
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--build', type=Path, required=True)
|
||||
parser.add_argument('--fresh', metavar='qN')
|
||||
try:
|
||||
collect(parser.parse_args().build)
|
||||
args = parser.parse_args()
|
||||
collect(args.build, args.fresh)
|
||||
except (ValueError, OSError, KeyError, TypeError) as exc:
|
||||
print(json.dumps({'collected': False, 'error': str(exc)}))
|
||||
sys.exit(1)
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read-only full Q verification. No normal-C join and no acceptance from counts."""
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def require(value, message):
|
||||
if not value:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def module(name, path):
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
result = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(result)
|
||||
return result
|
||||
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def content(refs):
|
||||
return {name: {key: row[key] for key in ('bytes', 'sha256')} for name, row in refs.items()}
|
||||
|
||||
|
||||
def roster_gate(expected, actual):
|
||||
require(len(expected) == len(set(expected)) and actual == expected, 'missing/extra/reordered suite')
|
||||
|
||||
|
||||
def pid_gate(row, start, end, owner):
|
||||
pid = row['actual_pid']
|
||||
require(type(pid) is int and pid > 0 and start['actual_pid'] == end['actual_pid'] == pid
|
||||
and row['native_process']['pid'] == pid, 'PID mismatch')
|
||||
require(start['owner_pid'] == end['owner_pid'] == owner
|
||||
and start['current_process_identity']['pid'] == pid
|
||||
and start['current_process_identity']['ppid'] == owner, 'PID owner')
|
||||
require(start['command'] == end['command'] == row['command'] == row['native_process']['argv'], 'PID argv')
|
||||
require(start['monotonic_ns'] < end['monotonic_ns'] and end['engine_ended'] is True
|
||||
and end['exit_code'] == end['actual_process_exit_code'] == 0
|
||||
and end['timed_out'] is False and end['lifecycle_error'] is None, 'PID end')
|
||||
|
||||
|
||||
def cleanup_gate(rows, count):
|
||||
require(len(rows) == count, 'cleanup roster')
|
||||
for row in rows:
|
||||
cleanup = row['cleanup']
|
||||
require(row['engine_ended'] is True and row['outer_cleanup_errors'] == []
|
||||
and cleanup['engine_ended'] is True and cleanup['errors'] == []
|
||||
and cleanup['actual_process_exit_code'] == 0, 'dirty cleanup')
|
||||
require(cleanup['attempts'], 'cleanup attempts')
|
||||
for attempt in cleanup['attempts']:
|
||||
require(attempt['errors'] == [] and attempt['kill_attempted'] is False
|
||||
and attempt['wait_completed'] is True and attempt['wait_returned_code'] == 0,
|
||||
'dirty cleanup wait')
|
||||
|
||||
|
||||
def settings_gate(before, after, selected):
|
||||
for name in ('project.godot', 'export_presets.cfg'):
|
||||
require(before[name] == after[name] == selected[name], 'settings drift: ' + name)
|
||||
|
||||
|
||||
def controls():
|
||||
"""Pure contract negatives, independent of native success or test totals."""
|
||||
import copy
|
||||
results = []
|
||||
def reject(name, callback):
|
||||
try:
|
||||
callback()
|
||||
except ValueError:
|
||||
results.append(name)
|
||||
return
|
||||
raise ValueError('negative accepted: ' + name)
|
||||
roster_gate(['a', 'b'], ['a', 'b'])
|
||||
reject('missing-suite', lambda: roster_gate(['a', 'b'], ['a']))
|
||||
reject('extra-suite', lambda: roster_gate(['a', 'b'], ['a', 'b', 'c']))
|
||||
row = {'actual_pid': 1, 'native_process': {'pid': 2}}
|
||||
reject('PID-mismatch', lambda: pid_gate(row, {'actual_pid': 1}, {'actual_pid': 1}, 9))
|
||||
dirty = [{'engine_ended': False, 'outer_cleanup_errors': [], 'cleanup': {}}]
|
||||
reject('dirty-cleanup', lambda: cleanup_gate(dirty, 1))
|
||||
source = {name: {'bytes': 1, 'sha256': 'a'} for name in ('project.godot', 'export_presets.cfg')}
|
||||
settings_gate(source, source, source)
|
||||
changed = copy.deepcopy(source)
|
||||
changed['project.godot']['sha256'] = 'b'
|
||||
reject('settings-drift', lambda: settings_gate(source, changed, source))
|
||||
return {'controls': results, 'native_run': False, 'formal_acceptance': False}
|
||||
|
||||
|
||||
def verify(root, run, required):
|
||||
root, run = Path(root).resolve(strict=True), Path(run).resolve(strict=True)
|
||||
references = {}
|
||||
|
||||
def read(relative):
|
||||
require(not Path(relative).is_absolute() and '..' not in Path(relative).parts, 'full raw traversal')
|
||||
path = run / relative
|
||||
require(path.is_file() and all(not p.is_symlink() for p in (path, *path.parents)), 'full raw ordinary file')
|
||||
data = path.read_bytes()
|
||||
references[relative] = {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
|
||||
return data
|
||||
|
||||
def load(relative):
|
||||
return json.loads(read(relative))
|
||||
|
||||
full = module('p04_actual_q_full', root / 'tools/run_all_tests.py')
|
||||
wrapper = module('p04_full_uid', Path(__file__).parent / 's5/run_s5_native.py')
|
||||
source = full.source_refs(root)
|
||||
before = load('source-start.json')
|
||||
after = full.source_refs(root)
|
||||
require(before == source == after, 'full source before/after/current')
|
||||
roster = full.roster(root)
|
||||
parse_paths = ['res://' + n for n in sorted(source) if n.endswith('.gd')]
|
||||
inputs, ended = load('runner-input.json'), load('runner-ended.json')
|
||||
roster_gate(roster, inputs['roster'])
|
||||
require(inputs['selected_source_map'] == {n: p['sha256'] for n, p in source.items()}, 'full exact Q source map')
|
||||
settings_gate(content(before), content(after), content(source))
|
||||
require(inputs['runner_sha256'] == sha(root / 'tools/run_all_tests.py')
|
||||
and inputs['marker_module_sha256'] == sha(root / 'tools/strict_test_markers.py'), 'actual runner/marker module')
|
||||
engine = wrapper.engine_pin(Path(inputs['engine']))
|
||||
require(inputs['engine_sha256'] == engine['sha256'], 'full engine pin')
|
||||
require(ended['passed'] is True and ended['error'] is None
|
||||
and ended['cleanup_errors'] == ended['guard_errors'] == [] and ended['engine_ended'] is True,
|
||||
'full run failed')
|
||||
require(inputs['run_id'] == ended['run_id'] and inputs['owner_runner_pid'] == ended['owner_runner_pid'], 'full run identity')
|
||||
require(inputs['default_player_before'] == ended['default_player_after'], 'protected profile changed')
|
||||
markers = module('p04_full_markers', root / 'tools/strict_test_markers.py')
|
||||
contract_path = root / wrapper.C_REL
|
||||
require(sha(contract_path) == inputs['marker_contract_sha256'], 'full contracts SHA')
|
||||
contracts = markers.load_contracts(contract_path)
|
||||
policy_path = full.SUPPORT / 'suite-policy.json'
|
||||
policy = full.read(policy_path)
|
||||
require(source['tools/regression/suite-policy.json']['sha256'] == sha(policy_path), 'source-bound full policy')
|
||||
full.policy_coverage(roster, source, policy)
|
||||
diagnostics = module('p04_full_diagnostics', full.SUPPORT / 'diagnostic_gate.py')
|
||||
native = module('p04_full_native', full.SUPPORT / 'owned_diagnostic_process.py')
|
||||
owners = module('p04_full_owners', full.SUPPORT / 'ordinary_proof_gate.py')
|
||||
audio = module('p04_full_audio', full.SUPPORT / 'audio_evidence_gate.py')
|
||||
sequence = [('import', None), ('parse', None)] + [(str(i).zfill(3), n) for i, n in enumerate(roster)]
|
||||
require([(p['phase'], p['test']) for p in ended['phases']] == sequence, 'entire derived phase roster')
|
||||
all_tests = load('all-tests.json')
|
||||
require(references['all-tests.json']['sha256'] == ended['all_tests_sha256'], 'full all-tests SHA')
|
||||
roster_gate(roster, [p['test'] for p in all_tests])
|
||||
require(load('parse-paths.json') == parse_paths, 'complete parse roster')
|
||||
uid_plan, uid_snapshot, binding = wrapper.load_uid_helper(root, full, source)
|
||||
plan = uid_plan(source)
|
||||
accepted = load('accepted-uids.json')
|
||||
require(load('uid-plan.json') == plan, 'derived full UID plan')
|
||||
generated, pids, suite_rows = {}, [], {}
|
||||
for index, (label, test) in enumerate(sequence):
|
||||
row = load(label + '-receipt.json')
|
||||
enriched = dict(row)
|
||||
if test:
|
||||
enriched.update(sequence=index - 2, godot=inputs['engine'])
|
||||
require(enriched == all_tests[index - 2], 'full test raw row join')
|
||||
require(enriched == ended['phases'][index] and row['passed'] is True and row['failed'] is False
|
||||
and row['validation_error'] is None and not row.get('guard_error')
|
||||
and row['default_player_entire_profile_unchanged'] is True, 'full phase guards')
|
||||
process = load(label + '/process.json')
|
||||
require(process == row['native_process'], 'native process receipt binding')
|
||||
pid_gate(row, load(label + '/started.json'), load(label + '/ended.json'), inputs['owner_runner_pid'])
|
||||
pids.append(row['actual_pid'])
|
||||
stdout, stderr, logger = [read(label + '/' + name).decode() for name in ('stdout.log', 'stderr.log', 'engine-native.log')]
|
||||
require(references[label + '/stdout.log']['sha256'] == process['stdout_sha256']
|
||||
and references[label + '/stderr.log']['sha256'] == process['stderr_sha256'], 'full streams SHA')
|
||||
require(all(references[label + '/engine-native.log'][k] == row['raw_native_log'][k]
|
||||
for k in ('bytes', 'sha256')), 'native logger pin')
|
||||
raw = stdout + stderr
|
||||
require(read(row['log']).decode() == raw and references[row['log']]['sha256'] == row['log_sha256'], 'full raw log join')
|
||||
review = diagnostics.review_streams(native, {'stdout': stdout, 'stderr': stderr, 'native_file': logger},
|
||||
test, root / test if test else None)
|
||||
require(review == row['finite_original_diagnostic_review']
|
||||
and diagnostics.diagnostic_result_gate(process, review)
|
||||
and full.process_gate(process, review['allowed_e31_error_lines']), 'full strict diagnostics')
|
||||
require(row['outer_actual_capture']['passed'] is True
|
||||
and row['outer_actual_capture']['foreign_process_or_group_signals'] == 0, 'owned capture')
|
||||
if test:
|
||||
parsed = markers.parse_raw(test, raw, contracts, source[test]['sha256'])
|
||||
require(parsed == row['completion'] and parsed['passed'] is True and parsed['failures'] == 0,
|
||||
'literal source-bound marker')
|
||||
require(row['policy'] == full.phase_policy(test, root / test, policy['suite_policies']), 'phase policy drift')
|
||||
p = row['policy']
|
||||
route = policy['outside_routes'].get(test)
|
||||
if route:
|
||||
require(full.routed_report(run / (label + '-evidence'), route, test, row['actual_pid'], raw,
|
||||
run / 'stage', source[test]['sha256']) == row['outside_report'],
|
||||
'full routed proof')
|
||||
proof = run / (label + '-teardown')
|
||||
if p['ordinary_cleanup_prepared']:
|
||||
require(owners.ordinary_gate(proof, row['actual_pid'], run, p['ordinary_control_labels']) ==
|
||||
row['ordinary_owner_pairs'], 'full ordinary ownership proof')
|
||||
if p['old_bounded_teardown'] or test == 'tests/ui/test_ui_audio_feedback.gd':
|
||||
require(audio.teardown_gate(proof, row['actual_pid'], run) == row['old_bounded_proof'],
|
||||
'full bounded teardown proof')
|
||||
if test == 'tests/ui/test_ui_audio_feedback.gd':
|
||||
audio_dir = run / (label + '-audio-proof')
|
||||
require(audio.command_gate(audio_dir / 'actual-command-result-buffer-proof.json', audio_dir,
|
||||
row['actual_pid']) == row['actual_command_evidence'], 'full audio commands')
|
||||
require(audio.ogg_gate(audio_dir / 'actual-ogg-decode-player-state.json', row['actual_pid'],
|
||||
inputs['selected_source_map']) == row['actual_ogg_evidence'], 'full actual OGG')
|
||||
suite_rows[test] = {'phase': label, 'pid': row['actual_pid'], 'source_sha256': source[test]['sha256'],
|
||||
'marker': parsed, 'log_sha256': row['log_sha256']}
|
||||
if label == 'parse':
|
||||
require(row['actual_parse_checks'] == len(parse_paths), 'derived parse count')
|
||||
uid = load(label + '-uids.json')
|
||||
require(uid.get('error') is None and uid['before'] == ({} if label == 'import' else accepted)
|
||||
and uid['after'] == accepted, 'full phase UID seals')
|
||||
for kind in ('startup', 'runtime'):
|
||||
snapshot = row.get('whole_' + kind + '_profile_after')
|
||||
if snapshot:
|
||||
require(full.inventory(run / 'profiles' / label / kind) == snapshot['files'],
|
||||
'complete retained private profile')
|
||||
for name, descriptor in row['generated_reports'].items():
|
||||
require(name not in source and name not in generated, 'unique generated report')
|
||||
pin = {k: descriptor[k] for k in ('bytes', 'sha256')}
|
||||
read('stage/' + name)
|
||||
require(references['stage/' + name] == pin, 'generated report raw')
|
||||
generated[name] = pin
|
||||
require(len(set(pids)) == len(sequence) and pids == ended['actual_captured_PIDs'], 'all full unique PIDs')
|
||||
cleanup_gate(ended['final_owned_cleanup'], len(sequence))
|
||||
require(uid_snapshot(run / 'stage', dict(content(source), **generated), plan) == accepted, 'retained exact stage/UID/settings')
|
||||
totals = full.totals(all_tests, roster)
|
||||
require(all(ended[k] == v for k, v in totals.items()) and not totals['remaining_unexecuted_tests']
|
||||
and not totals['missing_marker_paths'], 'recomputed full totals')
|
||||
kitchen = [n for n in roster if Path(n).name == 'test_required_kitchen.gd']
|
||||
require(len(kitchen) == 1, 'separate required-kitchen roster binding')
|
||||
# A suite pass supplies exact-version applicability, not domain boundary proof.
|
||||
conditions = {name: {'status': 'pending_boundary_raw', 'full_suite_applicable': True}
|
||||
for name in sorted(set(required) | {'EV'})}
|
||||
return {'verified': True, 'suites': len(roster), 'parse_files': len(parse_paths),
|
||||
'source_files': len(source), 'totals': totals, 'owned_pids': pids,
|
||||
'required_kitchen': dict(suite_rows[kitchen[0]], test=kitchen[0]),
|
||||
'conditions': conditions, 'references': references, 'source_sha256': inputs['selected_source_map'],
|
||||
'policy_sha256': sha(policy_path), 'engine_sha256': engine['sha256'],
|
||||
'normal_c_join': 'Root post-final only', 'formal_acceptance': False}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--controls', action='store_true')
|
||||
parser.add_argument('--root', type=Path)
|
||||
parser.add_argument('--run', type=Path)
|
||||
args = parser.parse_args()
|
||||
if args.controls:
|
||||
print(json.dumps(controls(), sort_keys=True))
|
||||
else:
|
||||
require(args.root is not None and args.run is not None, 'root and run required')
|
||||
gate = module('full_required_membership', args.root / 'tools/check_p04_order_evidence.py')
|
||||
print(json.dumps(verify(args.root, args.run, gate.REQUIRED), sort_keys=True))
|
||||
@@ -381,6 +381,10 @@ def persistence_pins(s):
|
||||
pin = s.resolver.manifest['product_source'][path]
|
||||
source = s.resolver.read(pin['path'], pin)
|
||||
bodies = function_bodies(source)
|
||||
if getattr(s, 'fresh', False):
|
||||
for function, expected in PERSISTENCE_BODIES.items():
|
||||
require(digest(bodies[function]) == expected, 'fresh persistence function: ' + function)
|
||||
return
|
||||
report = loads(s.read_build('audit-support/p04-repair19-close-r01/ROOT_ACTUAL_PERSISTENCE_CALL_CHAIN.json'))
|
||||
require(digest(source) == report['full_file_sha256'] ==
|
||||
'871a248ee101b6df543fd5cf0440b5d4b0f02c21fa145a99f0687888c1bc6f90', 'persistence whole-source pin')
|
||||
@@ -1221,6 +1225,195 @@ def verify_s3(build):
|
||||
return s.result(conditions, facts)
|
||||
|
||||
|
||||
FRESH_RUNS = ('s1', 's2a', 's2b', 's3', 's4', 's5')
|
||||
FRESH_BINDINGS = 'audit-support/p04-fresh-runs.json'
|
||||
|
||||
|
||||
def fresh_bindings(build):
|
||||
value = loads(ordinary(Path(build) / FRESH_BINDINGS).read_bytes())
|
||||
require(value['protocol'] == 'p04-fresh-runs-v1' and set(value['series']) == set(FRESH_RUNS),
|
||||
'Root fresh run binding roster')
|
||||
return value
|
||||
|
||||
|
||||
class FreshResolver:
|
||||
def __init__(self, source):
|
||||
self.manifest = {'product_source': source}
|
||||
self.allowed = {r['path']: r for r in source.values()}
|
||||
self.used = {}
|
||||
|
||||
def read(self, path, pin):
|
||||
require(path in self.allowed and pin == self.allowed[path], 'fresh source membership')
|
||||
data = checked(ordinary(path).read_bytes(), pin, path)
|
||||
self.used[path] = pin
|
||||
return data
|
||||
|
||||
|
||||
class FreshSeries(Series):
|
||||
"""Actual Root input/receipt pins; no historical native pin or relocation fallback."""
|
||||
fresh = True
|
||||
|
||||
def __init__(self, build, name):
|
||||
self.name, self.build = name, Path(build).resolve(strict=True)
|
||||
bindings = fresh_bindings(self.build)
|
||||
binding = bindings['series'][name]
|
||||
self.run = binding['run']
|
||||
require(not Path(self.run).is_absolute() and '..' not in Path(self.run).parts, 'fresh run relative path')
|
||||
self.base = self.build / self.run
|
||||
self.references, self.nodes, self.pids, self.phase_pairs = {}, {}, [], 0
|
||||
self.inputs = loads(self.read('runner-input.json', binding['runner_input']))
|
||||
self.execution = loads(self.read('runner-ended.json', binding['runner_ended']))
|
||||
require(self.inputs['mode'] == 'fresh-q' and not self.inputs['historical_r17'], 'fresh input only')
|
||||
provenance = self.inputs['provenance']
|
||||
require(all(provenance[k] == bindings[k] for k in ('M', 'S', 'Q_tree')), 'same fresh Q across all runs')
|
||||
self.source = loads(self.read('source_before.json'))
|
||||
require(self.source == self.inputs['source_before'] == loads(self.read('source_after.json')), 'whole fresh source before/after')
|
||||
self.resolver = FreshResolver(self.source)
|
||||
for pin in self.source.values():
|
||||
self.resolver.read(pin['path'], pin)
|
||||
qa = self.inputs['QA']
|
||||
checked(ordinary(qa['path']).read_bytes(), qa, 'fresh QA')
|
||||
require(self.inputs['QA_overrides'] == ['tests/s3/test_runtime_staff_assignment.gd'], 'single fresh QA override')
|
||||
selected = {k: v['sha256'] for k, v in self.source.items()}
|
||||
selected[self.inputs['QA_overrides'][0]] = qa['sha256']
|
||||
require(self.inputs['selected_source_map'] == selected, 'fresh selected manifest')
|
||||
for pin in self.inputs['fixed_input_pins']:
|
||||
checked(ordinary(pin['path']).read_bytes(), pin, 'fresh fixed input')
|
||||
execution = self.execution
|
||||
require(execution['passed'] is True and execution['error'] is None
|
||||
and execution['guard_errors'] == execution['cleanup_errors'] == [], 'fresh native guards')
|
||||
require([p['phase'] for p in execution['phases']] == ['import', 'parse', 'writer', 'reader'], 'fresh four phases')
|
||||
for phase_row in execution['phases']:
|
||||
require(phase_row['passed'] is True and phase_row['engine_ended'] is True, 'fresh phase passed/ended')
|
||||
self.ownership(phase_row)
|
||||
require(len(set(self.pids)) == 4 and self.pids == execution['actual_captured_PIDs'], 'fresh PID roster')
|
||||
pid_set = loads(self.read('PID-set.json'))
|
||||
require(pid_set['engine_PIDs'] == self.pids and
|
||||
pid_set['owner_runner_pid'] == self.inputs['owner_runner_pid'], 'fresh PID set binding')
|
||||
require(len(execution['cleanup']) == 4 and all(r['engine_ended'] is True for r in execution['cleanup']), 'fresh strict cleanup')
|
||||
for row in execution['cleanup']:
|
||||
cleanup = row['cleanup']
|
||||
require(row['outer_cleanup_errors'] == [] and cleanup['errors'] == []
|
||||
and cleanup['actual_process_exit_code'] == 0 and cleanup['attempts'], 'fresh cleanup errors')
|
||||
require(all(a['errors'] == [] and a['kill_attempted'] is False
|
||||
and a['wait_completed'] is True and a['wait_returned_code'] == 0
|
||||
for a in cleanup['attempts']), 'fresh cleanup abnormal wait')
|
||||
self.inventory = loads(self.read('raw-inventory.json', binding['raw_inventory']))
|
||||
for name, pin in self.inventory.items():
|
||||
self.read('raw/' + name, pin)
|
||||
if self.name in ('s1', 's2a', 's2b', 's3'):
|
||||
for path in self.inventory:
|
||||
if path.startswith('writer-') and '-phase-' in path:
|
||||
other = 'reader-' + path[len('writer-'):]
|
||||
require(other in self.inventory and self.read('raw/' + path) == self.read('raw/' + other),
|
||||
'fresh altered phase pair')
|
||||
if path.endswith('.var'): self.phase_pairs += 1
|
||||
if self.name == 's3':
|
||||
require(self.phase_pairs == 176, 'unchanged S3 complete phase roster')
|
||||
wrapper_path = Path(__file__).parent / 's5/run_s5_native.py'
|
||||
import importlib.util
|
||||
spec = importlib.util.spec_from_file_location('fresh_series_wrapper', wrapper_path)
|
||||
wrapper = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(wrapper)
|
||||
root = Path(self.inputs['project_root'])
|
||||
runner = wrapper.module('fresh_series_runner', root / 'tools/run_all_tests.py')
|
||||
refs = dict(self.source)
|
||||
refs[self.inputs['QA_overrides'][0]] = qa
|
||||
uid_plan, uid_snapshot, uid_binding = wrapper.load_uid_helper(root, runner, self.source)
|
||||
plan = uid_plan(refs)
|
||||
require(plan == self.inputs['uid_plan'], 'independently derived fresh UID plan')
|
||||
source = {n: {k: p[k] for k in ('bytes', 'sha256')} for n, p in refs.items()}
|
||||
accepted = uid_snapshot(self.base / 'stage', source, plan)
|
||||
require(accepted == loads(self.read('accepted-uids.json')), 'retained fresh UID seal')
|
||||
for role in ('import', 'parse', 'writer', 'reader'):
|
||||
require(loads(self.read(role + '-uids.json')) ==
|
||||
{'before': {} if role == 'import' else accepted, 'after': accepted}, 'phase UID seals')
|
||||
require(wrapper.engine_pin(Path(self.inputs['engine']['path'])) == self.inputs['engine'], 'fresh engine identity')
|
||||
if self.name == 's5':
|
||||
verify_s4_engine(self.inputs['engine'], execution['engine_identity'])
|
||||
else:
|
||||
observations = loads(self.read('fresh-engine-checks.json'))
|
||||
require([r['label'] for r in observations] ==
|
||||
['fixed', 'before-import', 'before-parse', 'before-writer', 'before-reader', 'fixed'],
|
||||
'fresh engine observation roster')
|
||||
require(all(r['descriptor'] == self.inputs['engine'] for r in observations), 'fresh engine drift')
|
||||
self.formal_pin = binding['formal_relocation']
|
||||
self.formal()
|
||||
|
||||
def formal(self):
|
||||
before = self.execution['formal_before']
|
||||
require(before and before == self.execution['formal_after'], 'fresh formal source unchanged')
|
||||
relocated = loads(self.read('formal-relocation.json', self.formal_pin))
|
||||
require(set(relocated) == {'writer', 'reader'}, 'fresh whole formal mirror')
|
||||
writer, reader = [loads(self.read('raw/' + role + '.json')) for role in ('writer', 'reader')]
|
||||
require(writer['profile'] != reader['profile'] and writer['pid'] != reader['pid'], 'fresh independent Reader')
|
||||
inodes = set()
|
||||
for role in ('writer', 'reader'):
|
||||
receipt = loads(self.read('raw/' + role + '.json'))
|
||||
require(set(receipt['slots']) == set(before) == set(relocated[role]), 'fresh formal roster')
|
||||
for slot, original in receipt['slots'].items():
|
||||
row = relocated[role][slot]
|
||||
require(row['provenance'] == original and row['members'] == before[slot], 'fresh restore manifest binding')
|
||||
require(set(row['members']) == {'journal.log', 'manifest.json', 'thumbnail.png', 'world.bin'}, 'all four members')
|
||||
require(row['relative'] == 'formal/' + role + '/' + slot and
|
||||
{p.name for p in (self.base / row['relative']).iterdir()} == set(row['members']),
|
||||
'exact formal directory membership')
|
||||
for member, pin in row['members'].items():
|
||||
self.read(row['relative'] + '/' + member, pin)
|
||||
st = ordinary(self.base / row['relative'] / member).stat()
|
||||
require((st.st_dev, st.st_ino) not in inodes, 'formal independent inodes')
|
||||
inodes.add((st.st_dev, st.st_ino))
|
||||
|
||||
def result(self, conditions, facts=None):
|
||||
return {'series': self.name, 'mode': 'fresh-q', 'verified_conditions': sorted(set(conditions)),
|
||||
'facts': facts or {}, 'provenance': self.inputs['provenance'],
|
||||
'source_files': len(self.source), 'owned_pids': self.pids,
|
||||
'references': self.references, 'formal_acceptance': False}
|
||||
|
||||
|
||||
def verify_fresh_s1(build):
|
||||
s = FreshSeries(build, 's1')
|
||||
return s.result(s1_semantics(s))
|
||||
|
||||
|
||||
def verify_fresh_s2a(build):
|
||||
s = FreshSeries(build, 's2a')
|
||||
return s.result(s2a_semantics(s))
|
||||
|
||||
|
||||
def verify_fresh_s2b(build):
|
||||
s = FreshSeries(build, 's2b')
|
||||
return s.result(s2b_semantics(s))
|
||||
|
||||
|
||||
def verify_fresh_s3(build):
|
||||
s = FreshSeries(build, 's3')
|
||||
conditions, facts = s3_semantics(s)
|
||||
# Event B4 is historical case logic, never the approved automatic-raid gate.
|
||||
return s.result([c for c in conditions if c != 'destruction_stop'], facts)
|
||||
|
||||
|
||||
def verify_fresh_s4(build):
|
||||
s = FreshSeries(build, 's4')
|
||||
S4Series.formal_s4(s)
|
||||
return s.result(['power_stop'], power_stop(s))
|
||||
|
||||
|
||||
def verify_fresh_s5(build):
|
||||
s = FreshSeries(build, 's5')
|
||||
import importlib.util
|
||||
path = Path(__file__).parent / 's5/s5_order_adapter.py'
|
||||
spec = importlib.util.spec_from_file_location('fresh_order_adapter', path)
|
||||
adapter = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(adapter)
|
||||
arguments = (s.base / 'raw', s.inventory['writer.json']['sha256'], s.inventory['reader.json']['sha256'])
|
||||
power = adapter.power.derive(*arguments)
|
||||
order = adapter.derive(*arguments)
|
||||
conditions = ['power_stop', 'dependency_stop', 'recovery_completion', 'destruction_stop', 'exit_release',
|
||||
'midnight_settlement', 'midnight_replay', 'save_restore']
|
||||
return s.result(conditions, {'power': power, 'order': order})
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--build', type=Path, required=True)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"""S1-only native entry. --check-only never loads ownership helpers or starts Godot."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
@@ -52,16 +53,39 @@ def main():
|
||||
parser.add_argument("--cache-run", type=Path, default=CACHE_RUN)
|
||||
parser.add_argument("--godot", type=Path, default=ENGINE)
|
||||
parser.add_argument("--check-only", action="store_true")
|
||||
parser.add_argument("--main")
|
||||
parser.add_argument("--submission")
|
||||
parser.add_argument("--tested-tree")
|
||||
parser.add_argument("--historical-r17", action="store_true")
|
||||
args = parser.parse_args()
|
||||
shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")
|
||||
mode = shared.select_mode(args)
|
||||
fresh = mode == "fresh-q"
|
||||
if fresh and "--project-root" not in sys.argv:
|
||||
raise ValueError("fresh-q requires explicit --project-root")
|
||||
if fresh and "--cache-run" not in sys.argv:
|
||||
args.cache_run = None
|
||||
engine_descriptor = shared.engine_pin(args.godot) if fresh else None
|
||||
provenance = None
|
||||
|
||||
if args.project_root.is_symlink():
|
||||
raise ValueError("project root symlink")
|
||||
root = args.project_root.resolve()
|
||||
out = args.output.resolve()
|
||||
if fresh:
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("fresh plan/output must stay inside BUILD")
|
||||
if out.exists() or out.is_symlink() or (args.check_only and args.plan.exists()):
|
||||
raise ValueError("fresh output and plan required")
|
||||
r = module("s1_standard_runner", root / "tools/run_all_tests.py")
|
||||
# Preserve the reviewed source_refs -> exactly one QA override order.
|
||||
source_before = r.source_refs(root)
|
||||
if fresh:
|
||||
provenance = shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree)
|
||||
refs = dict(source_before)
|
||||
refs[TEST] = pin(QA)
|
||||
expected = {n: dict(bytes=p["bytes"], sha256=p["sha256"]) for n, p in refs.items()}
|
||||
fixed = [pin(p) for p in MATERIALS + [
|
||||
fixed = [pin(p) for p in ([] if fresh else MATERIALS) + [
|
||||
QA, Path(__file__), HERE / "S1_ROOT_RUN.md",
|
||||
root / "tests/transport/test_runtime_transport.gd",
|
||||
root / "tests/staff/test_rescue_elevator.gd",
|
||||
@@ -70,7 +94,7 @@ def main():
|
||||
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
||||
cache_note = None
|
||||
cache_receipts = []
|
||||
for leaf in ["runner-ended.json", "runner-input.json"]:
|
||||
for leaf in (["runner-ended.json", "runner-input.json"] if args.cache_run is not None else []):
|
||||
path = args.cache_run / leaf
|
||||
try:
|
||||
cache_receipts.append(pin(path))
|
||||
@@ -84,6 +108,16 @@ def main():
|
||||
cache_receipts=cache_receipts, cache_access=cache_note,
|
||||
phases=["import", "parse", "writer", "reader"],
|
||||
native_engine_launches=0, whole_goal_accepted=False, unit_accepted=False)
|
||||
if fresh:
|
||||
uid_plan, uid_snapshot, uid_binding = shared.load_uid_helper(root, r, source_before)
|
||||
uid_source = copy.deepcopy(expected)
|
||||
uid_plan_map = uid_plan(refs)
|
||||
plan.update(protocol="p04-s1-fresh-q-v1", mode=mode, provenance=provenance, engine=engine_descriptor,
|
||||
engine_sha256=engine_descriptor["sha256"], uid_helper=uid_binding,
|
||||
uid_plan=uid_plan_map, import_mode="fresh" if args.cache_run is None else "cache",
|
||||
historical_r17=False, fresh_q_evidence=False)
|
||||
fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))
|
||||
# No historical execution is admitted.
|
||||
# Check-only only reads source/materials and writes the plan in task build.
|
||||
# It deliberately does not read default-player data, inspect processes or stat Godot.
|
||||
if args.check_only:
|
||||
@@ -96,14 +130,26 @@ def main():
|
||||
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
||||
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
||||
return 0
|
||||
r.require(fresh, "historical mode is read-only")
|
||||
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
||||
reports, phase_call, uid_state = shared.make_uid_policy(r, uid_snapshot, uid_source, uid_plan_map, out)
|
||||
engine_checks = []
|
||||
def fresh_engine_check(label):
|
||||
value = shared.engine_pin(args.godot, engine_descriptor)
|
||||
engine_checks.append(dict(label=label, descriptor=value))
|
||||
def fixed_guard():
|
||||
fresh_engine_check("fixed")
|
||||
r.require(shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree) == provenance,
|
||||
"fresh Q provenance changed")
|
||||
r.require(pin(root / uid_binding["helper_path"])["sha256"] == uid_binding["helper_sha256"],
|
||||
"UID helper changed")
|
||||
for value in fixed + cache_receipts:
|
||||
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
||||
fixed_guard()
|
||||
# Native admission is Root-only and fails closed on unreadable cache.
|
||||
r.require(cache_note is None, "Root must read exact cache receipts: " + str(cache_note))
|
||||
old = args.cache_run
|
||||
if old is not None:
|
||||
r.require(r.read(old / "runner-ended.json")["passed"], "ended cache run must have passed")
|
||||
old_map = r.read(old / "runner-input.json")["selected_source_map"]
|
||||
current_map = {n: p["sha256"] for n, p in source_before.items()}
|
||||
@@ -152,6 +198,7 @@ def main():
|
||||
data = value["text"].encode()
|
||||
r.require(hashlib.sha256(data).hexdigest() == value["sha256"], "bootstrap pin")
|
||||
(out / "bootstrap" / name).write_bytes(data)
|
||||
if old is not None:
|
||||
cache = old / "stage/.godot"
|
||||
cache_before = r.inventory(cache)
|
||||
r.require(bool(cache_before), "nonempty ended cache")
|
||||
@@ -187,7 +234,10 @@ def main():
|
||||
writer = r.read(out / "raw/writer.json")
|
||||
formal_before = {n: r.inventory(Path(p)) for n, p in writer["slots"].items()}
|
||||
r.require(len(formal_before) == 14, "all fourteen formal writer points")
|
||||
row = r.execute_phase(str(engine), stage, out, phase, test, selected, expected,
|
||||
fresh_engine_check("before-" + phase)
|
||||
if phase == "import" and old is None:
|
||||
r.require(not (stage / ".godot").exists(), "fresh import cache absent")
|
||||
row = phase_call(str(engine), stage, out, phase, test, selected, expected,
|
||||
previous, policy, contracts, paths, public, protected, root,
|
||||
outer, markers, diagnostics, owners, audio)
|
||||
phases.append(row)
|
||||
@@ -220,6 +270,8 @@ def main():
|
||||
# Fixed guard always follows ownership cleanup, even if setup or an engine failed.
|
||||
try:
|
||||
fixed_guard()
|
||||
r.require(uid_snapshot(stage, uid_source, uid_plan_map) == uid_state["accepted"], "UID seal after cleanup")
|
||||
r.write(out / "fresh-engine-checks.json", engine_checks)
|
||||
after = r.source_refs(root)
|
||||
r.write(out / "source_after.json", after)
|
||||
r.require(after == source_before, "whole product source unchanged")
|
||||
@@ -231,9 +283,15 @@ def main():
|
||||
except BaseException as caught:
|
||||
guards.append(type(caught).__name__ + ": " + str(caught))
|
||||
pids = [p.pid for p in outer.OWNED]
|
||||
passed = (error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
passed = (uid_state["accepted"] is not None and error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
and all(p["passed"] for p in phases) and len(pids) == len(set(pids)) == 4
|
||||
and all(p["engine_ended"] for p in cleanup))
|
||||
if passed:
|
||||
try:
|
||||
shared.mirror_formal(r, out, formal_before)
|
||||
except BaseException as caught:
|
||||
guards.append("formal mirror: " + str(caught))
|
||||
passed = False
|
||||
execution = dict(passed=passed, error=error, guard_errors=guards, phases=phases,
|
||||
actual_captured_PIDs=pids, cleanup=cleanup, cleanup_errors=cleanup_errors,
|
||||
formal_before=formal_before, formal_after=formal_after,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"""S2a-only native entry. --check-only never loads ownership helpers or starts Godot."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
@@ -73,17 +74,40 @@ def main():
|
||||
parser.add_argument("--cache-run", type=Path, default=CACHE_RUN)
|
||||
parser.add_argument("--godot", type=Path, default=ENGINE)
|
||||
parser.add_argument("--check-only", action="store_true")
|
||||
parser.add_argument("--main")
|
||||
parser.add_argument("--submission")
|
||||
parser.add_argument("--tested-tree")
|
||||
parser.add_argument("--historical-r17", action="store_true")
|
||||
args = parser.parse_args()
|
||||
shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")
|
||||
mode = shared.select_mode(args)
|
||||
fresh = mode == "fresh-q"
|
||||
if fresh and "--project-root" not in sys.argv:
|
||||
raise ValueError("fresh-q requires explicit --project-root")
|
||||
if fresh and "--cache-run" not in sys.argv:
|
||||
args.cache_run = None
|
||||
engine_descriptor = shared.engine_pin(args.godot) if fresh else None
|
||||
provenance = None
|
||||
|
||||
if args.project_root.is_symlink():
|
||||
raise ValueError("project root symlink")
|
||||
root = args.project_root.resolve()
|
||||
out = args.output.resolve()
|
||||
if fresh:
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("fresh plan/output must stay inside BUILD")
|
||||
if out.exists() or out.is_symlink() or (args.check_only and args.plan.exists()):
|
||||
raise ValueError("fresh output and plan required")
|
||||
r = module("s2a_standard_runner", root / "tools/run_all_tests.py")
|
||||
# Preserve the reviewed source_refs -> exactly one QA override order.
|
||||
source_before = r.source_refs(root)
|
||||
if fresh:
|
||||
provenance = shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree)
|
||||
refs = dict(source_before)
|
||||
refs[TEST] = pin(QA)
|
||||
template_guard()
|
||||
if not fresh: template_guard()
|
||||
expected = {n: dict(bytes=p["bytes"], sha256=p["sha256"]) for n, p in refs.items()}
|
||||
fixed = [pin(p) for p in MATERIALS + [
|
||||
fixed = [pin(p) for p in ([] if fresh else MATERIALS) + [
|
||||
QA, Path(__file__), HERE / "S2_ROOT_RUN.md",
|
||||
root / "tests/transport/test_runtime_transport.gd",
|
||||
root / "tests/staff/test_rescue_elevator.gd",
|
||||
@@ -92,7 +116,7 @@ def main():
|
||||
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
||||
cache_note = None
|
||||
cache_receipts = []
|
||||
for leaf in ["runner-ended.json", "runner-input.json"]:
|
||||
for leaf in (["runner-ended.json", "runner-input.json"] if args.cache_run is not None else []):
|
||||
path = args.cache_run / leaf
|
||||
try:
|
||||
cache_receipts.append(pin(path))
|
||||
@@ -106,6 +130,16 @@ def main():
|
||||
cache_receipts=cache_receipts, cache_access=cache_note,
|
||||
phases=["import", "parse", "writer", "reader"],
|
||||
native_engine_launches=0, whole_goal_accepted=False, unit_accepted=False)
|
||||
if fresh:
|
||||
uid_plan, uid_snapshot, uid_binding = shared.load_uid_helper(root, r, source_before)
|
||||
uid_source = copy.deepcopy(expected)
|
||||
uid_plan_map = uid_plan(refs)
|
||||
plan.update(protocol="p04-s2a-fresh-q-v1", mode=mode, provenance=provenance, engine=engine_descriptor,
|
||||
engine_sha256=engine_descriptor["sha256"], uid_helper=uid_binding,
|
||||
uid_plan=uid_plan_map, import_mode="fresh" if args.cache_run is None else "cache",
|
||||
historical_r17=False, fresh_q_evidence=False)
|
||||
fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))
|
||||
# No historical execution is admitted.
|
||||
# Check-only only reads source/materials and writes the plan in task build.
|
||||
# It deliberately does not read default-player data, inspect processes or stat Godot.
|
||||
if args.check_only:
|
||||
@@ -118,15 +152,27 @@ def main():
|
||||
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
||||
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
||||
return 0
|
||||
r.require(fresh, "historical mode is read-only")
|
||||
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
||||
reports, phase_call, uid_state = shared.make_uid_policy(r, uid_snapshot, uid_source, uid_plan_map, out)
|
||||
engine_checks = []
|
||||
def fresh_engine_check(label):
|
||||
value = shared.engine_pin(args.godot, engine_descriptor)
|
||||
engine_checks.append(dict(label=label, descriptor=value))
|
||||
def fixed_guard():
|
||||
template_guard()
|
||||
fresh_engine_check("fixed")
|
||||
r.require(shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree) == provenance,
|
||||
"fresh Q provenance changed")
|
||||
r.require(pin(root / uid_binding["helper_path"])["sha256"] == uid_binding["helper_sha256"],
|
||||
"UID helper changed")
|
||||
if not fresh: template_guard()
|
||||
for value in fixed + cache_receipts:
|
||||
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
||||
fixed_guard()
|
||||
# Native admission is Root-only and fails closed on unreadable cache.
|
||||
r.require(cache_note is None, "Root must read exact cache receipts: " + str(cache_note))
|
||||
old = args.cache_run
|
||||
if old is not None:
|
||||
r.require(r.read(old / "runner-ended.json")["passed"], "ended cache run must have passed")
|
||||
old_map = r.read(old / "runner-input.json")["selected_source_map"]
|
||||
current_map = {n: p["sha256"] for n, p in source_before.items()}
|
||||
@@ -175,6 +221,7 @@ def main():
|
||||
data = value["text"].encode()
|
||||
r.require(hashlib.sha256(data).hexdigest() == value["sha256"], "bootstrap pin")
|
||||
(out / "bootstrap" / name).write_bytes(data)
|
||||
if old is not None:
|
||||
cache = old / "stage/.godot"
|
||||
cache_before = r.inventory(cache)
|
||||
r.require(bool(cache_before), "nonempty ended cache")
|
||||
@@ -210,7 +257,10 @@ def main():
|
||||
writer = r.read(out / "raw/writer.json")
|
||||
formal_before = {n: r.inventory(Path(p)) for n, p in writer["slots"].items()}
|
||||
r.require(len(formal_before) == 1, "one C3 formal writer point")
|
||||
row = r.execute_phase(str(engine), stage, out, phase, test, selected, expected,
|
||||
fresh_engine_check("before-" + phase)
|
||||
if phase == "import" and old is None:
|
||||
r.require(not (stage / ".godot").exists(), "fresh import cache absent")
|
||||
row = phase_call(str(engine), stage, out, phase, test, selected, expected,
|
||||
previous, policy, contracts, paths, public, protected, root,
|
||||
outer, markers, diagnostics, owners, audio)
|
||||
phases.append(row)
|
||||
@@ -245,6 +295,8 @@ def main():
|
||||
# Fixed guard always follows ownership cleanup, even if setup or an engine failed.
|
||||
try:
|
||||
fixed_guard()
|
||||
r.require(uid_snapshot(stage, uid_source, uid_plan_map) == uid_state["accepted"], "UID seal after cleanup")
|
||||
r.write(out / "fresh-engine-checks.json", engine_checks)
|
||||
after = r.source_refs(root)
|
||||
r.write(out / "source_after.json", after)
|
||||
r.require(after == source_before, "whole product source unchanged")
|
||||
@@ -260,9 +312,15 @@ def main():
|
||||
except BaseException as caught:
|
||||
guards.append(type(caught).__name__ + ": " + str(caught))
|
||||
pids = [p.pid for p in outer.OWNED]
|
||||
passed = (error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
passed = (uid_state["accepted"] is not None and error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
and all(p["passed"] for p in phases) and len(pids) == len(set(pids)) == 4
|
||||
and all(p["engine_ended"] for p in cleanup))
|
||||
if passed:
|
||||
try:
|
||||
shared.mirror_formal(r, out, formal_before)
|
||||
except BaseException as caught:
|
||||
guards.append("formal mirror: " + str(caught))
|
||||
passed = False
|
||||
execution = dict(passed=passed, error=error, guard_errors=guards, phases=phases,
|
||||
actual_captured_PIDs=pids, cleanup=cleanup, cleanup_errors=cleanup_errors,
|
||||
formal_before=formal_before, formal_after=formal_after,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"""S2b-only native entry. --check-only never loads ownership helpers or starts Godot."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
@@ -62,19 +63,42 @@ def main():
|
||||
parser.add_argument("--cache-run", type=Path, default=CACHE_RUN)
|
||||
parser.add_argument("--godot", type=Path, default=ENGINE)
|
||||
parser.add_argument("--check-only", action="store_true")
|
||||
parser.add_argument("--main")
|
||||
parser.add_argument("--submission")
|
||||
parser.add_argument("--tested-tree")
|
||||
parser.add_argument("--historical-r17", action="store_true")
|
||||
args = parser.parse_args()
|
||||
shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")
|
||||
mode = shared.select_mode(args)
|
||||
fresh = mode == "fresh-q"
|
||||
if fresh and "--project-root" not in sys.argv:
|
||||
raise ValueError("fresh-q requires explicit --project-root")
|
||||
if fresh and "--cache-run" not in sys.argv:
|
||||
args.cache_run = None
|
||||
engine_descriptor = shared.engine_pin(args.godot) if fresh else None
|
||||
provenance = None
|
||||
|
||||
if args.project_root.is_symlink():
|
||||
raise ValueError("project root symlink")
|
||||
root = args.project_root.resolve()
|
||||
out = args.output.resolve()
|
||||
if fresh:
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("fresh plan/output must stay inside BUILD")
|
||||
if out.exists() or out.is_symlink() or (args.check_only and args.plan.exists()):
|
||||
raise ValueError("fresh output and plan required")
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("plan/output must stay in task build")
|
||||
r = module("s2b_standard_runner", root / "tools/run_all_tests.py")
|
||||
# Preserve the reviewed source_refs -> exactly one QA override order.
|
||||
source_before = r.source_refs(root)
|
||||
if fresh:
|
||||
provenance = shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree)
|
||||
refs = dict(source_before)
|
||||
refs[TEST] = pin(QA)
|
||||
template_guard(root)
|
||||
if not fresh: template_guard(root)
|
||||
expected = {n: dict(bytes=p["bytes"], sha256=p["sha256"]) for n, p in refs.items()}
|
||||
fixed = [pin(p) for p in MATERIALS + [
|
||||
fixed = [pin(p) for p in ([] if fresh else MATERIALS) + [
|
||||
QA, Path(__file__), HERE / "S2B_ROOT_RUN.md",
|
||||
root / "tests/transport/test_runtime_transport.gd",
|
||||
root / "tests/staff/test_rescue_elevator.gd",
|
||||
@@ -83,7 +107,7 @@ def main():
|
||||
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
||||
cache_note = None
|
||||
cache_receipts = []
|
||||
for leaf in ["runner-ended.json", "runner-input.json"]:
|
||||
for leaf in (["runner-ended.json", "runner-input.json"] if args.cache_run is not None else []):
|
||||
path = args.cache_run / leaf
|
||||
try:
|
||||
cache_receipts.append(pin(path))
|
||||
@@ -97,6 +121,16 @@ def main():
|
||||
cache_receipts=cache_receipts, cache_access=cache_note,
|
||||
phases=["import", "parse", "writer", "reader"],
|
||||
native_engine_launches=0, whole_goal_accepted=False, unit_accepted=False)
|
||||
if fresh:
|
||||
uid_plan, uid_snapshot, uid_binding = shared.load_uid_helper(root, r, source_before)
|
||||
uid_source = copy.deepcopy(expected)
|
||||
uid_plan_map = uid_plan(refs)
|
||||
plan.update(protocol="p04-s2b-fresh-q-v1", mode=mode, provenance=provenance, engine=engine_descriptor,
|
||||
engine_sha256=engine_descriptor["sha256"], uid_helper=uid_binding,
|
||||
uid_plan=uid_plan_map, import_mode="fresh" if args.cache_run is None else "cache",
|
||||
historical_r17=False, fresh_q_evidence=False)
|
||||
fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))
|
||||
# No historical execution is admitted.
|
||||
# Check-only only reads source/materials and writes the plan in task build.
|
||||
# It deliberately does not read default-player data, inspect processes or stat Godot.
|
||||
if args.check_only:
|
||||
@@ -109,16 +143,27 @@ def main():
|
||||
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
||||
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
||||
return 0
|
||||
r.require(root == PRODUCT.resolve() and len(source_before) == 1338, "Root native requires product 1338; worker plan is not native evidence")
|
||||
r.require(fresh, "historical mode is read-only")
|
||||
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
||||
reports, phase_call, uid_state = shared.make_uid_policy(r, uid_snapshot, uid_source, uid_plan_map, out)
|
||||
engine_checks = []
|
||||
def fresh_engine_check(label):
|
||||
value = shared.engine_pin(args.godot, engine_descriptor)
|
||||
engine_checks.append(dict(label=label, descriptor=value))
|
||||
def fixed_guard():
|
||||
template_guard(root)
|
||||
fresh_engine_check("fixed")
|
||||
r.require(shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree) == provenance,
|
||||
"fresh Q provenance changed")
|
||||
r.require(pin(root / uid_binding["helper_path"])["sha256"] == uid_binding["helper_sha256"],
|
||||
"UID helper changed")
|
||||
if not fresh: template_guard(root)
|
||||
for value in fixed + cache_receipts:
|
||||
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
||||
fixed_guard()
|
||||
# Native admission is Root-only and fails closed on unreadable cache.
|
||||
r.require(cache_note is None, "Root must read exact cache receipts: " + str(cache_note))
|
||||
old = args.cache_run
|
||||
if old is not None:
|
||||
r.require(r.read(old / "runner-ended.json")["passed"], "ended cache run must have passed")
|
||||
old_map = r.read(old / "runner-input.json")["selected_source_map"]
|
||||
current_map = {n: p["sha256"] for n, p in source_before.items()}
|
||||
@@ -167,6 +212,7 @@ def main():
|
||||
data = value["text"].encode()
|
||||
r.require(hashlib.sha256(data).hexdigest() == value["sha256"], "bootstrap pin")
|
||||
(out / "bootstrap" / name).write_bytes(data)
|
||||
if old is not None:
|
||||
cache = old / "stage/.godot"
|
||||
cache_before = r.inventory(cache)
|
||||
r.require(bool(cache_before), "nonempty ended cache")
|
||||
@@ -202,7 +248,10 @@ def main():
|
||||
writer = r.read(out / "raw/writer.json")
|
||||
formal_before = {n: r.inventory(Path(p)) for n, p in writer["slots"].items()}
|
||||
r.require(len(formal_before) == 6, "three formal points for each of two fresh branches")
|
||||
row = r.execute_phase(str(engine), stage, out, phase, test, selected, expected,
|
||||
fresh_engine_check("before-" + phase)
|
||||
if phase == "import" and old is None:
|
||||
r.require(not (stage / ".godot").exists(), "fresh import cache absent")
|
||||
row = phase_call(str(engine), stage, out, phase, test, selected, expected,
|
||||
previous, policy, contracts, paths, public, protected, root,
|
||||
outer, markers, diagnostics, owners, audio)
|
||||
phases.append(row)
|
||||
@@ -237,6 +286,8 @@ def main():
|
||||
# Fixed guard always follows ownership cleanup, even if setup or an engine failed.
|
||||
try:
|
||||
fixed_guard()
|
||||
r.require(uid_snapshot(stage, uid_source, uid_plan_map) == uid_state["accepted"], "UID seal after cleanup")
|
||||
r.write(out / "fresh-engine-checks.json", engine_checks)
|
||||
after = r.source_refs(root)
|
||||
r.write(out / "source_after.json", after)
|
||||
r.require(after == source_before, "whole product source unchanged")
|
||||
@@ -252,9 +303,15 @@ def main():
|
||||
except BaseException as caught:
|
||||
guards.append(type(caught).__name__ + ": " + str(caught))
|
||||
pids = [p.pid for p in outer.OWNED]
|
||||
passed = (error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
passed = (uid_state["accepted"] is not None and error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
and all(p["passed"] for p in phases) and len(pids) == len(set(pids)) == 4
|
||||
and all(p["engine_ended"] for p in cleanup))
|
||||
if passed:
|
||||
try:
|
||||
shared.mirror_formal(r, out, formal_before)
|
||||
except BaseException as caught:
|
||||
guards.append("formal mirror: " + str(caught))
|
||||
passed = False
|
||||
execution = dict(passed=passed, error=error, guard_errors=guards, phases=phases,
|
||||
actual_captured_PIDs=pids, cleanup=cleanup, cleanup_errors=cleanup_errors,
|
||||
formal_before=formal_before, formal_after=formal_after,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"""S3-only native entry. --check-only never loads ownership helpers or starts Godot."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
@@ -30,7 +31,8 @@ SLOTS = sorted(case + "-" + label for case in CASES for label in LABELS[case])
|
||||
MATERIALS = [MANIFEST, AUDIT, HERE.parent / "s2b/run_s2b_native.py",
|
||||
HERE.parent / "s2b/p04_s2b_shift_probe.gd", HERE.parent / "s2b/S2B_ROOT_RUN.md"]
|
||||
|
||||
def template_guard(root):
|
||||
def template_guard(root, historical=True):
|
||||
if historical:
|
||||
if pin(MANIFEST)["sha256"] != MANIFEST_SHA:
|
||||
raise ValueError("supplied seven-source manifest changed")
|
||||
manifest = json.loads(MANIFEST.read_text())
|
||||
@@ -80,19 +82,42 @@ def main():
|
||||
parser.add_argument("--cache-run", type=Path, default=CACHE_RUN)
|
||||
parser.add_argument("--godot", type=Path, default=ENGINE)
|
||||
parser.add_argument("--check-only", action="store_true")
|
||||
parser.add_argument("--main")
|
||||
parser.add_argument("--submission")
|
||||
parser.add_argument("--tested-tree")
|
||||
parser.add_argument("--historical-r17", action="store_true")
|
||||
args = parser.parse_args()
|
||||
shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")
|
||||
mode = shared.select_mode(args)
|
||||
fresh = mode == "fresh-q"
|
||||
if fresh and "--project-root" not in sys.argv:
|
||||
raise ValueError("fresh-q requires explicit --project-root")
|
||||
if fresh and "--cache-run" not in sys.argv:
|
||||
args.cache_run = None
|
||||
engine_descriptor = shared.engine_pin(args.godot) if fresh else None
|
||||
provenance = None
|
||||
|
||||
if args.project_root.is_symlink():
|
||||
raise ValueError("project root symlink")
|
||||
root = args.project_root.resolve()
|
||||
out = args.output.resolve()
|
||||
if fresh:
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("fresh plan/output must stay inside BUILD")
|
||||
if out.exists() or out.is_symlink() or (args.check_only and args.plan.exists()):
|
||||
raise ValueError("fresh output and plan required")
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("plan/output must stay in task build")
|
||||
r = module("s3_standard_runner", root / "tools/run_all_tests.py")
|
||||
# Preserve the reviewed source_refs -> exactly one QA override order.
|
||||
source_before = r.source_refs(root)
|
||||
if fresh:
|
||||
provenance = shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree)
|
||||
refs = dict(source_before)
|
||||
refs[TEST] = pin(QA)
|
||||
template_guard(root)
|
||||
template_guard(root, historical=not fresh)
|
||||
expected = {n: dict(bytes=p["bytes"], sha256=p["sha256"]) for n, p in refs.items()}
|
||||
fixed = [pin(p) for p in MATERIALS + [Path(row["supplied"]) for row in json.loads(MANIFEST.read_text())["files"]] + [
|
||||
fixed = [pin(p) for p in ([] if fresh else MATERIALS + [Path(row["supplied"]) for row in json.loads(MANIFEST.read_text())["files"]]) + [
|
||||
QA, Path(__file__), HERE / "S3_ROOT_RUN.md",
|
||||
root / "tests/transport/test_runtime_transport.gd",
|
||||
root / "tests/staff/test_rescue_elevator.gd",
|
||||
@@ -101,7 +126,7 @@ def main():
|
||||
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
||||
cache_note = None
|
||||
cache_receipts = []
|
||||
for leaf in ["runner-ended.json", "runner-input.json"]:
|
||||
for leaf in (["runner-ended.json", "runner-input.json"] if args.cache_run is not None else []):
|
||||
path = args.cache_run / leaf
|
||||
try:
|
||||
cache_receipts.append(pin(path))
|
||||
@@ -115,6 +140,16 @@ def main():
|
||||
cache_receipts=cache_receipts, cache_access=cache_note,
|
||||
phases=["import", "parse", "writer", "reader"],
|
||||
native_engine_launches=0, whole_goal_accepted=False, unit_accepted=False)
|
||||
if fresh:
|
||||
uid_plan, uid_snapshot, uid_binding = shared.load_uid_helper(root, r, source_before)
|
||||
uid_source = copy.deepcopy(expected)
|
||||
uid_plan_map = uid_plan(refs)
|
||||
plan.update(protocol="p04-s3-fresh-q-v1", mode=mode, provenance=provenance, engine=engine_descriptor,
|
||||
engine_sha256=engine_descriptor["sha256"], uid_helper=uid_binding,
|
||||
uid_plan=uid_plan_map, import_mode="fresh" if args.cache_run is None else "cache",
|
||||
historical_r17=False, fresh_q_evidence=False)
|
||||
fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))
|
||||
# No historical execution is admitted.
|
||||
# Check-only only reads source/materials and writes the plan in task build.
|
||||
# It deliberately does not read default-player data, inspect processes or stat Godot.
|
||||
if args.check_only:
|
||||
@@ -127,16 +162,27 @@ def main():
|
||||
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
||||
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
||||
return 0
|
||||
r.require(root == PRODUCT.resolve() and len(source_before) == 1338, "Root native requires product 1338; worker plan is not native evidence")
|
||||
r.require(fresh, "historical mode is read-only")
|
||||
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
||||
reports, phase_call, uid_state = shared.make_uid_policy(r, uid_snapshot, uid_source, uid_plan_map, out)
|
||||
engine_checks = []
|
||||
def fresh_engine_check(label):
|
||||
value = shared.engine_pin(args.godot, engine_descriptor)
|
||||
engine_checks.append(dict(label=label, descriptor=value))
|
||||
def fixed_guard():
|
||||
template_guard(root)
|
||||
fresh_engine_check("fixed")
|
||||
r.require(shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree) == provenance,
|
||||
"fresh Q provenance changed")
|
||||
r.require(pin(root / uid_binding["helper_path"])["sha256"] == uid_binding["helper_sha256"],
|
||||
"UID helper changed")
|
||||
template_guard(root, historical=not fresh)
|
||||
for value in fixed + cache_receipts:
|
||||
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
||||
fixed_guard()
|
||||
# Native admission is Root-only and fails closed on unreadable cache.
|
||||
r.require(cache_note is None, "Root must read exact cache receipts: " + str(cache_note))
|
||||
old = args.cache_run
|
||||
if old is not None:
|
||||
r.require(r.read(old / "runner-ended.json")["passed"], "ended cache run must have passed")
|
||||
old_map = r.read(old / "runner-input.json")["selected_source_map"]
|
||||
current_map = {n: p["sha256"] for n, p in source_before.items()}
|
||||
@@ -185,6 +231,7 @@ def main():
|
||||
data = value["text"].encode()
|
||||
r.require(hashlib.sha256(data).hexdigest() == value["sha256"], "bootstrap pin")
|
||||
(out / "bootstrap" / name).write_bytes(data)
|
||||
if old is not None:
|
||||
cache = old / "stage/.godot"
|
||||
cache_before = r.inventory(cache)
|
||||
r.require(bool(cache_before), "nonempty ended cache")
|
||||
@@ -220,7 +267,10 @@ def main():
|
||||
writer = r.read(out / "raw/writer.json")
|
||||
formal_before = {n: r.inventory(Path(p)) for n, p in writer["slots"].items()}
|
||||
r.require(sorted(formal_before) == SLOTS, "all 22 formal points for six fresh cases")
|
||||
row = r.execute_phase(str(engine), stage, out, phase, test, selected, expected,
|
||||
fresh_engine_check("before-" + phase)
|
||||
if phase == "import" and old is None:
|
||||
r.require(not (stage / ".godot").exists(), "fresh import cache absent")
|
||||
row = phase_call(str(engine), stage, out, phase, test, selected, expected,
|
||||
previous, policy, contracts, paths, public, protected, root,
|
||||
outer, markers, diagnostics, owners, audio)
|
||||
phases.append(row)
|
||||
@@ -256,6 +306,8 @@ def main():
|
||||
# Fixed guard always follows ownership cleanup, even if setup or an engine failed.
|
||||
try:
|
||||
fixed_guard()
|
||||
r.require(uid_snapshot(stage, uid_source, uid_plan_map) == uid_state["accepted"], "UID seal after cleanup")
|
||||
r.write(out / "fresh-engine-checks.json", engine_checks)
|
||||
after = r.source_refs(root)
|
||||
r.write(out / "source_after.json", after)
|
||||
r.require(after == source_before, "whole product source unchanged")
|
||||
@@ -271,9 +323,15 @@ def main():
|
||||
except BaseException as caught:
|
||||
guards.append(type(caught).__name__ + ": " + str(caught))
|
||||
pids = [p.pid for p in outer.OWNED]
|
||||
passed = (error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
passed = (uid_state["accepted"] is not None and error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
and all(p["passed"] for p in phases) and len(pids) == len(set(pids)) == 4
|
||||
and all(p["engine_ended"] for p in cleanup))
|
||||
if passed:
|
||||
try:
|
||||
shared.mirror_formal(r, out, formal_before)
|
||||
except BaseException as caught:
|
||||
guards.append("formal mirror: " + str(caught))
|
||||
passed = False
|
||||
execution = dict(passed=passed, error=error, guard_errors=guards, phases=phases,
|
||||
actual_captured_PIDs=pids, cleanup=cleanup, cleanup_errors=cleanup_errors,
|
||||
formal_before=formal_before, formal_after=formal_after,
|
||||
|
||||
@@ -29,7 +29,8 @@ LABELS = {"S4": ["boundary", "held", "recovered"]}
|
||||
SLOTS = ["S4-" + label for label in sorted(LABELS["S4"])]
|
||||
MATERIALS = [MANIFEST, BUILD / "audit-support/p04-review-repair22-r01/ACTUAL_CURRENT_PUBLIC_POWER_FUNCTIONS.json"]
|
||||
|
||||
def template_guard(root):
|
||||
def template_guard(root, historical=True):
|
||||
if historical:
|
||||
if root != PRODUCT.resolve() or not HERE.is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("Root must stage this exact QA/wrapper/plan inside own B")
|
||||
if pin(MANIFEST)["sha256"] != MANIFEST_SHA:
|
||||
@@ -105,12 +106,33 @@ def main():
|
||||
help="optional passed registered cache; default is fresh, without cache access")
|
||||
parser.add_argument("--godot", type=Path, default=ENGINE)
|
||||
parser.add_argument("--check-only", action="store_true")
|
||||
parser.add_argument("--main")
|
||||
parser.add_argument("--submission")
|
||||
parser.add_argument("--tested-tree")
|
||||
parser.add_argument("--historical-r17", action="store_true")
|
||||
args = parser.parse_args()
|
||||
shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")
|
||||
mode = shared.select_mode(args)
|
||||
fresh = mode == "fresh-q"
|
||||
if fresh and "--project-root" not in sys.argv:
|
||||
raise ValueError("fresh-q requires explicit --project-root")
|
||||
if fresh and "--cache-run" not in sys.argv:
|
||||
args.cache_run = None
|
||||
engine_descriptor = shared.engine_pin(args.godot) if fresh else None
|
||||
provenance = None
|
||||
|
||||
engine_descriptor = engine_pin(args.godot)
|
||||
if args.cache_run is not None and args.cache_run.resolve() != CACHE_RUN.resolve():
|
||||
raise ValueError("only registered own-B full-run cache")
|
||||
if args.project_root.is_symlink():
|
||||
raise ValueError("project root symlink")
|
||||
root = args.project_root.resolve()
|
||||
out = args.output.resolve()
|
||||
if fresh:
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("fresh plan/output must stay inside BUILD")
|
||||
if out.exists() or out.is_symlink() or (args.check_only and args.plan.exists()):
|
||||
raise ValueError("fresh output and plan required")
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("plan/output must stay in task build")
|
||||
if out.exists() or out.is_symlink():
|
||||
@@ -120,15 +142,17 @@ def main():
|
||||
r = module("s4_standard_runner", root / "tools/run_all_tests.py")
|
||||
# Preserve the reviewed source_refs -> exactly one QA override order.
|
||||
source_before = r.source_refs(root)
|
||||
if fresh:
|
||||
provenance = shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree)
|
||||
refs = dict(source_before)
|
||||
refs[TEST] = pin(QA)
|
||||
template_guard(root)
|
||||
template_guard(root, historical=not fresh)
|
||||
expected = {n: dict(bytes=p["bytes"], sha256=p["sha256"]) for n, p in refs.items()}
|
||||
fixed = [pin(p) for p in MATERIALS + [
|
||||
fixed = [pin(p) for p in ([] if fresh else MATERIALS) + [
|
||||
QA, Path(__file__), HERE / "S4_ROOT_RUN.md",
|
||||
root / "tests/transport/test_runtime_transport.gd",
|
||||
root / "tests/staff/test_rescue_elevator.gd",
|
||||
CONTRACTS,
|
||||
root / shared.C_REL if fresh else CONTRACTS,
|
||||
]]
|
||||
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
||||
cache_note = None
|
||||
@@ -154,6 +178,16 @@ def main():
|
||||
cache_receipts=cache_receipts, cache_access=cache_note,
|
||||
phases=["import", "parse", "writer", "reader"],
|
||||
native_engine_launches=0, whole_goal_accepted=False, unit_accepted=False)
|
||||
if fresh:
|
||||
uid_plan, uid_snapshot, uid_binding = shared.load_uid_helper(root, r, source_before)
|
||||
uid_source = copy.deepcopy(expected)
|
||||
uid_plan_map = uid_plan(refs)
|
||||
plan.update(protocol="p04-s4-fresh-q-v1", mode=mode, provenance=provenance, engine=engine_descriptor,
|
||||
engine_sha256=engine_descriptor["sha256"], uid_helper=uid_binding,
|
||||
uid_plan=uid_plan_map, import_mode="fresh" if args.cache_run is None else "cache",
|
||||
historical_r17=False, fresh_q_evidence=False)
|
||||
fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))
|
||||
# No historical execution is admitted.
|
||||
# Check-only only reads source/materials and writes the plan in task build.
|
||||
# Reads engine identity; never launches Godot or inspects players/processes.
|
||||
if args.check_only:
|
||||
@@ -163,7 +197,7 @@ def main():
|
||||
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
||||
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
||||
return 0
|
||||
r.require(root == PRODUCT.resolve() and len(source_before) == 1338, "Root native requires product 1338; worker plan is not native evidence")
|
||||
r.require(fresh, "historical mode is read-only")
|
||||
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
||||
engine_observations = []
|
||||
engine_identity = dict(before=engine_descriptor, during=[], after=None)
|
||||
@@ -178,9 +212,19 @@ def main():
|
||||
except BaseException as caught:
|
||||
engine_observations.append(dict(stage=label, error=str(caught)))
|
||||
raise
|
||||
reports, phase_call, uid_state = shared.make_uid_policy(r, uid_snapshot, uid_source, uid_plan_map, out)
|
||||
engine_checks = []
|
||||
def fresh_engine_check(label):
|
||||
value = shared.engine_pin(args.godot, engine_descriptor)
|
||||
engine_checks.append(dict(label=label, descriptor=value))
|
||||
def fixed_guard():
|
||||
fresh_engine_check("fixed")
|
||||
r.require(shared.fresh_q_guard(root, args.main, args.submission, args.tested_tree) == provenance,
|
||||
"fresh Q provenance changed")
|
||||
r.require(pin(root / uid_binding["helper_path"])["sha256"] == uid_binding["helper_sha256"],
|
||||
"UID helper changed")
|
||||
repin("cleanup-fixed-guard")
|
||||
template_guard(root)
|
||||
template_guard(root, historical=not fresh)
|
||||
for value in fixed + cache_receipts:
|
||||
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
||||
fixed_guard()
|
||||
@@ -257,7 +301,7 @@ def main():
|
||||
r.require(len(paths) == 316, "complete 316-script parse roster")
|
||||
r.write(out / "parse-paths.json", paths)
|
||||
markers = module("s4_markers", root / "tools/strict_test_markers.py")
|
||||
contracts = markers.load_contracts(CONTRACTS)
|
||||
contracts = markers.load_contracts(root / shared.C_REL if fresh else CONTRACTS)
|
||||
contracts[TEST] = dict(test=TEST, template="S4 power: <checks> checks, <failures> failures", required=True)
|
||||
policy = r.read(r.SUPPORT / "suite-policy.json")
|
||||
r.require(TEST not in policy["suite_policies"], "no normal suite watchdog/policy override")
|
||||
@@ -283,7 +327,10 @@ def main():
|
||||
repin("before-" + phase)
|
||||
r.write(out / ("engine-identity-before-" + phase + ".json"),
|
||||
dict(engine_observations[-1], observation_index=len(engine_observations)-1))
|
||||
row = r.execute_phase(str(engine), stage, out, phase, test, selected, expected,
|
||||
fresh_engine_check("before-" + phase)
|
||||
if phase == "import" and old is None:
|
||||
r.require(not (stage / ".godot").exists(), "fresh import cache absent")
|
||||
row = phase_call(str(engine), stage, out, phase, test, selected, expected,
|
||||
previous, policy, contracts, paths, public, protected, root,
|
||||
outer, markers, diagnostics, owners, audio)
|
||||
phases.append(row)
|
||||
@@ -330,6 +377,8 @@ def main():
|
||||
# Fixed guard always follows ownership cleanup, even if setup or an engine failed.
|
||||
try:
|
||||
fixed_guard()
|
||||
r.require(uid_snapshot(stage, uid_source, uid_plan_map) == uid_state["accepted"], "UID seal after cleanup")
|
||||
r.write(out / "fresh-engine-checks.json", engine_checks)
|
||||
after = r.source_refs(root)
|
||||
r.write(out / "source_after.json", after)
|
||||
r.require(after == source_before, "whole product source unchanged")
|
||||
@@ -345,7 +394,7 @@ def main():
|
||||
except BaseException as caught:
|
||||
guards.append(type(caught).__name__ + ": " + str(caught))
|
||||
pids = [p.pid for p in outer.OWNED]
|
||||
passed = (error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
passed = (uid_state["accepted"] is not None and error is None and not guards and not cleanup_errors and len(phases) == 4
|
||||
and all(p["passed"] for p in phases) and len(pids) == len(set(pids)) == 4
|
||||
and all(p["engine_ended"] for p in cleanup))
|
||||
execution = dict(passed=passed, error=error, guard_errors=guards, phases=phases,
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
# REPAIR40 implementation supersession; native evidence remains pending
|
||||
|
||||
The implementation-pending statements below are superseded only for S5A/S5B
|
||||
power, S5C command destruction, S5D automatic raid destruction, S5E paid midnight
|
||||
and S5F command/planned exit. The single CASE_TABLE now dispatches these cases.
|
||||
No case is relabelled as an executed proof. Root must establish every outcome
|
||||
from fresh Q raw; an unalignable raid or unsupported condition fails normally.
|
||||
|
||||
The S5 order adapter does not infer patience_release or paused_midnight.
|
||||
Fresh S3 can supply patience_release only from its own actually observed raw.
|
||||
The remaining frozen REQUIRED conditions, including shift_completion,
|
||||
same_minute_replay and paused_midnight, are not supplied by historical union.
|
||||
The final checker must remain failed if any required condition is missing.
|
||||
|
||||
The earlier text is retained as historical planning context:
|
||||
|
||||
# S5 — pending implementation, not a native run plan
|
||||
|
||||
No S5 executable driver or native receipt is supplied by this partial repair.
|
||||
|
||||
@@ -1,3 +1,73 @@
|
||||
# REPAIR40 A–F source batch — Root verification required
|
||||
|
||||
This section supersedes earlier implementation-pending directions below only
|
||||
for the code now supplied. It is not admission, a native result, original credit,
|
||||
or permission to repeat the once-only final full run.
|
||||
|
||||
Root order (unchanged):
|
||||
1. Affected pure controls. Keep every previous negative. Run full_suite_verifier.py
|
||||
--controls. New S5 typed mutation controls require actual fresh native raw;
|
||||
their positives remain unexecuted until that raw exists.
|
||||
2. Check-only S1–S5 plans on the final Q.
|
||||
3. One heavy lease: fresh native S1–S5, capacity/PID checks and verified complete
|
||||
Writer/Reader restore manifests. Within this step, evaluate the order adapter
|
||||
and its typed mutation controls against actual S5 raw when available.
|
||||
4. Fresh collect to a new exclusive audit-support/p04-raw-collect-q<N>.
|
||||
5. Full 184/329 once on final Q; derive actual roster/parse/source counts.
|
||||
6. Index.
|
||||
7. --verify-only.
|
||||
8. Independent review.
|
||||
9. Normal prepare/final and Root post-final normal_c_join.
|
||||
|
||||
Stage the complete unchanged directory hierarchy (including shared s5 wrapper,
|
||||
adapters and series dependencies) under BUILD/audit-support/p04-fresh-context.
|
||||
Stage the actual Q source there as well, preserving source bytes. Native outputs
|
||||
must be separate directories under BUILD, outside that context directory.
|
||||
Use --main M --submission S --tested-tree Qt --project-root <actual-Q> for every
|
||||
run_s*_native.py. No global monkeypatching is used to select Q.
|
||||
Historical --historical-r17 --check-only remains read-only. No historical native
|
||||
execution is admissible. All fresh plans/outputs are exclusive and must be absent.
|
||||
The single QA override and the selected source/UID/engine/ownership gates remain.
|
||||
|
||||
Before fresh collection Root writes audit-support/p04-fresh-runs.json from the
|
||||
actual receipts (no baked receipt SHA values):
|
||||
- protocol: p04-fresh-runs-v1
|
||||
- M, S, Q_tree: the actual full HEX40 inputs
|
||||
- collection: audit-support/p04-raw-collect-q<N>
|
||||
- series: exactly s1, s2a, s2b, s3, s4, s5; each entry has run (BUILD-relative)
|
||||
and byte/SHA descriptors named runner_input, runner_ended, raw_inventory,
|
||||
formal_relocation, read from the corresponding actual output files.
|
||||
- full_suite: run (BUILD-relative), runner_input and runner_ended descriptors
|
||||
from the final full run. These fields are consumed at index/checker time,
|
||||
so fresh collection precedes and does not depend on the full run.
|
||||
Use collect_p04_native.py --build <BUILD> --fresh q<N>.
|
||||
Never overwrite r22 and never merge its verified_conditions.
|
||||
|
||||
The full run uses the actual Q tools/run_all_tests.py standard schema and the
|
||||
Root finite-UID controller contract illustrated in the hash-verified context.
|
||||
Retain source-start.json, runner-input/ended, all-tests, parse-paths, every phase
|
||||
receipt/process/started/ended/log, UID plan/seals, retained stage and generated
|
||||
reports. full_suite_verifier imports that actual Q runner and marker/diagnostic
|
||||
modules. Its 15+EV entries explicitly distinguish suite applicability from
|
||||
boundary proof. test_required_kitchen is separately bound. It consumes no C,
|
||||
prepare/final or independent-review result; normal C remains Root's later join.
|
||||
|
||||
S5 has one CASE_TABLE for reserved counts, ordered labels and prepare/advance/
|
||||
stop/assert methods. S5A/B retain their original recovery and duplicate path.
|
||||
S5C–F use public commands and ordinary ticks. The automatic raid uses the
|
||||
autonomy fixture strengths with the service facility as OBJECTIVE; its queried
|
||||
earliest_minute must equal N. New cases replay independently after formal load.
|
||||
The adapter uses typed nodes, complete typed restore/replay equality and raw
|
||||
phase/receipt joins. It fails rather than fabricating an unavailable observation.
|
||||
The private receipt buffer is restored for C–F because their boundary already
|
||||
contains transactions; the A/B boundary receipt behavior is unchanged.
|
||||
|
||||
No worker engine, Git, Runner, native or controls run occurred. Only the recorded
|
||||
static checks were performed. r35/r36 remain FAILED; worker38/39 stops remain
|
||||
historical records; Q37 remains a local diagnostic. Original credit remains zero.
|
||||
|
||||
## Retained earlier directions
|
||||
|
||||
# Concrete32 power pair — unexecuted, not batch admission
|
||||
|
||||
`p04_s5_power_probe.gd` supplies S5A_PURE (paid public bath, genuine mana
|
||||
|
||||
+151
-14
@@ -1,7 +1,14 @@
|
||||
extends "res://tests/s3/test_runtime_actor_hardening.gd"
|
||||
|
||||
const CASES: Array[String] = ["S5A_PURE", "S5B_DEPENDENCY"]
|
||||
const SEEDS: Dictionary = {"S5A_PURE": 420550, "S5B_DEPENDENCY": 420551}
|
||||
const CASE_TABLE: Dictionary = {
|
||||
"S5A_PURE": {"expected_reserved_ids": 0, "labels": ["boundary", "held", "recovered", "duplicate_guard"], "prepare": "_prepare", "advance": "_advance", "stop": "_assert_stopped", "assert": "_assert_outcome"},
|
||||
"S5B_DEPENDENCY": {"expected_reserved_ids": 1, "labels": ["boundary", "held", "recovered", "duplicate_guard"], "prepare": "_prepare", "advance": "_advance", "stop": "_assert_stopped", "assert": "_assert_outcome"},
|
||||
"S5C_DESTRUCTION_COMMAND": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_order_stop", "assert": "_assert_order"},
|
||||
"S5D_DESTRUCTION_RAID": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_order_stop", "assert": "_assert_order"},
|
||||
"S5E_MIDNIGHT": {"expected_reserved_ids": 1, "labels": ["boundary", "recalled"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_order_stop", "assert": "_assert_order"},
|
||||
"S5F_EXIT": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_order_stop", "assert": "_assert_order"}
|
||||
}
|
||||
const SEEDS: Dictionary = {"S5A_PURE": 420550, "S5B_DEPENDENCY": 420551, "S5C_DESTRUCTION_COMMAND": 420552, "S5D_DESTRUCTION_RAID": 420553, "S5E_MIDNIGHT": 424242, "S5F_EXIT": 420555}
|
||||
const GUEST: StringName = &"p04.s5.guest.a"
|
||||
const REQUEST: StringName = &"p04.s5.request.a"
|
||||
const QUEUED_GUEST: StringName = &"p04.s5.guest.b"
|
||||
@@ -38,7 +45,7 @@ func _run() -> void:
|
||||
return
|
||||
_expect(DirAccess.make_dir_recursive_absolute(_evidence_dir) == OK, "external evidence directory")
|
||||
if _mode == "writer":
|
||||
for branch: String in CASES:
|
||||
for branch: String in CASE_TABLE:
|
||||
_case = branch
|
||||
_writer_case()
|
||||
else:
|
||||
@@ -92,7 +99,7 @@ func _queue(guest_id: StringName, request_id: StringName, exit_at: int) -> void:
|
||||
_expect(guest != null and request != null, "actual Guest and request exist")
|
||||
if guest == null or request == null: return
|
||||
_expect(guest.state == GuestRuntime.State.QUEUING and guest.queue_request_id == request_id, "actual queued ownership before advancing clock")
|
||||
_expect(request.quoted_price == _price and request.service_minutes == _duration and request.reserved_inventory_ids.size() == (1 if _case == "S5B_DEPENDENCY" else 0), "definition price/duration and one meal reservation")
|
||||
_expect(request.quoted_price == _price and request.service_minutes == _duration and request.reserved_inventory_ids.size() == CASE_TABLE[_case]["expected_reserved_ids"], "definition price/duration and one meal reservation")
|
||||
for id: StringName in request.reserved_inventory_ids:
|
||||
var reservation: InventoryReservation = _runtime.inventory_service.get_reservation(id)
|
||||
_expect(reservation != null and reservation.is_active() and reservation.requester_id == request_id, "public queue actually reserves meal")
|
||||
@@ -148,6 +155,128 @@ func _prepare() -> bool:
|
||||
_expect(_reserve > 0 and service.elapsed_minutes == _duration - 1, "positive reserve and duration-1 progress")
|
||||
return _clock.absolute_minute == _boundary - 1
|
||||
|
||||
func _prepare_order() -> bool:
|
||||
_fresh()
|
||||
var midnight: bool = _case == "S5E_MIDNIGHT"
|
||||
if midnight:
|
||||
_boundary = 1440
|
||||
var enabled: Dictionary = _runtime.enable_production_operations()
|
||||
_expect(bool(enabled.get(&"ok", false)), "S2a public operations path")
|
||||
if not bool(enabled.get(&"ok", false)): return false
|
||||
var facility: FacilityInstance = _build_cafeteria(true)
|
||||
if facility == null: return false
|
||||
_facility_id = facility.instance_id
|
||||
var definition: FacilityDefinition = _runtime.definition_registry.get_facility(facility.definition_id)
|
||||
_price = definition.base_price
|
||||
_duration = definition.base_service_minutes
|
||||
_patience = _runtime.guest_service.get_definition(&"traveler").base_patience
|
||||
if midnight:
|
||||
_prepare_paid_reception()
|
||||
_cmd(&"set_staff_work_assignment", {&"staff_id": StringName("fixture.kitchen.worker.%s" % _facility_id), &"template_id": &"NIGHT", &"facility_id": facility.related_facility_id})
|
||||
var staff_ids: Array[StringName] = []
|
||||
for index: int in range(definition.staff_min):
|
||||
var id: StringName = StringName("p04.s5.staff.%d" % index)
|
||||
staff_ids.append(id)
|
||||
_cmd(&"register_staff", {&"staff_id": id, &"role_id": &"server", &"options": {&"state": StaffRuntime.State.OFF_DUTY, &"current_cell": Vector3i.ZERO}})
|
||||
_cmd(&"set_staff_work_assignment", {&"staff_id": id, &"template_id": &"NIGHT" if midnight else &"DAY", &"facility_id": _facility_id})
|
||||
var queue_at: int = _boundary - _duration - 1
|
||||
_expect(_price > 0 and _duration > 1 and queue_at > _clock.absolute_minute, "natural paid service before boundary")
|
||||
if queue_at <= _clock.absolute_minute or _duration <= 1: return false
|
||||
if _case == "S5D_DESTRUCTION_RAID":
|
||||
_expect(_duration > 5, "raid setup fits before natural completion")
|
||||
if _duration <= 5: return false
|
||||
_clock.advance_minutes(queue_at - _clock.absolute_minute)
|
||||
_expect(facility.active_staff_ids == staff_ids, "ordinary physical attendance")
|
||||
var second: bool = _case in ["S5D_DESTRUCTION_RAID", "S5F_EXIT"]
|
||||
_expect(_stock(facility.local_inventory_id, &"ingredient/basic_meal", 2 if second else 1, &"p04.s5.order.stock"), "actual reservable meals")
|
||||
_queue(GUEST, REQUEST, _boundary if _case == "S5F_EXIT" else _boundary + _duration + 1)
|
||||
_clock.advance_one_minute()
|
||||
var active: Array = _runtime.facility_service.get_active_services(_facility_id)
|
||||
_expect(active.size() == 1, "one natural primary service")
|
||||
if active.size() != 1: return false
|
||||
var service: ServiceInstance = active[0]
|
||||
_service_id = service.service_id
|
||||
_expect(service.started_at + _duration == _boundary, "natural N completion")
|
||||
if _case == "S5D_DESTRUCTION_RAID":
|
||||
_clock.advance_minutes(_boundary - 5 - _clock.absolute_minute)
|
||||
_prepare_breach()
|
||||
_clock.advance_minutes(_boundary - 2 - _clock.absolute_minute)
|
||||
_queue(QUEUED_GUEST, QUEUED_REQUEST, _boundary + _duration + 1)
|
||||
_clock.advance_minutes(_boundary - 1 - _clock.absolute_minute)
|
||||
if _case == "S5F_EXIT": _queue(QUEUED_GUEST, QUEUED_REQUEST, _boundary + _duration + 1)
|
||||
_reserve = _state.get_resource(&"mana")
|
||||
_recovery = {&"staff_ids": staff_ids, &"resume_minute": _boundary}
|
||||
_expect(service.elapsed_minutes == _duration - 1, "duration minus one at N-1")
|
||||
return _clock.absolute_minute == _boundary - 1
|
||||
|
||||
func _prepare_paid_reception() -> void:
|
||||
# S2a paid-midnight fixture, with catalog wages and ordinary assignments.
|
||||
var definition: FacilityDefinition = _runtime.definition_registry.get_facility(&"reception")
|
||||
_cmd(&"build_facility", {&"definition_id": &"reception", &"origin": Vector3i(2, 0, WorldService.LAYER_FRONT)})
|
||||
_clock.advance_minutes(definition.build_minutes)
|
||||
var reception_id: StringName = &""
|
||||
for instance: FacilityInstance in _runtime.facility_service.get_instances():
|
||||
if instance.definition_id == &"reception": reception_id = instance.instance_id
|
||||
_expect(not reception_id.is_empty(), "public paid reception completed")
|
||||
var catalog: Dictionary = JSON.parse_string(FileAccess.get_file_as_string("res://data/characters/mvp_staff_candidates.json"))
|
||||
for candidate_id: StringName in [&"staff_akane", &"staff_bardo"]:
|
||||
var wage: int = -1
|
||||
for row: Dictionary in catalog["entries"]:
|
||||
if StringName(row["id"]) == candidate_id: wage = int(row["daily_wage"])
|
||||
_cmd(&"hire_staff_candidate", {&"candidate_id": candidate_id})
|
||||
var worker: StaffRuntime = _runtime.staff_service.get_staff(candidate_id)
|
||||
_expect(worker != null and wage > 0 and worker.get_effective_daily_wage() == wage, "unchanged paid catalog wage")
|
||||
_cmd(&"set_staff_work_assignment", {&"staff_id": candidate_id, &"template_id": &"DAY" if candidate_id == &"staff_akane" else &"NIGHT", &"facility_id": reception_id})
|
||||
|
||||
func _prepare_breach() -> void:
|
||||
# Exact autonomy fixture strengths; the real service facility is the objective.
|
||||
_cmd(&"set_facility_conditions", {&"facility_id": _facility_id, &"conditions": {&"durability": 1}})
|
||||
_cmd(&"register_staff", {&"staff_id": &"p04.s5.guard", &"role_id": &"security", &"options": {&"state": StaffRuntime.State.AVAILABLE, &"health": 100, &"fatigue": 0, &"skills": {&"combat": 100}}})
|
||||
var wave: Dictionary = {&"wave_id": &"p04.s5.wave", &"threat_strength": 1000, &"retreat_threshold": 0, &"max_rounds": 1, &"entry_points": [&"gate.north"]}
|
||||
_cmd(&"create_defense_raid", {&"raid_id": &"p04.s5.raid", &"definition": {&"source_id": &"runtime_test", &"entry_points": [&"gate.north", &"gate.south"], &"objective_ids": [_facility_id], &"waves": [wave], &"round_minutes": 5, &"max_duration_minutes": 180, &"retreat_policy": &"HOLD", &"defender_retreat_threshold": 0}})
|
||||
_cmd(&"register_defense_combatant", {&"raid_id": &"p04.s5.raid", &"actor_id": &"p04.s5.guard", &"side": &"DEFENDER", &"combat": 0, &"max_health": 100, &"options": {&"armor": 2}})
|
||||
_cmd(&"register_defense_asset", {&"raid_id": &"p04.s5.raid", &"asset_id": _facility_id, &"kind": &"OBJECTIVE", &"max_integrity": 10000, &"defense": 0, &"options": {&"target_order": 1}})
|
||||
_cmd(&"register_defense_combatant", {&"raid_id": &"p04.s5.raid", &"actor_id": &"p04.s5.attacker", &"side": &"ATTACKER", &"combat": 1000, &"max_health": 100, &"options": {&"wave_id": &"p04.s5.wave", &"entry_point_id": &"gate.north"}})
|
||||
_cmd(&"start_defense_raid", {&"raid_id": &"p04.s5.raid"})
|
||||
var due: Array[Dictionary] = _runtime.defense_service.get_due_rounds(_boundary)
|
||||
_expect(due.size() == 1 and due[0][&"earliest_minute"] == _boundary and due[0][&"raid_id"] == &"p04.s5.raid", "automatic breach due at exactly N; no substitute")
|
||||
|
||||
func _advance_order(label: String) -> void:
|
||||
if label == "boundary":
|
||||
if _case == "S5C_DESTRUCTION_COMMAND": _cmd(&"set_facility_conditions", {&"facility_id": _facility_id, &"conditions": {&"durability": 0}}, _boundary)
|
||||
if _case == "S5F_EXIT": _cmd(&"leave_facility_queue", {&"facility_id": _facility_id, &"request_id": QUEUED_REQUEST}, _boundary)
|
||||
if label == "recalled":
|
||||
var before: Dictionary = _runtime.create_snapshot()
|
||||
var replay: CommandResult = _runtime.operations_coordinator.advance_to(_boundary)
|
||||
_expect(replay.is_success() and replay.is_replay, "same midnight is a replay")
|
||||
_expect(var_to_bytes(before) == var_to_bytes(_runtime.create_snapshot()), "same-minute replay changes no typed state")
|
||||
_recovery[&"midnight_replay"] = replay.to_dictionary()
|
||||
else:
|
||||
_clock.advance_one_minute()
|
||||
|
||||
func _assert_order_stop(point: Dictionary) -> void:
|
||||
if _case == "S5C_DESTRUCTION_COMMAND":
|
||||
_expect(point[&"service"][&"state"] == "FAILED" and point[&"service"][&"failure_reason"] == String(FacilityService.INTERRUPTION_BROKEN), "command destruction interrupts before payment")
|
||||
else:
|
||||
_expect(point[&"service"][&"state"] == "COMPLETED", "natural completion precedes later boundary effects")
|
||||
if _case in ["S5C_DESTRUCTION_COMMAND", "S5D_DESTRUCTION_RAID"]:
|
||||
_expect(point[&"facility"][&"durability"] == 0 and point[&"facility"][&"state"] == "BROKEN", "destroyed facility")
|
||||
if _case == "S5D_DESTRUCTION_RAID":
|
||||
_expect(point[&"facility"][&"suspension_reason"] == "DESTROYED", "automatic breach suspension")
|
||||
if _case == "S5E_MIDNIGHT":
|
||||
_expect(point[&"operations_enabled"] and not point[&"actual_coordinator_absent"], "operations-enabled midnight")
|
||||
|
||||
func _assert_order(before: Dictionary, point: Dictionary) -> void:
|
||||
_assert_order_stop(point)
|
||||
var paid: bool = _case != "S5C_DESTRUCTION_COMMAND"
|
||||
_expect(point[&"wallets"][String(GUEST)] == before[&"wallets"][String(GUEST)] - (_price if paid else 0), "exact primary wallet delta")
|
||||
_assert_reservation(before, point, REQUEST, "CONSUMED" if paid else "RELEASED", _boundary)
|
||||
if _case == "S5F_EXIT" or (_case == "S5D_DESTRUCTION_RAID" and point[&"minute"] > _boundary):
|
||||
_assert_reservation(before, point, QUEUED_REQUEST, "RELEASED", _boundary if _case == "S5F_EXIT" else _boundary + 1)
|
||||
_expect(point[&"wallets"][String(QUEUED_GUEST)] == before[&"wallets"][String(QUEUED_GUEST)], "secondary request never charged")
|
||||
if _case == "S5F_EXIT" and point[&"minute"] == _boundary:
|
||||
_expect(point[&"guests"][String(GUEST)][&"state"] == "LEAVING", "planned exit after completed service")
|
||||
|
||||
func _connect_observations() -> void:
|
||||
_runtime.economy_service.transaction_posted.connect(func(id: StringName, entries: Array) -> void:
|
||||
var rows: Array = []
|
||||
@@ -201,7 +330,10 @@ func _capture() -> Dictionary:
|
||||
&"actual_coordinator_absent": _runtime.operations_coordinator == null, &"unrelated_getters_called": false}
|
||||
|
||||
func _labels() -> Array[String]:
|
||||
return ["boundary", "held", "recovered"]
|
||||
var labels: Array[String] = []
|
||||
for label: String in CASE_TABLE[_case]["labels"]:
|
||||
if label != "duplicate_guard": labels.append(label)
|
||||
return labels
|
||||
|
||||
func _advance(label: String) -> void:
|
||||
if label == "boundary":
|
||||
@@ -250,16 +382,17 @@ func _advance(label: String) -> void:
|
||||
_clock.advance_one_minute()
|
||||
|
||||
func _writer_case() -> void:
|
||||
if not _prepare(): return
|
||||
if not Callable(self, CASE_TABLE[_case]["prepare"]).call(): return
|
||||
var before: Dictionary = _capture()
|
||||
_assert_before(before)
|
||||
if _case in ["S5A_PURE", "S5B_DEPENDENCY"]: _assert_before(before)
|
||||
_points["before"] = _write("before", before)
|
||||
_connect_observations()
|
||||
for label: String in _labels():
|
||||
_advance(label)
|
||||
Callable(self, CASE_TABLE[_case]["advance"]).call(label)
|
||||
var actual: Dictionary = _capture()
|
||||
_assert_outcome(before, actual)
|
||||
Callable(self, CASE_TABLE[_case]["assert"]).call(before, actual)
|
||||
_save_point(label, actual)
|
||||
if "duplicate_guard" in CASE_TABLE[_case]["labels"]:
|
||||
_advance("duplicate_guard")
|
||||
var guard: Dictionary = _capture()
|
||||
_assert_outcome(before, guard)
|
||||
@@ -410,6 +543,8 @@ func _load_point(path: String, expected: Dictionary) -> bool:
|
||||
var restored: bool = _runtime.restore_snapshot(loaded[&"snapshot"])
|
||||
_expect(restored, "public Runtime restore")
|
||||
_expect(var_to_bytes(_runtime.create_snapshot()) == var_to_bytes(expected[&"snapshot"]), "all restored typed fields equal Writer")
|
||||
if _case not in ["S5A_PURE", "S5B_DEPENDENCY"]:
|
||||
_receipts = expected[&"receipts"].duplicate(true)
|
||||
return restored
|
||||
|
||||
func _is_replayed_phase(row: Dictionary) -> bool:
|
||||
@@ -418,6 +553,7 @@ func _is_replayed_phase(row: Dictionary) -> bool:
|
||||
func _assert_expected_phase_roster(references: Array) -> void:
|
||||
var expected_pairs: Array = []
|
||||
var end: int = int(_recovery[&"resume_minute"]) + 1
|
||||
if _case == "S5E_MIDNIGHT": end = _boundary
|
||||
for minute: int in range(_boundary, end):
|
||||
for phase: int in range(SimulationKernel.TickPhase.size()):
|
||||
expected_pairs.append([minute if phase == SimulationKernel.TickPhase.APPLY_COMMANDS else minute + 1, SimulationKernel.TickPhase.keys()[phase]])
|
||||
@@ -434,7 +570,7 @@ func _reader() -> void:
|
||||
var writer: Dictionary = JSON.parse_string(file.get_as_text())
|
||||
file.close()
|
||||
_expect(int(writer["pid"]) != OS.get_process_id() and writer["profile"] != OS.get_user_data_dir(), "independent Reader PID/profile")
|
||||
for branch: String in CASES:
|
||||
for branch: String in CASE_TABLE:
|
||||
_case = branch
|
||||
var writer_case: Dictionary = _read(writer["branches"][branch])
|
||||
var hashes: Dictionary = {}
|
||||
@@ -465,15 +601,16 @@ func _reader() -> void:
|
||||
var before: Dictionary = _read(writer_case[&"points"]["before"])
|
||||
var boundary: Dictionary = _read(writer_case[&"points"]["boundary"])
|
||||
if not _load_point(_slots[branch + "-boundary"], boundary): return
|
||||
_assert_stopped(_capture())
|
||||
Callable(self, CASE_TABLE[_case]["stop"]).call(_capture())
|
||||
_connect_observations()
|
||||
var replay_refs: Dictionary = {}
|
||||
for label: String in ["held", "recovered", "duplicate_guard"]:
|
||||
_advance(label)
|
||||
for label: String in CASE_TABLE[_case]["labels"]:
|
||||
if label == "boundary": continue
|
||||
Callable(self, CASE_TABLE[_case]["advance"]).call(label)
|
||||
var actual: Dictionary = _capture()
|
||||
var expected: Dictionary = _read(writer_case[&"points"][label])
|
||||
_expect(var_to_bytes(actual) == var_to_bytes(expected), "replay complete typed point including Runtime, inputs, receipts " + label)
|
||||
_assert_outcome(before, actual)
|
||||
Callable(self, CASE_TABLE[_case]["assert"]).call(before, actual)
|
||||
replay_refs[label] = _write(label + "-replay", actual)
|
||||
var expected_phases: Array = []
|
||||
for reference: Dictionary in writer_case[&"phases"]:
|
||||
|
||||
@@ -29,8 +29,23 @@ ENGINE_SHA256 = "c7cccbf8fb143e34e02fd6521e09be2c2b974f0d5db080b19071c9c570718cc
|
||||
MANIFEST = BUILD / "audit-support/p04-r17-full-inputs-r01/MANIFEST.json"
|
||||
MANIFEST_SHA = "a15f29fa12537f6d8aaf7cabea390922a9f16e3eb9c10981e5742aafc8c4c8a8"
|
||||
CONTRACTS = BUILD / "audit-support/p04-r17-full-inputs-r01/fixed/6ce6b28c5985e8a4f13b78bfeb1f1e09f6216d874fb01e0656ec1633bfa01cd7/completion_marker_contracts.json"
|
||||
CASES = ["S5A_PURE", "S5B_DEPENDENCY"]
|
||||
LABELS = {case: ["boundary", "held", "recovered"] for case in CASES}
|
||||
def case_table(path):
|
||||
matches = re.findall(r"^const CASE_TABLE: Dictionary = (\{.*?^\})", Path(path).read_text(), re.M | re.S)
|
||||
if len(matches) != 1:
|
||||
raise ValueError("exactly one literal CASE_TABLE required")
|
||||
table = json.loads(matches[0])
|
||||
for case, row in table.items():
|
||||
if (set(row) != {"expected_reserved_ids", "labels", "prepare", "advance", "stop", "assert"}
|
||||
or not row["labels"] or row["labels"][0] != "boundary"
|
||||
or len(row["labels"]) != len(set(row["labels"]))):
|
||||
raise ValueError("invalid case table: " + case)
|
||||
return table
|
||||
|
||||
|
||||
CASE_TABLE = case_table(QA)
|
||||
CASES = list(CASE_TABLE)
|
||||
LABELS = {case: [label for label in row["labels"] if label != "duplicate_guard"]
|
||||
for case, row in CASE_TABLE.items()}
|
||||
SLOTS = sorted(case + "-" + label for case in CASES for label in LABELS[case])
|
||||
MATERIALS = [MANIFEST, BUILD / "audit-support/p04-review-repair22-r01/ACTUAL_CURRENT_PUBLIC_POWER_FUNCTIONS.json"]
|
||||
|
||||
@@ -171,6 +186,27 @@ def engine_pin(path, expected=None):
|
||||
raise ValueError("engine identity changed")
|
||||
return value
|
||||
|
||||
|
||||
def mirror_formal(r, out, before):
|
||||
"""Mirror complete Writer and Reader packages, preserving original receipts."""
|
||||
relocated = {}
|
||||
for role in ("writer", "reader"):
|
||||
receipt = r.read(out / ("raw/" + role + ".json"))
|
||||
r.require(set(receipt["slots"]) == set(before), "formal slot roster")
|
||||
relocated[role] = {}
|
||||
for slot, original in receipt["slots"].items():
|
||||
r.require(Path(slot).name == slot and slot not in (".", ".."), "formal slot name")
|
||||
target = out / "formal" / role / slot
|
||||
target.mkdir(parents=True)
|
||||
members = r.inventory(Path(original))
|
||||
r.require(set(members) == {"journal.log", "manifest.json", "thumbnail.png", "world.bin"}
|
||||
and members == before[slot], "complete unchanged formal package")
|
||||
for member in members:
|
||||
shutil.copyfile(Path(original) / member, target / member)
|
||||
r.require(r.inventory(target) == members, "all copied formal hashes")
|
||||
relocated[role][slot] = dict(provenance=original, relative=str(target.relative_to(out)), members=members)
|
||||
r.write(out / "formal-relocation.json", relocated)
|
||||
|
||||
C_REL = "docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json"
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Typed S5 ordering derivations. Native provenance is verified separately."""
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def module(name, path):
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
value = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(value)
|
||||
return value
|
||||
|
||||
|
||||
POWER_PATH = Path(__file__).with_name('s5_power_adapter.py')
|
||||
power = module('s5_order_power', POWER_PATH)
|
||||
Raw, staff_check, duplicate_check = power.Raw, power.staff_check, power.duplicate_check
|
||||
series, require = power.series, power.require
|
||||
DEPENDENCIES = {str(p): hashlib.sha256(p.read_bytes()).hexdigest()
|
||||
for p in (POWER_PATH, power.SERIES_PATH)}
|
||||
GUEST, REQUEST = power.GUEST, power.REQUEST
|
||||
SECOND, SECOND_REQUEST = 'p04.s5.guest.b', 'p04.s5.request.b'
|
||||
|
||||
|
||||
def field(node, *keys):
|
||||
for key in keys:
|
||||
node = node.at(key)
|
||||
return node
|
||||
|
||||
|
||||
def scalar(node, *keys):
|
||||
node = field(node, *keys)
|
||||
require(node.kind in (1, 2, 4, 21), 'typed scalar required')
|
||||
return node.value
|
||||
|
||||
|
||||
def rows(node, *keys):
|
||||
node = field(node, *keys)
|
||||
require(node.kind == 28, 'typed array required')
|
||||
return node.value
|
||||
|
||||
|
||||
def phase(phases, name, minute):
|
||||
found = [p for p in phases if scalar(p, 'phase') == name and scalar(p, 'minute') == minute]
|
||||
require(len(found) == 1, 'one raw phase: ' + name)
|
||||
return found[0]
|
||||
|
||||
|
||||
def sales(point):
|
||||
return [r for r in rows(point, 'ledger') if scalar(r, 'category') == 'SERVICE_SALE'
|
||||
and scalar(r, 'credit_account') == 'GUEST_WALLET:' + GUEST]
|
||||
|
||||
|
||||
def release(before, after, request, minute):
|
||||
old = [r for r in rows(before, 'reservations') if scalar(r, 'requester_id') == request]
|
||||
new = [r for r in rows(after, 'reservations') if scalar(r, 'requester_id') == request]
|
||||
require(len(old) == len(new) == 1, 'one original reservation')
|
||||
ident = scalar(old[0], 'reservation_id')
|
||||
require(scalar(new[0], 'reservation_id') == ident and scalar(old[0], 'state') == 'ACTIVE'
|
||||
and scalar(new[0], 'state') == 'RELEASED' and scalar(new[0], 'terminal_at') == minute,
|
||||
'reservation release identity/state/time')
|
||||
operations = rows(after, 'snapshot', 'systems', 'runtime', 'inventory', 'idempotency_results')
|
||||
matches = [r for r in operations if scalar(r, 'action') == 'release'
|
||||
and scalar(r, 'result', 'reservation_id') == ident]
|
||||
require(len(matches) == 1 and scalar(matches[0], 'result', 'ok') is True,
|
||||
'exactly one successful release')
|
||||
require(field(after, 'requests', request).plain() == {}, 'no orphan request')
|
||||
return ident
|
||||
|
||||
|
||||
def payment(before, after, minute):
|
||||
sale = sales(after)
|
||||
require(not sales(before) and len(sale) == 1, 'exactly one new sale')
|
||||
price = scalar(before, 'inputs', 'price')
|
||||
require(price > 0 and scalar(sale[0], 'amount') == price
|
||||
and scalar(sale[0], 'absolute_minute') == minute
|
||||
and scalar(sale[0], 'source_entity_id') == scalar(after, 'inputs', 'facility_id'),
|
||||
'sale amount/time/facility')
|
||||
require(scalar(after, 'wallets', GUEST) == scalar(before, 'wallets', GUEST) - price,
|
||||
'single wallet debit')
|
||||
require(scalar(after, 'service', 'state') == 'COMPLETED'
|
||||
and scalar(after, 'service', 'completed_at') == minute, 'completed before payment')
|
||||
runtime = field(after, 'snapshot', 'systems', 'runtime')
|
||||
key = 'service.payment.' + scalar(after, 'service', 'service_id')
|
||||
idem = [r for r in rows(runtime, 'economy', 'idempotency') if scalar(r, 'key') == key]
|
||||
require(len(idem) == 1 and scalar(idem[0], 'transaction_id') == scalar(sale[0], 'transaction_id'),
|
||||
'independent service/payment idempotency join')
|
||||
receipt_entries = [r for receipt in rows(after, 'receipts') for r in rows(receipt, 'entries')]
|
||||
require(sum(r.raw == sale[0].raw for r in receipt_entries) == 1, 'sale bound to one typed receipt')
|
||||
return sale[0]
|
||||
|
||||
|
||||
def destruction_command(points, phases):
|
||||
before, end = points['before'], points['held']
|
||||
n = scalar(before, 'inputs', 'boundary')
|
||||
prior = phase(phases, 'FACILITY_COMPLETION', n)
|
||||
require(scalar(prior, 'facility', 'durability') == 0
|
||||
and scalar(prior, 'facility', 'state') == 'BROKEN', 'command destroys before completion')
|
||||
for p in (points['boundary'], end):
|
||||
require(scalar(p, 'service', 'state') == 'FAILED'
|
||||
and scalar(p, 'service', 'failure_reason') == 'BROKEN', 'INTERRUPTION_BROKEN')
|
||||
require(not sales(p) and scalar(p, 'wallets', GUEST) == scalar(before, 'wallets', GUEST),
|
||||
'zero destroyed charge')
|
||||
release(before, p, REQUEST, n)
|
||||
return {'destruction_stop': {'charges': 0}, 'command_destruction_before_completion': True}
|
||||
|
||||
|
||||
def destruction_raid(points, phases):
|
||||
before, end = points['before'], points['held']
|
||||
n = scalar(before, 'inputs', 'boundary')
|
||||
pre = phase(phases, 'INCIDENTS_AND_EVENTS', n)
|
||||
post = phase(phases, 'FACILITY_QUEUES', n)
|
||||
payment(before, phase(phases, 'VITALS_AND_ENVIRONMENT', n), n)
|
||||
payment(before, pre, n)
|
||||
require(scalar(pre, 'facility', 'durability') > 0 and scalar(post, 'facility', 'durability') == 0
|
||||
and scalar(post, 'facility', 'state') == 'BROKEN'
|
||||
and scalar(post, 'facility', 'suspension_reason') == 'DESTROYED', 'sale before automatic destruction')
|
||||
require(scalar(end, 'minute') == n + 1, 'unfinished failure at N+1')
|
||||
release(before, end, SECOND_REQUEST, n + 1)
|
||||
failed = [r for r in rows(end, 'snapshot', 'systems', 'runtime', 'facilities', 'service_history')
|
||||
if scalar(r, 'request_id') == SECOND_REQUEST]
|
||||
require(len(failed) == 1 and scalar(failed[0], 'state') == 'FAILED'
|
||||
and scalar(failed[0], 'failure_reason') == 'BROKEN', 'unfinished service failed by broken facility')
|
||||
require(scalar(end, 'wallets', SECOND) == scalar(before, 'wallets', SECOND), 'no unfinished charge')
|
||||
require([r.raw for r in sales(end)] == [r.raw for r in sales(pre)], 'no extra raid sale')
|
||||
return {'raid_sale_before_destruction': True, 'raid_unfinished_release': True}
|
||||
|
||||
|
||||
def midnight_day(points, phases):
|
||||
before, end, replay = points['before'], points['boundary'], points['recalled']
|
||||
n = scalar(before, 'inputs', 'boundary')
|
||||
require(n > 0 and n % 1440 == 0, 'midnight multiple')
|
||||
pre = phase(phases, 'FACILITY_COMPLETION', n)
|
||||
require(not sales(pre), 'settlement before sale')
|
||||
coordinator = field(pre, 'snapshot', 'systems', 'runtime', 'operations', 'coordinator')
|
||||
days = [r for r in rows(coordinator, 'day_summaries') if scalar(r, 'closed_at') == n]
|
||||
require(len(days) == 1 and scalar(days[0], 'period_end_minute_exclusive') == n,
|
||||
'one half-open DAILY_CLOSE at N')
|
||||
upkeep = [r for r in rows(pre, 'ledger') if scalar(r, 'category') == 'MAINTENANCE_PAYMENT'
|
||||
and scalar(r, 'absolute_minute') == n]
|
||||
require(upkeep and len({scalar(r, 'transaction_id') for r in upkeep}) == 1, 'a_upkeep before sale')
|
||||
mana = phase(phases, 'MANA', n)
|
||||
require(all(any(r.raw == u.raw for r in rows(mana, 'ledger')) for u in upkeep),
|
||||
'upkeep posted during TIME_BOUNDARIES')
|
||||
sale = payment(before, end, n)
|
||||
payment(before, phase(phases, 'VITALS_AND_ENVIRONMENT', n), n)
|
||||
require(n <= scalar(sale, 'absolute_minute') < n + 1440, 'new day sale')
|
||||
require(field(end, 'snapshot').raw == field(replay, 'snapshot').raw,
|
||||
'same-minute replay preserves every typed Runtime field')
|
||||
require(scalar(replay, 'inputs', 'recovery', 'midnight_replay', 'is_replay') is True,
|
||||
'same minute is_replay')
|
||||
def paid_view(point):
|
||||
value = point.plain()
|
||||
runtime = value['snapshot']['systems']['runtime']
|
||||
value.update(staff=runtime['staff'], payroll=runtime['staff']['payroll_settlements'],
|
||||
shifts=runtime['staff']['shifts'], operations=runtime['operations']['coordinator'],
|
||||
idempotency={'economy': runtime['economy']['idempotency']})
|
||||
return value
|
||||
# Reuse the unchanged paid-midnight ledger/duty joins after the typed order gates.
|
||||
series.settlement(paid_view(before), paid_view(end))
|
||||
return {'midnight_settlement': {'settlements': 1, 'sales_payments': 1, 'payroll_payments': 1,
|
||||
'upkeep_payments': 1, 'duty_payments': 1, 'nonzero_payroll': True},
|
||||
'midnight_replay': {'settlements': 1, 'same_minute_replayed': True, 'duplicate_payments': 0},
|
||||
'midnight_close_upkeep_before_sale': True, 'midnight_new_day_sale': True}
|
||||
|
||||
|
||||
def exit_order(points, phases):
|
||||
before = points['before']
|
||||
n = scalar(before, 'inputs', 'boundary')
|
||||
pre = phase(phases, 'FACILITY_COMPLETION', n)
|
||||
release(before, pre, SECOND_REQUEST, n)
|
||||
for p in [pre, points['boundary'], points['held']]:
|
||||
services = rows(p, 'snapshot', 'systems', 'runtime', 'facilities', 'service_history')
|
||||
services = services + [s for facility in rows(p, 'snapshot', 'systems', 'runtime', 'facilities', 'instances')
|
||||
for s in rows(facility, 'active_services')]
|
||||
require(not any(scalar(s, 'request_id') == SECOND_REQUEST for s in services), 'command exit before start')
|
||||
require(scalar(p, 'wallets', SECOND) == scalar(before, 'wallets', SECOND), 'command exit no charge')
|
||||
ai = phase(phases, 'AI_DECISIONS', n)
|
||||
published = phase(phases, 'PUBLISH_SNAPSHOT', n)
|
||||
payment(before, ai, n)
|
||||
payment(before, phase(phases, 'VITALS_AND_ENVIRONMENT', n), n)
|
||||
require(scalar(ai, 'guests', GUEST, 'state') == 'DECIDING'
|
||||
and scalar(ai, 'guests', GUEST, 'planned_exit_at') <= n
|
||||
and scalar(published, 'guests', GUEST, 'state') == 'LEAVING'
|
||||
and scalar(published, 'guests', GUEST, 'exit_reason') == 'PLANNED_EXIT',
|
||||
'AI exit only after DECIDING and paid completion')
|
||||
return {'exit_release': {'orphan_reservations': 0, 'released_once': True}, 'command_exit_before_start': True,
|
||||
'planned_exit_after_completion': True}
|
||||
|
||||
|
||||
DERIVERS = {'S5C_DESTRUCTION_COMMAND': destruction_command, 'S5D_DESTRUCTION_RAID': destruction_raid,
|
||||
'S5E_MIDNIGHT': midnight_day, 'S5F_EXIT': exit_order}
|
||||
|
||||
|
||||
def derive(root, writer_sha, reader_sha):
|
||||
root = Path(root)
|
||||
raw = Raw(root)
|
||||
writer = json.loads(raw.pin(root / 'writer.json', writer_sha), object_pairs_hook=power.unique)
|
||||
reader = json.loads(raw.pin(root / 'reader.json', reader_sha), object_pairs_hook=power.unique)
|
||||
require(writer['pid'] != reader['pid'] and writer['profile'] != reader['profile'], 'independent Reader')
|
||||
expected = set(DERIVERS) | set(power.CASES)
|
||||
require(set(writer['branches']) == set(reader['branches']) == expected, 'complete S5 roster')
|
||||
result = {}
|
||||
for case, function in DERIVERS.items():
|
||||
branch = raw.reference(writer['branches'][case])
|
||||
replay = raw.reference(reader['branches'][case])
|
||||
points = {k: raw.typed(v) for k, v in branch['points'].items()}
|
||||
phases = [raw.typed(r) for r in branch['phases']]
|
||||
raw.typed(branch['commands'])
|
||||
for p in points.values():
|
||||
staff_check(p, field(p, 'inputs', 'recovery'))
|
||||
result[case] = function(points, phases)
|
||||
for label, ref in replay['restored'].items():
|
||||
require(field(raw.typed(ref), 'snapshot').raw == field(points[label], 'snapshot').raw,
|
||||
'whole typed formal restore')
|
||||
require(set(replay['restored']) == set(points) - {'before'}, 'complete restore roster')
|
||||
require(set(replay['replay']) == set(points) - {'before', 'boundary'}, 'complete replay roster')
|
||||
for label, ref in replay['replay'].items():
|
||||
require(raw.typed(ref).raw == points[label].raw, 'whole typed independent replay')
|
||||
n = scalar(points['before'], 'inputs', 'boundary')
|
||||
expected_phases = [p.raw for p in phases if scalar(p, 'minute') > n or
|
||||
(scalar(p, 'minute') == n and scalar(p, 'phase') == 'APPLY_COMMANDS')]
|
||||
require([raw.typed(r).raw for r in replay['phases']] == expected_phases, 'complete phase replay')
|
||||
result[case]['formal_restore_verified'] = True
|
||||
if case == 'S5E_MIDNIGHT':
|
||||
result[case]['save_restore'] = {'settlements': 1, 'duplicate_payments': 0, 'formal_save_restored': True}
|
||||
return {'cases': result, 'dependency_sha256': DEPENDENCIES, 'raw_sha256': raw.hashes,
|
||||
'pending': ['patience_release', 'paused_midnight'], 'formal_acceptance': False}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Root-only typed mutations against fresh native S5 raw; never synthetic positives."""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
import struct
|
||||
import sys
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
import s5_order_adapter as a
|
||||
|
||||
mutation = a.module('order_typed_mutation', Path(__file__).with_name('s5_power_adapter_controls.py'))
|
||||
BUILD = Path('/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build')
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--raw-root', type=Path, required=True)
|
||||
parser.add_argument('--writer-sha256', required=True)
|
||||
parser.add_argument('--reader-sha256', required=True)
|
||||
parser.add_argument('--scratch', type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
scratch = args.scratch
|
||||
a.require(scratch.is_absolute() and not scratch.exists() and not scratch.is_symlink(), 'explicit absent scratch')
|
||||
a.require(scratch.parent.resolve(strict=True).is_relative_to(BUILD.resolve(strict=True)), 'scratch inside BUILD')
|
||||
a.require(not scratch.resolve().is_relative_to(args.raw_root.resolve()), 'scratch outside native raw')
|
||||
for parent in scratch.parents:
|
||||
a.require(not parent.is_symlink(), 'scratch ancestor symlink')
|
||||
positive = a.derive(args.raw_root, args.writer_sha256, args.reader_sha256)
|
||||
scratch.mkdir()
|
||||
raw = a.Raw(args.raw_root)
|
||||
writer = json.loads(raw.pin(args.raw_root / 'writer.json', args.writer_sha256))
|
||||
cases = {}
|
||||
for case in a.DERIVERS:
|
||||
branch = raw.reference(writer['branches'][case])
|
||||
cases[case] = ({k: raw.typed(v) for k, v in branch['points'].items()},
|
||||
[raw.typed(r) for r in branch['phases']])
|
||||
checks = []
|
||||
|
||||
def negative(label, case, owner, target, replacement):
|
||||
points, phases = cases[case]
|
||||
encoded = mutation.replace(owner, target, replacement)
|
||||
(scratch / (label + '.var')).write_bytes(encoded)
|
||||
changed = a.series.variant(encoded)
|
||||
changed_points = {k: changed if v is owner else v for k, v in points.items()}
|
||||
changed_phases = [changed if v is owner else v for v in phases]
|
||||
try:
|
||||
a.DERIVERS[case](changed_points, changed_phases)
|
||||
except ValueError:
|
||||
checks.append(label)
|
||||
return
|
||||
raise ValueError('mutation accepted: ' + label)
|
||||
|
||||
midnight = 'S5E_MIDNIGHT'
|
||||
points, phases = cases[midnight]
|
||||
n = a.scalar(points['before'], 'inputs', 'boundary')
|
||||
end = points['boundary']
|
||||
negative('sale-old-day', midnight, end, a.field(a.sales(end)[0], 'absolute_minute'), mutation.scalar(2, n - 1))
|
||||
pre = a.phase(phases, 'FACILITY_COMPLETION', n)
|
||||
days = a.field(pre, 'snapshot', 'systems', 'runtime', 'operations', 'coordinator', 'day_summaries')
|
||||
empty = days.raw[:-sum(len(r.raw) for r in days.value)] if days.value else days.raw
|
||||
# Preserve the original typed-array header and replace its element count.
|
||||
start = 12 if days.raw[:4] == struct.pack('<I', 28 | (1 << 16)) else 8
|
||||
empty = days.raw[:start-4] + struct.pack('<I', 0)
|
||||
negative('settlement-after-sale', midnight, pre, days, empty)
|
||||
raid = 'S5D_DESTRUCTION_RAID'
|
||||
points, phases = cases[raid]
|
||||
pre = a.phase(phases, 'INCIDENTS_AND_EVENTS', a.scalar(points['before'], 'inputs', 'boundary'))
|
||||
negative('raid-sale-missing', raid, pre, a.field(a.sales(pre)[0], 'category'), mutation.scalar(4, 'REMOVED_SALE'))
|
||||
command = 'S5C_DESTRUCTION_COMMAND'
|
||||
points, phases = cases[command]
|
||||
end = points['held']
|
||||
ops = a.field(end, 'snapshot', 'systems', 'runtime', 'inventory', 'idempotency_results')
|
||||
release = next(r for r in ops.value if a.scalar(r, 'action') == 'release')
|
||||
start = 12 if ops.raw[:4] == struct.pack('<I', 28 | (1 << 16)) else 8
|
||||
doubled = ops.raw[:start-4] + struct.pack('<I', len(ops.value) + 1) + ops.raw[start:] + release.raw
|
||||
negative('double-release', command, end, ops, doubled)
|
||||
exit_case = 'S5F_EXIT'
|
||||
points, phases = cases[exit_case]
|
||||
n = a.scalar(points['before'], 'inputs', 'boundary')
|
||||
ai = a.phase(phases, 'AI_DECISIONS', n)
|
||||
negative('ai-exit-during-service', exit_case, ai, a.field(ai, 'guests', a.GUEST, 'state'), mutation.scalar(4, 'RECEIVING_SERVICE'))
|
||||
pre = a.phase(phases, 'FACILITY_COMPLETION', n)
|
||||
reservation = next(r for r in a.rows(pre, 'reservations') if a.scalar(r, 'requester_id') == a.SECOND_REQUEST)
|
||||
negative('command-exit-after-start', exit_case, pre, a.field(reservation, 'terminal_at'), mutation.scalar(2, n + 1))
|
||||
print(json.dumps({'positive_cases': list(positive['cases']), 'negative_controls': checks,
|
||||
'formal_acceptance': False}, sort_keys=True))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -100,7 +100,9 @@ def derive(root, writer_sha, reader_sha):
|
||||
writer = json.loads(raw.pin(root / "writer.json", writer_sha), object_pairs_hook=unique)
|
||||
reader = json.loads(raw.pin(root / "reader.json", reader_sha), object_pairs_hook=unique)
|
||||
require(writer["pid"] != reader["pid"] and writer["profile"] != reader["profile"], "independent reader required")
|
||||
require(set(writer["branches"]) == set(reader["branches"]) == set(CASES), "exact case pair")
|
||||
expected = set(CASES) | {"S5C_DESTRUCTION_COMMAND", "S5D_DESTRUCTION_RAID", "S5E_MIDNIGHT", "S5F_EXIT"}
|
||||
require(set(writer["branches"]) == set(reader["branches"]) and
|
||||
set(writer["branches"]) in (set(CASES), expected), "exact pair or full case table roster")
|
||||
output = {}
|
||||
for case in CASES:
|
||||
branch = raw.reference(writer["branches"][case])
|
||||
|
||||
@@ -283,6 +283,15 @@ def supplied_file(directory, descriptor):
|
||||
support = directory / 'audit-support'
|
||||
roots = [support / n for n in ('p04-whole-closure-r01', 'native-first-current',
|
||||
'p04-current-native-series-r01', 'p04-r17-full-inputs-r01')]
|
||||
fresh_path = support / 'p04-fresh-runs.json'
|
||||
if fresh_path.is_file():
|
||||
fresh = load(fresh_path)
|
||||
require(fresh['protocol'] == 'p04-fresh-runs-v1', 'fresh material registry')
|
||||
roots.append(support / 'p04-fresh-context')
|
||||
for row in fresh['series'].values():
|
||||
relative = Path(row['run'])
|
||||
require(not relative.is_absolute() and '..' not in relative.parts, 'fresh material run path')
|
||||
roots.append(directory / relative)
|
||||
matches = [root for root in roots if path.is_relative_to(root)]
|
||||
require(len(matches) == 1, 'unsupplied external material: ' + name)
|
||||
path = safe(matches[0], path.relative_to(matches[0]).as_posix())
|
||||
@@ -356,6 +365,10 @@ def verify_roles(index, directory):
|
||||
composed = git_bytes('-c', 'rerere.enabled=false', 'merge-tree', '--write-tree',
|
||||
main, submitted).decode().strip()
|
||||
require(re.fullmatch('[0-9a-f]{40}', composed) is not None, 'conflicted composition')
|
||||
if 'fresh_run_bindings' in index:
|
||||
fresh = index['fresh_run_bindings']
|
||||
require((fresh['M'], fresh['S'], fresh['Q_tree']) == (main, submitted, composed),
|
||||
'fresh evidence does not bind recomputed Q')
|
||||
main_entries, patch, target = [tree_entries(t) for t in (main, submitted, composed)]
|
||||
anchor_entries = tree_entries(MAIN_ANCHOR)
|
||||
for path in main_entries.keys() | target.keys():
|
||||
@@ -1050,7 +1063,7 @@ def verify_shift_completion(base):
|
||||
return {'verified_conditions': ['shift_completion'], 'phases': points, 'transaction_id': transaction_id}
|
||||
|
||||
|
||||
def combine_native_series(directory, native):
|
||||
def combine_historical_native_series(directory, native):
|
||||
"""Independent R composition; rerun raw checks, never trust condition scalars.
|
||||
|
||||
The C verifier and its fixtures remain unchanged. This function does not
|
||||
@@ -1095,6 +1108,80 @@ def combine_native_series(directory, native):
|
||||
'stage_A': 'candidate binding stage A pending', 'formal_acceptance': False}
|
||||
|
||||
|
||||
def combine_native_series(directory, native):
|
||||
"""Fresh raw supplies conditions; historical collection is separate provenance."""
|
||||
import importlib.util
|
||||
def module(name, path):
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
value = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(value)
|
||||
return value
|
||||
module_path = ROOT / DOC_SCOPE / 'p04_native_series.py'
|
||||
series = module('p04_fresh_series', module_path)
|
||||
root_bindings = series.fresh_bindings(directory)
|
||||
collection = root_bindings['collection']
|
||||
require(re.fullmatch(r'audit-support/p04-raw-collect-q[0-9]+', collection) is not None,
|
||||
'exclusive fresh collection name')
|
||||
base = directory / collection
|
||||
manifest_path = safe(base, 'MANIFEST.json')
|
||||
manifest = load(manifest_path)
|
||||
require(manifest['protocol'] == 'p04-fresh-native-series-collection-v1'
|
||||
and manifest['historical_merged'] is False
|
||||
and set(manifest['series']) == set(series.FRESH_RUNS), 'fresh series roster')
|
||||
verified, bindings, results, pids = set(), {}, {}, []
|
||||
for name in series.FRESH_RUNS:
|
||||
binding = manifest['series'][name]
|
||||
path = safe(base, binding['path'])
|
||||
require(path.name == name + '.json' and sha(path) == binding['sha256']
|
||||
and path.stat().st_size == binding['bytes'], 'fresh series collection pin')
|
||||
recorded = load(path)
|
||||
require(recorded['verifier_sha256'] == sha(module_path), 'fresh verifier drift')
|
||||
actual = getattr(series, 'verify_fresh_' + name)(directory)
|
||||
require({k: v for k, v in recorded.items() if k != 'verifier_sha256'} == actual, 'fresh raw recomputation drift')
|
||||
verified.update(actual['verified_conditions'])
|
||||
pids.extend(actual['owned_pids'])
|
||||
bindings[name], results[name] = binding['sha256'], actual
|
||||
require(len(pids) == len(set(pids)), 'fresh series PID reuse')
|
||||
order = results['s5']['facts']['order']['cases']
|
||||
gates = {
|
||||
'D05-P04-DESTRUCTION': [('S5C_DESTRUCTION_COMMAND', 'command_destruction_before_completion'),
|
||||
('S5D_DESTRUCTION_RAID', 'raid_sale_before_destruction'),
|
||||
('S5D_DESTRUCTION_RAID', 'raid_unfinished_release')],
|
||||
'D05-P04-MIDNIGHT-DAY': [('S5E_MIDNIGHT', 'midnight_close_upkeep_before_sale'),
|
||||
('S5E_MIDNIGHT', 'midnight_new_day_sale')],
|
||||
'D05-P04-EXIT': [('S5F_EXIT', 'command_exit_before_start'), ('S5F_EXIT', 'planned_exit_after_completion')],
|
||||
}
|
||||
for ref, pairs in gates.items():
|
||||
require(all(order[case][key] is True for case, key in pairs), 'S5 order gate: ' + ref)
|
||||
power = results['s5']['facts']['power']['cases']
|
||||
require(power['S5A_PURE']['measurements']['power_stop'] == REQUIRED['power_stop'][2]
|
||||
and power['S5B_DEPENDENCY']['measurements']['dependency_stop'] == REQUIRED['dependency_stop'][2],
|
||||
'S5 D05-P04-PAUSE-REASON gate')
|
||||
full_verifier = module('p04_full_verifier', ROOT / DOC_SCOPE / 'full_suite_verifier.py')
|
||||
full_binding = root_bindings['full_suite']
|
||||
full_run = directory / full_binding['run']
|
||||
require(not Path(full_binding['run']).is_absolute() and '..' not in Path(full_binding['run']).parts,
|
||||
'full run path')
|
||||
for leaf, key in [('runner-input.json', 'runner_input'), ('runner-ended.json', 'runner_ended')]:
|
||||
series.checked(safe(full_run, leaf).read_bytes(), full_binding[key], 'Root full receipt')
|
||||
full_inputs = load(safe(full_run, 'runner-input.json'))
|
||||
full = full_verifier.verify(Path(full_inputs['project_root']), full_run, REQUIRED)
|
||||
require(full['verified'] is True and set(full['conditions']) == set(REQUIRED) | {'EV'}, 'full condition membership')
|
||||
expected_source = {n: p['sha256'] for n, p in load(directory / root_bindings['series']['s5']['run'] / 'source_before.json').items()}
|
||||
require(full['source_sha256'] == expected_source, 'full and boundary exact same Q')
|
||||
history = safe(directory / 'audit-support/p04-raw-collect-r22', 'MANIFEST.json')
|
||||
c_base = directory / 'audit-support/native-first-current'
|
||||
require(native == verify_native(c_base), 'historical C provenance recomputation')
|
||||
return {'verified_conditions': sorted(verified), 'series_manifest_sha256': sha(manifest_path),
|
||||
'series_bindings': bindings, 'fresh_collection': collection, 'full_suite': full,
|
||||
'historical_collection': {'manifest_sha256': sha(history), 'merged': False},
|
||||
'C_source_manifest_sha256': sha(safe(c_base, 'SOURCE_MANIFEST.json')),
|
||||
'C_provenance_sha256': sha(safe(c_base, 'OWNERSHIP_RAW_PROVENANCE.json')),
|
||||
'missing_conditions': sorted((set(REQUIRED) | {'EV'}) - verified),
|
||||
'nativeWindows': {name: 'pending' for name in sorted(set(REQUIRED) | {'EV'})},
|
||||
'stage_A': 'candidate binding stage A pending', 'formal_acceptance': False}
|
||||
|
||||
|
||||
def verify(directory):
|
||||
# Contract hashes the supplied spec string, while the checked-in JSON has
|
||||
# one final LF. Accept only that exact representation difference.
|
||||
|
||||
Reference in New Issue
Block a user