P04-01: 同時発生の更新規約
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
+445
-144
@@ -1,162 +1,463 @@
|
|||||||
{
|
{
|
||||||
"repair": 43,
|
"repair": 45,
|
||||||
"scope": "Static worker checks only",
|
"status": "ready",
|
||||||
"python": [
|
"scope": "Worker implementation ready for submission only; whole unit incomplete",
|
||||||
|
"repair44_attempt": {
|
||||||
|
"repair": 44,
|
||||||
|
"status": "blocked",
|
||||||
|
"scope": "Actual worker checks only; no native or formal acceptance",
|
||||||
|
"blocker": {
|
||||||
|
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r43-eb94e1d7/tools/run_all_tests.py",
|
||||||
|
"operation": "UID pure control module read",
|
||||||
|
"error": "PermissionError: [Errno 1] Operation not permitted",
|
||||||
|
"stop_authority": "REPAIR44: stop for an actually unreadable file"
|
||||||
|
},
|
||||||
|
"approval_sha256": {
|
||||||
|
"expected": "cd365ded1b777a0327d090709f0a4161f5005562819183455d9f2e106fba3e96",
|
||||||
|
"actual": "cd365ded1b777a0327d090709f0a4161f5005562819183455d9f2e106fba3e96",
|
||||||
|
"result": "PASS"
|
||||||
|
},
|
||||||
|
"spec": {
|
||||||
|
"raw_bytes": 7000,
|
||||||
|
"raw_sha256": "d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f",
|
||||||
|
"one_final_LF_removed_sha256": "9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881",
|
||||||
|
"existing_protocol": "PASS"
|
||||||
|
},
|
||||||
|
"q43_handoff_INDEX": {
|
||||||
|
"entries": 14,
|
||||||
|
"exact_raw_bytes_and_sha256": "PASS"
|
||||||
|
},
|
||||||
|
"pure_controls": [
|
||||||
|
{
|
||||||
|
"name": "negative",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "join",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "encoder",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "approval",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "candidate",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "series",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wrapper",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "full-suite-negatives",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "guard-mutations",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "UID",
|
||||||
|
"exit_code": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "power-adapter",
|
||||||
|
"exit_code": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "repair44",
|
||||||
|
"exit_code": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pure_results": {
|
||||||
|
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/REPAIR44_PURE_RESULTS.json",
|
||||||
|
"sha256": "4a702903f9d3189af50b68383cc5bc7829a7480b3a0199459e5b9b3ed710733e"
|
||||||
|
},
|
||||||
|
"new_controls": {
|
||||||
|
"source": "s5/repair44_controls.py",
|
||||||
|
"synthetic_only": true,
|
||||||
|
"paid_mutations_rejected": 17,
|
||||||
|
"roster_name_sync_probe_regex_self_check": "PASS",
|
||||||
|
"no_pyc": "PASS"
|
||||||
|
},
|
||||||
|
"not_run": [
|
||||||
|
"AST and explicit build-cfile py_compile on every touched Python file (stopped before this stage)",
|
||||||
|
"Check-only S1-S5 plan (stopped before this stage)",
|
||||||
|
"Fresh native S1-S5 and independent Reader",
|
||||||
|
"Fresh collect, full184, index, verify-only, registered validation, independent whole-unit review and integration"
|
||||||
|
],
|
||||||
|
"formal_acceptance": false
|
||||||
|
},
|
||||||
|
"compile_checks": [
|
||||||
{
|
{
|
||||||
"path": "tools/check_p04_order_evidence.py",
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_negative_fixtures.py",
|
||||||
"sha256": "5c8dd212fde1104f4090d7747fbaf6a5df4afcc69592be341965464b9a89262b",
|
"AST_exit_code": 0,
|
||||||
"AST": "PASS",
|
"py_compile_exit_code": 0,
|
||||||
"py_compile": "PASS"
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/11.pyc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py",
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py",
|
||||||
"sha256": "256c8978c879bd953733e0ca3dc807ae0edfc2f77e6c3e7eae4a93dc43e7dc1f",
|
"AST_exit_code": 0,
|
||||||
"AST": "PASS",
|
"py_compile_exit_code": 0,
|
||||||
"py_compile": "PASS"
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/12.pyc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_order_adapter.py",
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/repair44_controls.py",
|
||||||
"sha256": "f1404045b57c0d5cf37eef04f6adc16d5f7840c06410c014775bcee0ace7dab8",
|
"AST_exit_code": 0,
|
||||||
"AST": "PASS",
|
"py_compile_exit_code": 0,
|
||||||
"py_compile": "PASS"
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/16.pyc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_order_adapter_controls.py",
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py",
|
||||||
"sha256": "2771627b674f9b31c888559e1e04623a944a4bdb01c390278838197ca78fd8d3",
|
"AST_exit_code": 0,
|
||||||
"AST": "PASS",
|
"py_compile_exit_code": 0,
|
||||||
"py_compile": "PASS"
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/17.pyc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_guard_oracle.py",
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_order_adapter.py",
|
||||||
"sha256": "b58ee46f5c8a82de796bffd88ff8cab89f1f9e7e5c9417414310a1b649dc6c1c",
|
"AST_exit_code": 0,
|
||||||
"AST": "PASS",
|
"py_compile_exit_code": 0,
|
||||||
"py_compile": "PASS"
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/18.pyc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_power_adapter.py",
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_order_adapter_controls.py",
|
||||||
"sha256": "ba89ad5c07718fd0976712d6a0605aa72d64ac7276e9e7d350476203542c0b86",
|
"AST_exit_code": 0,
|
||||||
"AST": "PASS",
|
"py_compile_exit_code": 0,
|
||||||
"py_compile": "PASS"
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/19.pyc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_power_adapter.py",
|
||||||
|
"AST_exit_code": 0,
|
||||||
|
"py_compile_exit_code": 0,
|
||||||
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/20.pyc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "tools/check_p04_order_evidence.py",
|
||||||
|
"AST_exit_code": 0,
|
||||||
|
"py_compile_exit_code": 0,
|
||||||
|
"cfile": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/21.pyc"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"gdscript": {
|
"uid": {
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/p04_s5_power_probe.gd",
|
"name": "UID-repair45",
|
||||||
"sha256": "593de4376659873c0ef58c42dda0a77eedd1195e296cbf403b7289710896e7cf",
|
"argv": [
|
||||||
"probe_guard_regexes": [
|
"python3",
|
||||||
"\\bvar\\s+\\w+\\s*=",
|
"-B",
|
||||||
"\\bfor\\s+\\w+\\s+in\\b",
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_uid_controls.py",
|
||||||
"\\.(?:patience_remaining|elapsed_minutes|power_available|capacity|hold_until)\\s*=(?!=)"
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/build/owner-handoff/p04-after-p26-closure-r01/verified-m-engine-free-r45",
|
||||||
|
"--scratch",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/uid"
|
||||||
],
|
],
|
||||||
"result": "PASS",
|
"exit_code": 0,
|
||||||
"regex_negative_self_check": "PASS",
|
"stdout": "{\"accepted\": false, \"Root-only\": true, \"controls\": [\"positive\", \"extra\", \"original\", \"owner\", \"existing-collision\", \"generated-collision\", \"no-newline\", \"crlf\", \"uppercase\", \"too-long\", \"hardlink\", \"symlink\", \"missing\", \"post-seal-reports\"], \"uid_helper\": {\"helper_path\": \"tools/run_p13_reference_tests.py\", \"helper_sha256\": \"9adc8aa2a7662df8dd70386ddb0bff34574e44d7411de3b6128ddd15eb24675c\", \"helper_bytes\": 13957, \"functions\": {\"uid_plan\": \"c9b094e12e3ace11b4c81365d134f7a218dd73ca8e6501f5f860acd2af0e980d\", \"uid_snapshot\": \"2987194db9bcfaf781e25808c755a9d8c8b87cb7f57f92a8f8e4292c2823c4e9\"}, \"shared_module\": \"tools/run_all_tests.py\", \"shared_sha256\": \"320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4\"}, \"scratch\": \"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/uid\"}\n",
|
||||||
"case_table_static_dispatch": "PASS",
|
"stderr": ""
|
||||||
"cases": 9,
|
},
|
||||||
"slots": 21
|
"no_pyc": {
|
||||||
|
"exit_code": 0,
|
||||||
|
"files": [],
|
||||||
|
"scope": "execution/p04-01/**/*.pyc and tools/check_p04_order_evidence.py source only"
|
||||||
|
},
|
||||||
|
"check_only_initial_argument_refusals": [
|
||||||
|
{
|
||||||
|
"series": "s1",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s1/run_s1_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s1-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s1-native"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: fresh-q requires a full HEX40 triple without --historical-r17\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s2a",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s2/run_s2a_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2a-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2a-native"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: fresh-q requires a full HEX40 triple without --historical-r17\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s2b",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s2b/run_s2b_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2b-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2b-native"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: fresh-q requires a full HEX40 triple without --historical-r17\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s3",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s3/run_s3_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s3-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s3-native"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: fresh-q requires a full HEX40 triple without --historical-r17\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s4",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s4-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s4-native"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: fresh-q requires a full HEX40 triple without --historical-r17\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s5",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s5-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s5-native"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: fresh-q requires a full HEX40 triple without --historical-r17\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"check_only": {
|
||||||
|
"tree_argument_scope": "Actual HEAD tree only; W is dirty, not a final Q or C claim",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"series": "s1",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s1/run_s1_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s1-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s1-native",
|
||||||
|
"--tested-tree",
|
||||||
|
"af5256155815214dc73620d5a2ad04cbcd139274"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: checkout is not clean\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s2a",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s2/run_s2a_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2a-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2a-native",
|
||||||
|
"--tested-tree",
|
||||||
|
"af5256155815214dc73620d5a2ad04cbcd139274"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: checkout is not clean\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s2b",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s2b/run_s2b_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2b-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s2b-native",
|
||||||
|
"--tested-tree",
|
||||||
|
"af5256155815214dc73620d5a2ad04cbcd139274"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: checkout is not clean\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s3",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s3/run_s3_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s3-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s3-native",
|
||||||
|
"--tested-tree",
|
||||||
|
"af5256155815214dc73620d5a2ad04cbcd139274"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: checkout is not clean\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s4",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s4-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s4-native",
|
||||||
|
"--tested-tree",
|
||||||
|
"af5256155815214dc73620d5a2ad04cbcd139274"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: checkout is not clean\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"series": "s5",
|
||||||
|
"argv": [
|
||||||
|
"python3",
|
||||||
|
"-B",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py",
|
||||||
|
"--project-root",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement",
|
||||||
|
"--main",
|
||||||
|
"c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"--submission",
|
||||||
|
"eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97",
|
||||||
|
"--check-only",
|
||||||
|
"--plan",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s5-plan.json",
|
||||||
|
"--output",
|
||||||
|
"/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/repair45-1792309312161922000/s5-native",
|
||||||
|
"--tested-tree",
|
||||||
|
"af5256155815214dc73620d5a2ad04cbcd139274"
|
||||||
|
],
|
||||||
|
"exit_code": 2,
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "ValueError: checkout is not clean\n"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"retained_passes": "REPAIR44 roster positives/negatives, all-consumer name-sync, probe_guard regex self-check, 17 paid-before-incident mutations; no source changed in REPAIR45",
|
||||||
|
"pure_results": {
|
||||||
|
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/REPAIR44_PURE_RESULTS.json",
|
||||||
|
"sha256": "569063467403bd004ff5b342486a822bba430f6e81a3e8081ed44cb50d23e5dd"
|
||||||
},
|
},
|
||||||
"formal_acceptance": false,
|
"formal_acceptance": false,
|
||||||
"pure_controls": [
|
"not_run": [
|
||||||
{
|
"Clean exact-Q check-only after automatic submission (Root)",
|
||||||
"name": "negative",
|
"Fresh native S1-S4 and ten S5 cases; independent Reader and fresh order positives",
|
||||||
"exit_code": 0
|
"Fresh adapters/collect/full184/index/verify-only/registered validation/independent whole-unit review/integration"
|
||||||
},
|
]
|
||||||
{
|
|
||||||
"name": "join",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "encoder",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "approval",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "candidate",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "series",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "wrapper",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "full-suite-negatives",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "guard-mutations",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "UID",
|
|
||||||
"exit_code": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "power-adapter",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "UID-M-source-subset",
|
|
||||||
"exit_code": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "guard-mutations-final",
|
|
||||||
"exit_code": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pure_results": {
|
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/REPAIR43_PURE_RESULTS.json",
|
|
||||||
"sha256": "4fb424248b987e333f7fe0edf5621929338baa4547432f41c6cd06f5822e468b"
|
|
||||||
},
|
|
||||||
"spec_protocol_controls": [
|
|
||||||
{
|
|
||||||
"case": "canonical_without_LF",
|
|
||||||
"accepted": true,
|
|
||||||
"expected": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "tracked_single_LF",
|
|
||||||
"accepted": true,
|
|
||||||
"expected": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "double_final_LF",
|
|
||||||
"accepted": false,
|
|
||||||
"expected": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "CRLF_final",
|
|
||||||
"accepted": false,
|
|
||||||
"expected": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "BOM",
|
|
||||||
"accepted": false,
|
|
||||||
"expected": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"case": "interior_mutation",
|
|
||||||
"accepted": false,
|
|
||||||
"expected": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"step0_raw_hash_comparisons": {
|
|
||||||
"entries": 118,
|
|
||||||
"result": "PASS",
|
|
||||||
"report": "docs/plans/original-completion-2026-10-02/execution/p04-01/REPAIR43_PRECHECK.json",
|
|
||||||
"sha256": "e092c7aa702dfdbaf66ef70b9f50afc5088dfb5e25f491c4332c242113e80bba"
|
|
||||||
},
|
|
||||||
"UID_input_resolution": "Initial base-checkout missing helper; exact M source-subset retry passed all 14 pure helper controls. No Q/native applicability claim.",
|
|
||||||
"Root_pending": [
|
|
||||||
"Fresh S1-S5 check-only plans, capacity, native/Reader/order raw positives and raw-dependent mutations",
|
|
||||||
"Fresh collect, full suite, index, verify-only, registered validation, independent whole-unit review, normal integration"
|
|
||||||
],
|
|
||||||
"source_facts": {
|
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/REPAIR43_SOURCE_FACTS.json",
|
|
||||||
"sha256": "fcf2c795d239f9c11e8d3f54ba9f57c7f895f08af43788d8814e0ab455ffb49d"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,136 @@
|
|||||||
# REPAIR41 history and REPAIR42/43 status
|
# REPAIR41 history and REPAIR45 status
|
||||||
|
|
||||||
|
## REPAIR45 — implementation ready for submission
|
||||||
|
|
||||||
|
The supplied byte-verified M engine-free context resolved the REPAIR44 UID dependency.
|
||||||
|
UID controls: all 14 PASS, exit 0. Both supplied helper SHA-256 pins match exactly.
|
||||||
|
AST and explicit fresh BUILD-cfile py_compile passed for all eight touched Python
|
||||||
|
files, with python3 -B and PYTHONDONTWRITEBYTECODE=1. No source was changed in
|
||||||
|
REPAIR45; retained passing controls were not rerun. The no-pyc static check
|
||||||
|
passed again (exit 0); generated compile files exist only under allocated BUILD.
|
||||||
|
The prior UID failure remains recorded as failed, not replaced with a PASS.
|
||||||
|
|
||||||
|
Sequential check-only S1, S2a, S2b, S3, S4 and S5 each returned exit 2:
|
||||||
|
`ValueError: checkout is not clean`
|
||||||
|
The initial missing-tested-tree argument refusals are also retained. The later
|
||||||
|
attempt used the actual HEAD tree solely as a guard input, not a claim of final
|
||||||
|
Q, clean source or C. No engine started. Root executes clean exact-Q check-only
|
||||||
|
after automatic submission. Full argv/stdout/stderr and compile paths are in
|
||||||
|
REPAIR41_STATIC_CHECKS.json. No Git writes, Runner or native run were performed.
|
||||||
|
|
||||||
|
Implementation is ready; the whole original unit remains incomplete and P04
|
||||||
|
credit remains 0. Deferred Root conditions, in order: freeze final Q; affected
|
||||||
|
pure controls; clean exact-Q check-only; capacity check; one heavy lease with
|
||||||
|
fresh native S1–S4 and all ten S5 cases; independent Reader and adapters on actual
|
||||||
|
raw (including fresh Reader order positives); fresh collect; full 184 suite once;
|
||||||
|
index; --verify-only; registered validation before review; independent whole-unit
|
||||||
|
Opus review; normal prepare / exact C / integration / final / Root DB join /
|
||||||
|
ledger / main push. Native Reader and acceptance remain pending.
|
||||||
|
patience_release stays pending unless fresh S3 raw shows it. Product freeze,
|
||||||
|
M, allowed paths, REQUIRED membership/thresholds, all seven domains, G1/G2,
|
||||||
|
R40–R44 and the existing one-trailing-LF spec protocol remain unchanged.
|
||||||
|
|
||||||
|
|
||||||
|
## REPAIR44
|
||||||
|
|
||||||
|
**Worker stopped: unreadable required check dependency.** The UID pure control
|
||||||
|
cannot read `/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r43-eb94e1d7/tools/run_all_tests.py`:
|
||||||
|
`PermissionError: [Errno 1] Operation not permitted`. REPAIR44 explicitly requires
|
||||||
|
stopping for an actually unreadable file. No permission bypass or alternate
|
||||||
|
positive is claimed. REPAIR44_PURE_RESULTS.json retains the failed invocation.
|
||||||
|
Eleven other pure programs completed successfully (including the new 17 paid
|
||||||
|
mutation negatives and roster/name-sync/regex/no-pyc controls). The already
|
||||||
|
launched sequential batch finished power-adapter and repair44 controls after
|
||||||
|
the UID failure; these results are recorded within their limited scope.
|
||||||
|
AST/build-cfile compilation of all touched Python files and check-only S1–S5
|
||||||
|
were not reached. The implementation below is work in progress, not a completed
|
||||||
|
REPAIR44 submission. Resume requires a readable verified check dependency.
|
||||||
|
|
||||||
|
Same original unit, W and submitted S=eb94e1d7dbae3b0be84171b4ef0024b4f6b0ae97;
|
||||||
|
M=c0ea009b28a7649aca6a433a1a24dc0be5e7ab81. No reset or new counted work.
|
||||||
|
Original whole unit remains incomplete, formal 16/88, P04 credit 0.
|
||||||
|
R43 import/parse/Writer passed (2749/0), then run_s5_native.py:525 compared
|
||||||
|
sorted receipt branches to insertion-order CASES. G/H preceded E/F; all nine
|
||||||
|
cases were present but Reader never started. R43 native remains FAILED,
|
||||||
|
alongside r35/r36/R40 native. Q37 remains its own-version local PASS only.
|
||||||
|
Seven Writer-only typed derivers/G1/G2 and twelve pure/six check-only passes
|
||||||
|
are not independent Reader, replay or acceptance.
|
||||||
|
|
||||||
|
The canonical wrapper roster is now sorted(CASE_TABLE). LABELS, SLOTS and
|
||||||
|
receipt comparisons derive from it, with exact lengths, uniqueness and set
|
||||||
|
membership. Reader independently enumerates CASE_TABLE. The new pure controls
|
||||||
|
reproduce the old failure, accept insertion/reverse order and reject missing,
|
||||||
|
duplicate or unknown cases and missing/extra/duplicate slots. The ten cases are
|
||||||
|
`S5A_PURE`, `S5B_DEPENDENCY`, `S5C_DESTRUCTION_COMMAND`, `S5D_DESTRUCTION_RAID`,
|
||||||
|
`S5D_IN_FLIGHT`, `S5D_PAID_BEFORE_INCIDENT`, `S5E_MIDNIGHT`, `S5F_EXIT`,
|
||||||
|
`S5G_SHIFT_1080`, `S5H_PAUSED_MIDNIGHT`.
|
||||||
|
|
||||||
|
New fixture: primary queues at N-duration-1, starts at N-duration and completes
|
||||||
|
at N. Secondary queues at N-2 and starts at N-1, holding its own reservation;
|
||||||
|
two meals are stocked through _stock. Cafeteria definition capacity=12 (line22),
|
||||||
|
staff_min=2 (line18), base_service_minutes=45 (line24), base_price=25 (line26),
|
||||||
|
inventory_inputs=one meal (line27), exact file sha256
|
||||||
|
86d540fe2d78b9dcdbe5a0af6e4a001f4cec54934636ed01deb25a943c79128a.
|
||||||
|
Staff setup derives staff_min; prices/duration subsequently bind to the primary
|
||||||
|
service snapshot. Capacity permits the concurrent secondary; no product value
|
||||||
|
is changed. Seed 420558 is a distinct deterministic fixture seed following the
|
||||||
|
existing 42055x private-QA family, not a product RNG policy change.
|
||||||
|
|
||||||
|
M source proof (full bodies, file hashes and line ranges in
|
||||||
|
REPAIR44_SOURCE_FACTS.json): simulation_kernel.advance_one_minute line122,
|
||||||
|
body sha b9587ef722d8c8640248025462819374ae5eca1c3d8bbe600b6bc9c328567777,
|
||||||
|
runs FACILITY_COMPLETION, VITALS_AND_ENVIRONMENT, INCIDENTS_AND_EVENTS,
|
||||||
|
FACILITY_QUEUES in that order. _run_phase line236, body sha
|
||||||
|
52461eeb288892a4bb4b6a99570185af08a30758ef88b0046a911baaa6f318e1,
|
||||||
|
emits phase-start observations before handlers; therefore completion is
|
||||||
|
observed as ACTIVE at FACILITY_COMPLETION start and COMPLETED with one receipt
|
||||||
|
at VITALS_AND_ENVIRONMENT start. Receipt phase is FACILITY_COMPLETION.
|
||||||
|
Runtime registers the handlers at lines400–428. _advance_relationship_events
|
||||||
|
line8637, body sha 20ca7abfdcbbc914f91545c3eded46e3e87035ff4153541ffcbf92471b02b03f,
|
||||||
|
starts the queued automatic event in INCIDENTS_AND_EVENTS. Public registration
|
||||||
|
and enqueue functions are at lines6878/6887 (full hashes in the source facts).
|
||||||
|
_validate_event_action line9991, body sha
|
||||||
|
83e0cce3b59244440b11acdee6f87dd521859701769b1689ff2775db5c92c5f5,
|
||||||
|
allows SET_FACILITY_STATE for this non-Defense-owned facility. _apply_event_action
|
||||||
|
line10040, body sha d79e7aca02eed06f500ffc632c6160cd80d76c3d7c5c90dc097f71b60380d365,
|
||||||
|
calls set_operational_status with durability=0 and suspension_reason=DESTROYED.
|
||||||
|
The fixture never registers the busy facility as a Defense asset and expects no
|
||||||
|
guard. FacilityService.start_next_service line449 (body sha
|
||||||
|
2eb1cf1226fb1496b6b96c39184ad6a767b4fde747923df599097372435ffa4c) checks the
|
||||||
|
actual instance capacity and starts secondary work with ordinary active staff.
|
||||||
|
ServiceInstance.mark_failed line128 stores completed_at for failure timing,
|
||||||
|
body sha 178c6879e64385f0e3ff99fa98ae6ceb4dc67f6c2c981b0effb229f5d4d647fa.
|
||||||
|
|
||||||
|
The independent adapter retains payment/release/sales/phase helpers. It proves
|
||||||
|
the pre-completion state, single typed receipt/Runtime-ledger/idempotency joins,
|
||||||
|
surviving identical boundary/held sale, one primary wallet debit, financial day
|
||||||
|
from ledger absolute_minute, positive pre-event durability and BROKEN/DESTROYED
|
||||||
|
afterward. Secondary stays active/reserved through N and fails/releases once at
|
||||||
|
N+1 with unchanged wallet, no remaining request/reservation or generated service.
|
||||||
|
The checker adds this raw-recomputed sub-gate inside D05-P04-DESTRUCTION.
|
||||||
|
All previous gates and REQUIRED names/thresholds stay intact. Pure mutations
|
||||||
|
cover every requested failure, including AFTER-copy; they are serializer units,
|
||||||
|
not substitutes for fresh native Writer/Reader raw.
|
||||||
|
|
||||||
|
The six explicitly named __pycache__/*.repair43.pyc were read, byte sizes,
|
||||||
|
headers and SHA-256 inspected, then deleted; no source/evidence was deleted.
|
||||||
|
Execution-scope .gitignore now excludes __pycache__/ and *.pyc. Python checks
|
||||||
|
use -B and explicit py_compile cfile under allocated build. The static control
|
||||||
|
rejects any remaining *.pyc in the allowed execution tree.
|
||||||
|
|
||||||
|
All existing R40–R43 cases, G1/G2 shadow oracle and negatives, R41 diagnostic,
|
||||||
|
historical/fresh S4 pin separation, 43+ controls and the Step 0 table below are
|
||||||
|
preserved. Product source/values/guards, permissions, billing, all seven domains
|
||||||
|
and 15+EV thresholds are unchanged. Approval raw SHA-256 exactly matches
|
||||||
|
cd365ded1b777a0327d090709f0a4161f5005562819183455d9f2e106fba3e96.
|
||||||
|
The spec raw is 7000 bytes, sha
|
||||||
|
d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f;
|
||||||
|
stripping exactly its one final LF gives the registered
|
||||||
|
9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881.
|
||||||
|
This is the existing spec-only EOF protocol; all other hashes compare raw bytes.
|
||||||
|
REPAIR41_STATIC_CHECKS.json records actual worker checks only. Native Reader,
|
||||||
|
formal acceptance and patience_release remain pending (the last needs fresh S3).
|
||||||
|
Root freezes final Q and follows the twelve steps in s5/S5_ROOT_RUN.md.
|
||||||
|
|
||||||
## REPAIR42/43 implementation submission
|
## REPAIR42/43 implementation submission
|
||||||
|
|
||||||
|
|||||||
+169
File diff suppressed because one or more lines are too long
+131
@@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"M": "c0ea009b28a7649aca6a433a1a24dc0be5e7ab81",
|
||||||
|
"files": {
|
||||||
|
"scripts/core/simulation_kernel.gd": {
|
||||||
|
"sha256": "341c0c878c4894adbac628d0db6362ff69fc3347bdd9e61e50936e15dc2d1edb",
|
||||||
|
"bytes": 7602,
|
||||||
|
"functions": {
|
||||||
|
"advance_one_minute": {
|
||||||
|
"line": 122,
|
||||||
|
"end_line": 158,
|
||||||
|
"sha256": "b9587ef722d8c8640248025462819374ae5eca1c3d8bbe600b6bc9c328567777",
|
||||||
|
"body": "func advance_one_minute() -> void:\n\t_abort_current_tick_requested = false\n\t_last_tick_advanced = false\n\ttick_started.emit(absolute_minute)\n\t_run_phase(TickPhase.APPLY_COMMANDS)\n\t# A Runtime gate can reject the tick before the Clock changes. This is\n\t# distinct from an ordinary pause raised by a command that already committed\n\t# for the upcoming minute.\n\tif _abort_current_tick_requested:\n\t\t_abort_current_tick_requested = false\n\t\treturn\n\n\tvar previous_absolute_minute := absolute_minute\n\tabsolute_minute += 1\n\t_sync_calendar_fields()\n\t_handle_time_boundaries(previous_absolute_minute)\n\t_run_phase(TickPhase.TIME_BOUNDARIES)\n\n\tfor phase in [\n\t\tTickPhase.MANA,\n\t\tTickPhase.CONSTRUCTION,\n\t\tTickPhase.LOGISTICS,\n\t\tTickPhase.FACILITY_COMPLETION,\n\t\tTickPhase.VITALS_AND_ENVIRONMENT,\n\t\tTickPhase.INCIDENTS_AND_EVENTS,\n\t\tTickPhase.FACILITY_QUEUES,\n\t\tTickPhase.AI_DECISIONS,\n\t\tTickPhase.PUBLISH_SNAPSHOT,\n\t]:\n\t\t_run_phase(phase)\n\n\tsnapshot_version += 1\n\ttick_completed.emit(absolute_minute)\n\t_emit_current_time()\n\t_abort_current_tick_requested = false\n\t_last_tick_advanced = true\n\n"
|
||||||
|
},
|
||||||
|
"_run_phase": {
|
||||||
|
"line": 236,
|
||||||
|
"end_line": 249,
|
||||||
|
"sha256": "52461eeb288892a4bb4b6a99570185af08a30758ef88b0046a911baaa6f318e1",
|
||||||
|
"body": "func _run_phase(phase: TickPhase) -> void:\n\ttick_phase_started.emit(phase, absolute_minute)\n\tif not _phase_handlers.has(phase):\n\t\treturn\n\tvar handlers: Dictionary = _phase_handlers[phase]\n\tvar handler_ids: Array = handlers.keys()\n\thandler_ids.sort_custom(func(left: Variant, right: Variant) -> bool:\n\t\treturn String(left) < String(right)\n\t)\n\tfor handler_id: Variant in handler_ids:\n\t\tvar callback: Callable = handlers[handler_id]\n\t\tif callback.is_valid():\n\t\t\tcallback.call(absolute_minute)\n\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload/simulation_runtime.gd": {
|
||||||
|
"sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0",
|
||||||
|
"bytes": 616434,
|
||||||
|
"functions": {
|
||||||
|
"_execute_register_event_definition": {
|
||||||
|
"line": 6878,
|
||||||
|
"end_line": 6886,
|
||||||
|
"sha256": "6c271786ca52115a233f9c3ad2d19f93ef101f2da533672118165757aac3347d",
|
||||||
|
"body": "func _execute_register_event_definition(command: SimulationCommand) -> CommandResult:\n\tvar raw_definition: Variant = command.payload.get(&\"definition\", command.payload.get(\"definition\", null))\n\tvar definition := EventDefinition.from_variant(raw_definition)\n\tif definition == null:\n\t\treturn CommandResult.failed(CommandResult.Code.INVALID_PAYLOAD, command.command_id, \"Event definition is malformed.\")\n\tvar result := event_service.register_definition(definition)\n\tresult.command_id = command.command_id\n\treturn result\n\n"
|
||||||
|
},
|
||||||
|
"_execute_enqueue_event": {
|
||||||
|
"line": 6887,
|
||||||
|
"end_line": 6895,
|
||||||
|
"sha256": "5e5d5fb5e225dbcb09aeb2addb92c0011965c7e8f6b12cda91ca05d98e240c08",
|
||||||
|
"body": "func _execute_enqueue_event(command: SimulationCommand) -> CommandResult:\n\tvar event_id := StringName(command.payload.get(&\"event_id\", command.payload.get(\"event_id\", \"\")))\n\tvar actor_ids := _name_array(command.payload.get(&\"actor_ids\", command.payload.get(\"actor_ids\", [])))\n\tvar raw_options: Variant = command.payload.get(&\"options\", command.payload.get(\"options\", {}))\n\tvar options: Dictionary = raw_options.duplicate(true) if raw_options is Dictionary else {}\n\tvar result := event_service.enqueue_candidate(event_id, actor_ids, _runtime_event_minute(), options)\n\tresult.command_id = command.command_id\n\treturn result\n\n"
|
||||||
|
},
|
||||||
|
"_advance_relationship_events": {
|
||||||
|
"line": 8637,
|
||||||
|
"end_line": 8655,
|
||||||
|
"sha256": "20ca7abfdcbbc914f91545c3eded46e3e87035ff4153541ffcbf92471b02b03f",
|
||||||
|
"body": "func _advance_relationship_events(absolute_minute: int) -> void:\n\tif _operations_tick_blocked:\n\t\treturn\n\tif _operations_morning_already_processed(absolute_minute):\n\t\treturn\n\tevent_service.process_expired(absolute_minute)\n\tevent_service.audit_actor_availability(absolute_minute)\n\t_enqueue_pending_relationship_candidates()\n\tif event_service.get_foreground_instance() == null:\n\t\tvar started := event_service.start_next_event(\n\t\t\tabsolute_minute,\n\t\t\t_build_event_context(absolute_minute)\n\t\t)\n\t\tif started.is_success() and bool(started.details.get(&\"waiting_for_choice\", false)):\n\t\t\t_clock.set_paused(true)\n\tif event_service.pause_requested:\n\t\t_clock.set_paused(true)\n\n\n"
|
||||||
|
},
|
||||||
|
"_validate_event_action": {
|
||||||
|
"line": 9991,
|
||||||
|
"end_line": 10039,
|
||||||
|
"sha256": "83e0cce3b59244440b11acdee6f87dd521859701769b1689ff2775db5c92c5f5",
|
||||||
|
"body": "func _validate_event_action(action: EventAction) -> Dictionary:\n\tmatch action.type:\n\t\tEventAction.Type.ADD_LEDGER_ENTRY:\n\t\t\tvar from_account := StringName(action.payload.get(&\"from_account\", action.payload.get(\"from_account\", PLAYER_CASH_ACCOUNT)))\n\t\t\tvar to_account := StringName(action.payload.get(&\"to_account\", action.payload.get(\"to_account\", OPERATING_EXPENSE_ACCOUNT)))\n\t\t\tvar amount := int(action.payload.get(&\"amount\", action.payload.get(\"amount\", 0)))\n\t\t\tif amount <= 0 or not economy_service.has_account(from_account) or not economy_service.has_account(to_account):\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Ledger Action has invalid accounts or amount.\"}\n\t\t\tif not economy_service.account_allows_negative(from_account) and economy_service.get_balance(from_account) < amount:\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Ledger Action source cannot fund the amount.\"}\n\t\tEventAction.Type.ADD_OR_REMOVE_ITEM:\n\t\t\tvar inventory_id := StringName(action.payload.get(&\"inventory_id\", action.payload.get(\"inventory_id\", \"\")))\n\t\t\tvar item_id := StringName(action.payload.get(&\"item_id\", action.payload.get(\"item_id\", \"\")))\n\t\t\tvar delta := int(action.payload.get(&\"quantity_delta\", action.payload.get(\"quantity_delta\", 0)))\n\t\t\tif inventory_id.is_empty() or item_id.is_empty() or delta == 0:\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Inventory Action requires inventory, item and non-zero delta.\"}\n\t\t\tif delta < 0 and inventory_service.available_quantity(inventory_id, item_id) < -delta:\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Inventory Action stock is unavailable.\"}\n\t\tEventAction.Type.CREATE_TASK:\n\t\t\tif StringName(action.payload.get(&\"task_type\", action.payload.get(\"task_type\", \"\"))).is_empty():\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"CREATE_TASK requires task_type.\"}\n\t\tEventAction.Type.SET_FACILITY_STATE:\n\t\t\tvar facility_id := StringName(action.payload.get(&\"facility_id\", action.payload.get(\"facility_id\", \"\")))\n\t\t\tvar conditions_value: Variant = action.payload.get(&\"conditions\", action.payload.get(\"conditions\", null))\n\t\t\tif not facility_service.has_instance(facility_id) or not conditions_value is Dictionary:\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Facility Action target or conditions are invalid.\"}\n\t\t\tvar defense_owner: StringName = _defense_lock_owner(facility_id, &\"ASSET\")\n\t\t\tif not defense_owner.is_empty() \\\n\t\t\t\t\tand (conditions_value.has(&\"durability\") or conditions_value.has(\"durability\")):\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Event Action cannot mutate Defense-owned Facility durability.\"}\n\t\tEventAction.Type.TELEPORT_ENTITY_FOR_RECOVERY:\n\t\t\tvar entity_id := StringName(action.payload.get(&\"entity_id\", action.payload.get(\"entity_id\", \"\")))\n\t\t\tvar cell_value: Variant = _parse_world_cell(\n\t\t\t\taction.payload.get(&\"cell\", action.payload.get(\"cell\", null))\n\t\t\t)\n\t\t\tif not _event_actor_exists(entity_id) or cell_value == null:\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Recovery teleport target is invalid.\"}\n\t\t\tvar target_cell: Vector3i = cell_value\n\t\t\tvar traffic := path_service.get_cell_traffic(target_cell)\n\t\t\tvar actor_id := (\n\t\t\t\t_guest_path_actor_id(entity_id)\n\t\t\t\tif guest_service.has_guest(entity_id)\n\t\t\t\telse _staff_path_actor_id(entity_id)\n\t\t\t)\n\t\t\tif traffic.is_empty() or bool(traffic.get(&\"temporary_block\", false)) \\\n\t\t\t\t\tor not path_service.has_actor_projection(actor_id):\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Recovery teleport requires a projected actor and an unblocked walkable target.\"}\n\treturn {&\"ok\": true}\n\n"
|
||||||
|
},
|
||||||
|
"_apply_event_action": {
|
||||||
|
"line": 10040,
|
||||||
|
"end_line": 10123,
|
||||||
|
"sha256": "d79e7aca02eed06f500ffc632c6160cd80d76c3d7c5c90dc097f71b60380d365",
|
||||||
|
"body": "func _apply_event_action(action: EventAction, context: Dictionary) -> Dictionary:\n\tvar instance_id := StringName(context.get(&\"event_instance_id\", \"\"))\n\tmatch action.type:\n\t\tEventAction.Type.CREATE_DEFENSE_RAID:\n\t\t\treturn _apply_event_defense_raid(action, context)\n\t\tEventAction.Type.ADD_LEDGER_ENTRY:\n\t\t\tvar from_account := StringName(action.payload.get(&\"from_account\", action.payload.get(\"from_account\", PLAYER_CASH_ACCOUNT)))\n\t\t\tvar to_account := StringName(action.payload.get(&\"to_account\", action.payload.get(\"to_account\", OPERATING_EXPENSE_ACCOUNT)))\n\t\t\tvar amount := int(action.payload.get(&\"amount\", action.payload.get(\"amount\", 0)))\n\t\t\tvar result := economy_service.transfer(\n\t\t\t\tfrom_account, to_account, amount, _runtime_event_minute(),\n\t\t\t\t&\"EVENT_ACTION\", instance_id,\n\t\t\t\tStringName(\"event.action.%s.%s\" % [instance_id, action.action_id])\n\t\t\t)\n\t\t\treturn {&\"ok\": result.is_success(), &\"error\": result.message}\n\t\tEventAction.Type.ADD_OR_REMOVE_ITEM:\n\t\t\tvar inventory_id := StringName(action.payload.get(&\"inventory_id\", action.payload.get(\"inventory_id\", \"\")))\n\t\t\tvar item_id := StringName(action.payload.get(&\"item_id\", action.payload.get(\"item_id\", \"\")))\n\t\t\tvar delta := int(action.payload.get(&\"quantity_delta\", action.payload.get(\"quantity_delta\", 0)))\n\t\t\tif delta > 0:\n\t\t\t\tvar added := inventory_service.add_stack(inventory_id, item_id, delta, 100, -1, _runtime_event_minute())\n\t\t\t\treturn {&\"ok\": bool(added.get(&\"ok\", false)), &\"error\": added.get(&\"message\", \"\")}\n\t\t\tvar reserved := inventory_service.reserve_item(\n\t\t\t\tinventory_id, item_id, -delta, instance_id, &\"event_action\",\n\t\t\t\t_runtime_event_minute(), _runtime_event_minute() + 1,\n\t\t\t\tStringName(\"event.item.reserve.%s.%s\" % [instance_id, action.action_id])\n\t\t\t)\n\t\t\tif not bool(reserved.get(&\"ok\", false)):\n\t\t\t\treturn {&\"ok\": false, &\"error\": reserved.get(&\"message\", \"Item reservation failed.\")}\n\t\t\tvar consumed := inventory_service.consume_reservations(\n\t\t\t\t_name_array(reserved.get(&\"reservation_ids\", [])),\n\t\t\t\tStringName(\"event.item.consume.%s.%s\" % [instance_id, action.action_id]),\n\t\t\t\t_runtime_event_minute()\n\t\t\t)\n\t\t\treturn {&\"ok\": bool(consumed.get(&\"ok\", false)), &\"error\": consumed.get(&\"message\", \"\")}\n\t\tEventAction.Type.CREATE_TASK:\n\t\t\tvar raw_options: Variant = action.payload.get(&\"options\", action.payload.get(\"options\", {}))\n\t\t\tvar options: Dictionary = raw_options.duplicate(true) if raw_options is Dictionary else {}\n\t\t\tvar created := staff_service.create_task(\n\t\t\t\tStringName(action.payload.get(&\"task_type\", action.payload.get(\"task_type\", \"\"))),\n\t\t\t\tint(action.payload.get(&\"priority\", action.payload.get(\"priority\", 50))),\n\t\t\t\t_runtime_event_minute(),\n\t\t\t\toptions,\n\t\t\t\tStringName(action.payload.get(&\"task_id\", action.payload.get(\"task_id\", \"\")))\n\t\t\t)\n\t\t\treturn {&\"ok\": created.is_success(), &\"error\": created.message}\n\t\tEventAction.Type.SET_FACILITY_STATE:\n\t\t\tvar updated := facility_service.set_operational_status(\n\t\t\t\tStringName(action.payload.get(&\"facility_id\", action.payload.get(\"facility_id\", \"\"))),\n\t\t\t\taction.payload.get(&\"conditions\", action.payload.get(\"conditions\", {})),\n\t\t\t\t_runtime_event_minute()\n\t\t\t)\n\t\t\treturn {&\"ok\": updated.is_success(), &\"error\": updated.message}\n\t\tEventAction.Type.TELEPORT_ENTITY_FOR_RECOVERY:\n\t\t\tvar entity_id := StringName(action.payload.get(&\"entity_id\", action.payload.get(\"entity_id\", \"\")))\n\t\t\tvar cell: Vector3i = _parse_world_cell(action.payload.get(&\"cell\", action.payload.get(\"cell\", null)))\n\t\t\tvar guest := guest_service.get_guest(entity_id)\n\t\t\tvar actor_id: StringName\n\t\t\tvar moved := false\n\t\t\tif guest != null:\n\t\t\t\tactor_id = _guest_path_actor_id(entity_id)\n\t\t\t\tmoved = guest_service.record_path_success(\n\t\t\t\t\tentity_id, cell, _runtime_event_minute()\n\t\t\t\t)\n\t\t\telse:\n\t\t\t\tvar staff := staff_service.get_staff(entity_id)\n\t\t\t\tactor_id = _staff_path_actor_id(entity_id)\n\t\t\t\tstaff.current_cell = cell\n\t\t\t\tmoved = true\n\t\t\tif not moved or not path_service.project_actor_position(\n\t\t\t\tactor_id, cell, _runtime_event_minute()\n\t\t\t):\n\t\t\t\treturn {&\"ok\": false, &\"error\": \"Recovery teleport could not commit its Path projection.\"}\n\t\t\t_movement_credits[actor_id] = {\n\t\t\t\t&\"credit\": 0,\n\t\t\t\t&\"updated_at\": _runtime_event_minute(),\n\t\t\t}\n\t\t\t_publish_actor_event(&\"ENTITY_RECOVERY_TELEPORTED\", &\"event_service\", [entity_id, actor_id], {\n\t\t\t\t&\"cell\": cell,\n\t\t\t\t&\"path_actor_id\": actor_id,\n\t\t\t})\n\t\t\treturn {&\"ok\": true}\n\treturn {&\"ok\": false, &\"error\": \"Unsupported Event Action.\"}\n\n"
|
||||||
|
},
|
||||||
|
"_advance_facilities": {
|
||||||
|
"line": 8504,
|
||||||
|
"end_line": 8509,
|
||||||
|
"sha256": "f1efd0c23bdd60d1ef19a21879640b53b8b4d88844c0c881fe7cd724387ec274",
|
||||||
|
"body": "func _advance_facilities(absolute_minute: int) -> void:\n\tif _operations_tick_blocked:\n\t\treturn\n\tfacility_service.advance_one_minute(absolute_minute)\n\tkitchen_production.advance_one_minute(absolute_minute)\n\n"
|
||||||
|
},
|
||||||
|
"_process_tick_commands": {
|
||||||
|
"line": 5765,
|
||||||
|
"end_line": 5775,
|
||||||
|
"sha256": "9de66a4bb84b12304300d49085f44546412319bd4aee91e67b61becf97e50294",
|
||||||
|
"body": "func _process_tick_commands(current_absolute_minute: int) -> void:\n\tif _operations_enabled:\n\t\t_operations_tick_blocked = _operations_should_block_tick()\n\t\tif _operations_tick_blocked:\n\t\t\t_clock.set_paused(true)\n\t\t\t_clock.request_current_tick_abort()\n\t\t\treturn\n\t_process_commands(current_absolute_minute + 1)\n\t_synchronize_operations_population()\n\n\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts/facility/facility_service.gd": {
|
||||||
|
"sha256": "ceb4a3e9224587423f273cdb2b56e6843ab176ac1fc4fe79dd498b5ed5c33b77",
|
||||||
|
"bytes": 44951,
|
||||||
|
"functions": {
|
||||||
|
"start_next_service": {
|
||||||
|
"line": 449,
|
||||||
|
"end_line": 524,
|
||||||
|
"sha256": "2eb1cf1226fb1496b6b96c39184ad6a767b4fde747923df599097372435ffa4c",
|
||||||
|
"body": "func start_next_service(\n\tinstance_id: StringName,\n\tabsolute_minute: int = -1,\n\tvalidator: Callable = Callable()\n) -> CommandResult:\n\tvar instance := get_instance(instance_id)\n\tif instance == null:\n\t\treturn _not_found(\"Facility instance\", instance_id)\n\tvar minute := _resolve_minute(absolute_minute)\n\t_resolve_operating_dependency(instance_id, minute, {}, {})\n\tinstance.apply_pending_policy(minute)\n\tvar old_state := instance.state\n\tinstance.evaluate_state(minute)\n\t_emit_state_change(instance, old_state)\n\tif not instance.can_start_service(minute):\n\t\treturn _invalid(\n\t\t\t\"Facility cannot start a service in its current state.\",\n\t\t\t{\n\t\t\t\t&\"instance_id\": instance_id,\n\t\t\t\t&\"state\": FacilityInstanceType.State.keys()[instance.state],\n\t\t\t\t&\"reasons\": instance.state_reasons.duplicate(),\n\t\t\t}\n\t\t)\n\t_cleanup_missing_queue_requests(instance)\n\tif instance.queue_entries.is_empty():\n\t\treturn _not_found(\"Queued service request\", &\"\")\n\tvar request := get_request(instance.queue_entries[0])\n\tif request == null:\n\t\treturn _invalid(\"The next queue entry is corrupt.\")\n\tif not instance.can_accept_customers(request.guest_ids):\n\t\treturn _invalid(\"Simultaneous customer limit reached.\", {&\"reason\": &\"CUSTOMER_CAPACITY\"})\n\tvar effective_validator := validator if validator.is_valid() else _start_validator\n\tvar callback_failure := _run_boundary_callback(\n\t\teffective_validator,\n\t\t[request, instance, minute],\n\t\t\"Service start validation failed.\",\n\t\tCommandResultType.Code.VALIDATION_FAILED\n\t)\n\tif callback_failure != null:\n\t\tcallback_failure.details[&\"request_id\"] = request.request_id\n\t\tcallback_failure.details[&\"instance_id\"] = instance_id\n\t\treturn callback_failure\n\n\tvar service_id := _next_service_id()\n\tvar service := ServiceInstanceType.new().configure(\n\t\tservice_id,\n\t\trequest.request_id,\n\t\tinstance_id,\n\t\tminute,\n\t\trequest.service_minutes if request.service_minutes > 0 else instance.base_service_minutes,\n\t\trequest.guest_ids,\n\t\tinstance.active_staff_ids,\n\t\t{\n\t\t\t&\"quality_snapshot\": request.expected_quality,\n\t\t\t&\"price_snapshot\": request.quoted_price,\n\t\t\t&\"policy_snapshot\": request.policy_snapshot,\n\t\t\t&\"inventory_reservations\": request.reserved_inventory_ids,\n\t\t}\n\t)\n\tinstance.queue_entries.remove_at(0)\n\t# Report this start's service index, independent of customer headcount and callbacks.\n\tvar slot := instance.active_services.size()\n\tinstance.active_services[service_id] = service\n\t_known_service_ids[service_id] = true\n\t_increment_stat(instance.statistics_today, &\"services_started\")\n\t_increment_stat(instance.lifetime_statistics, &\"services_started\")\n\tservice_started.emit(service)\n\tlast_error = \"\"\n\treturn _success({\n\t\t&\"instance_id\": instance_id,\n\t\t&\"request_id\": request.request_id,\n\t\t&\"service_id\": service_id,\n\t\t&\"slot\": slot,\n\t})\n\n\n"
|
||||||
|
},
|
||||||
|
"_fail_service": {
|
||||||
|
"line": 933,
|
||||||
|
"end_line": 947,
|
||||||
|
"sha256": "56f61b255217bddb4c8a6ad3af6ed1f9edc3b6a6e928dacf2105be6698936de5",
|
||||||
|
"body": "func _fail_service(\n\tinstance: FacilityInstance,\n\tservice: ServiceInstance,\n\treason: StringName,\n\tabsolute_minute: int\n) -> void:\n\tservice.mark_failed(reason, absolute_minute)\n\tinstance.active_services.erase(service.service_id)\n\t_requests.erase(service.request_id)\n\t_service_history[service.service_id] = service\n\t_increment_stat(instance.statistics_today, &\"services_failed\")\n\t_increment_stat(instance.lifetime_statistics, &\"services_failed\")\n\tservice_failed.emit(service, reason)\n\n\n"
|
||||||
|
},
|
||||||
|
"set_operational_status": {
|
||||||
|
"line": 132,
|
||||||
|
"end_line": 177,
|
||||||
|
"sha256": "10275169f4a71ad490c432443c34068d1951f099e11132b3c18b48647e7845c8",
|
||||||
|
"body": "func set_operational_status(\n\tinstance_id: StringName,\n\tconditions: Dictionary,\n\tabsolute_minute: int = -1\n) -> CommandResult:\n\tvar instance := get_instance(instance_id)\n\tif instance == null:\n\t\treturn _not_found(\"Facility instance\", instance_id)\n\tvar old_state := instance.state\n\tif _has_value(conditions, &\"related_facility_id\"):\n\t\tvar raw_related: Variant = _value(conditions, &\"related_facility_id\", null)\n\t\tif typeof(raw_related) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treturn _invalid(\"Related facility must be one facility ID.\")\n\t\tvar related := StringName(raw_related)\n\t\tif related == instance_id or (not related.is_empty() and not has_instance(related)):\n\t\t\treturn _invalid(\"Related facility is missing or refers to itself.\")\n\t\tif instance.requires_operating_kitchen() and not related.is_empty():\n\t\t\tvar kitchen := get_instance(related)\n\t\t\tif kitchen.definition_id != &\"kitchen\" or kitchen.origin.z != WorldService.LAYER_BACK:\n\t\t\t\treturn _invalid(\"Dining facilities require one existing BACK kitchen.\", {&\"reason\": &\"INVALID_RELATED_KITCHEN\"})\n\t\t\tif not _required_related_placement_matches(instance, kitchen):\n\t\t\t\treturn _invalid(\"The BACK kitchen must lie inside this FRONT dining facility's XY footprint.\", {&\"reason\": &\"INVALID_RELATED_KITCHEN_PLACEMENT\"})\n\t\tvar seen := {instance_id: true}\n\t\tvar cursor := related\n\t\twhile not cursor.is_empty() and has_instance(cursor):\n\t\t\tif seen.has(cursor):\n\t\t\t\treturn _invalid(\"Related facilities cannot form a cycle.\")\n\t\t\tseen[cursor] = true\n\t\t\tcursor = get_instance(cursor).related_facility_id\n\tif _has_value(conditions, &\"related_facility_operating\") or _has_value(conditions, &\"operation_state\"):\n\t\treturn _invalid(\"Operating flags are computed from actual facility conditions.\")\n\tif _has_value(conditions, &\"suspension_reason\") and (typeof(_value(conditions, &\"suspension_reason\", null)) not in [TYPE_STRING, TYPE_STRING_NAME] or StringName(_value(conditions, &\"suspension_reason\", &\"\")) not in [&\"DESTROYED\", &\"RAIDED\"]):\n\t\treturn _invalid(\"Suspension recovery is not specified.\")\n\tvar minute := _resolve_minute(absolute_minute)\n\tinstance.set_operational_conditions(conditions, minute)\n\tif old_state != instance.state or _has_value(conditions, &\"related_facility_id\"):\n\t\trefresh_operating_dependencies(minute)\n\t_emit_state_change(instance, old_state)\n\tlast_error = \"\"\n\treturn _success({\n\t\t&\"instance_id\": instance_id,\n\t\t&\"state\": FacilityInstanceType.State.keys()[instance.state],\n\t\t&\"state_reasons\": instance.state_reasons.duplicate(),\n\t})\n\n\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts/facility/facility_instance.gd": {
|
||||||
|
"sha256": "0c6aa493f3299611e05dd26aa429dda8cf7b5c479e4d09632036fb862f79a324",
|
||||||
|
"bytes": 22815,
|
||||||
|
"functions": {
|
||||||
|
"can_start_service": {
|
||||||
|
"line": 243,
|
||||||
|
"end_line": 247,
|
||||||
|
"sha256": "39ab5458947ddce7d26129d0174f82dfcec0e87358c058220f61c483f43a9cd5",
|
||||||
|
"body": "func can_start_service(absolute_minute: int) -> bool:\n\tevaluate_state(absolute_minute)\n\treturn state in [State.OPEN, State.DEGRADED] and available_slots() > 0\n\n\n"
|
||||||
|
},
|
||||||
|
"can_accept_customers": {
|
||||||
|
"line": 267,
|
||||||
|
"end_line": 278,
|
||||||
|
"sha256": "3d0984f009ca82b40057c57e0a10a1b68200026843b55a9e63d821064292046f",
|
||||||
|
"body": "func can_accept_customers(guest_ids: Array[StringName]) -> bool:\n\tif customer_capacity < 0:\n\t\treturn true\n\tvar customers: Dictionary = {}\n\tfor service: ServiceInstance in active_services.values():\n\t\tfor guest_id: StringName in service.guest_ids:\n\t\t\tcustomers[guest_id] = true\n\tfor guest_id: StringName in guest_ids:\n\t\tcustomers[guest_id] = true\n\treturn customers.size() <= customer_capacity\n\n\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts/facility/service_instance.gd": {
|
||||||
|
"sha256": "629a142f80cbc31b97b6d08483d94e029e448969bb6d39fdc8dd39931654dd35",
|
||||||
|
"bytes": 7320,
|
||||||
|
"functions": {
|
||||||
|
"mark_failed": {
|
||||||
|
"line": 128,
|
||||||
|
"end_line": 134,
|
||||||
|
"sha256": "178c6879e64385f0e3ff99fa98ae6ceb4dc67f6c2c981b0effb229f5d4d647fa",
|
||||||
|
"body": "func mark_failed(reason: StringName, absolute_minute: int) -> void:\n\tstate = State.FAILED\n\tfailure_reason = reason\n\tcompleted_at = absolute_minute\n\tstaff_grace_deadline = NO_DEADLINE\n\n\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data/facilities/cafeteria.tres": {
|
||||||
|
"sha256": "86d540fe2d78b9dcdbe5a0af6e4a001f4cec54934636ed01deb25a943c79128a",
|
||||||
|
"bytes": 867,
|
||||||
|
"functions": {},
|
||||||
|
"source": "[gd_resource type=\"Resource\" script_class=\"FacilityDefinition\" load_steps=2 format=3]\n\n[ext_resource type=\"Script\" path=\"res://scripts/data/facility_definition.gd\" id=\"1\"]\n\n[resource]\nscript = ExtResource(\"1\")\nid = &\"cafeteria\"\ndisplay_name = \"大衆食堂\"\ndescription = \"低価格で多くの客の食欲を満たす。裏層の厨房から料理を受け取る。\"\nzone = 0\nlayer = 0\nfootprint = Vector2i(4, 2)\nconstruction_cost = {&\"gold\": 800, &\"materials\": 12}\nbuild_minutes = 180\nweight_per_cell = 2\nmaintenance_gold = 4\nmaintenance_mana = 2\nstaff_min = 2\nstaff_max = 4\nrequired_roles = Array[StringName]([&\"cook\", &\"server\", &\"attendant\"])\nprimary_skill = &\"cooking\"\ncapacity = 12\nqueue_capacity = 24\nbase_service_minutes = 45\nbase_quality = 55\nbase_price = 25\ninventory_inputs = {&\"ingredient/basic_meal\": 1}\ntags = Array[StringName]([&\"dining\", &\"social\"])\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-3
@@ -5,6 +5,7 @@ import hashlib
|
|||||||
import importlib.util
|
import importlib.util
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import py_compile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -23,9 +24,10 @@ def run():
|
|||||||
results = []
|
results = []
|
||||||
with tempfile.TemporaryDirectory(prefix='.checker-fixtures-', dir=Path(__file__).parent) as temp:
|
with tempfile.TemporaryDirectory(prefix='.checker-fixtures-', dir=Path(__file__).parent) as temp:
|
||||||
base = Path(temp)
|
base = Path(temp)
|
||||||
# Keep py_compile output inside allowed_paths; delete with the fixture.
|
# Generated bytecode belongs in allocated build, never tracked docs.
|
||||||
env = dict(os.environ, PYTHONPYCACHEPREFIX=str(base / 'pycache'))
|
build = Path(os.environ['BUILD_OUTPUT_DIR']).resolve(strict=True)
|
||||||
subprocess.run(['python3', '-m', 'py_compile', str(CHECKER)], env=env, check=True)
|
with tempfile.TemporaryDirectory(prefix='p04-compile-', dir=build) as compiled:
|
||||||
|
py_compile.compile(str(CHECKER), cfile=str(Path(compiled) / 'checker.pyc'), doraise=True)
|
||||||
evidence = base / 'p04-evidence'
|
evidence = base / 'p04-evidence'
|
||||||
evidence.mkdir()
|
evidence.mkdir()
|
||||||
artifacts = {}
|
artifacts = {}
|
||||||
|
|||||||
@@ -1428,12 +1428,15 @@ def verify_fresh_s5(build):
|
|||||||
arguments = (s.base / 'raw', s.inventory['writer.json']['sha256'], s.inventory['reader.json']['sha256'])
|
arguments = (s.base / 'raw', s.inventory['writer.json']['sha256'], s.inventory['reader.json']['sha256'])
|
||||||
power = adapter.power.derive(*arguments)
|
power = adapter.power.derive(*arguments)
|
||||||
order = adapter.derive(*arguments)
|
order = adapter.derive(*arguments)
|
||||||
|
require(set(order['cases']) == set(adapter.DERIVERS)
|
||||||
|
and set(power['cases']) == set(adapter.power.CASES), 'complete fresh adapter case sets')
|
||||||
conditions = ['power_stop', 'dependency_stop', 'recovery_completion', 'destruction_stop', 'exit_release',
|
conditions = ['power_stop', 'dependency_stop', 'recovery_completion', 'destruction_stop', 'exit_release',
|
||||||
'midnight_settlement', 'midnight_replay', 'save_restore', 'shift_completion',
|
'midnight_settlement', 'midnight_replay', 'save_restore', 'shift_completion',
|
||||||
'paused_midnight', 'same_minute_replay']
|
'paused_midnight', 'same_minute_replay']
|
||||||
require(order['cases']['S5D_DESTRUCTION_RAID']['G1'] is True
|
require(order['cases']['S5D_DESTRUCTION_RAID']['G1'] is True
|
||||||
and order['cases']['S5D_IN_FLIGHT']['G2'] is True
|
and order['cases']['S5D_IN_FLIGHT']['G2'] is True
|
||||||
and order['cases']['S5D_DESTRUCTION_RAID']['idle_objective_breach'] is True,
|
and order['cases']['S5D_DESTRUCTION_RAID']['idle_objective_breach'] is True
|
||||||
|
and order['cases']['S5D_PAID_BEFORE_INCIDENT']['paid_before_incident'] is True,
|
||||||
'fresh destruction requires both guards and exact-N idle breach')
|
'fresh destruction requires both guards and exact-N idle breach')
|
||||||
for case, key in [('S5G_SHIFT_1080', 'shift_completion'), ('S5H_PAUSED_MIDNIGHT', 'paused_midnight'),
|
for case, key in [('S5G_SHIFT_1080', 'shift_completion'), ('S5H_PAUSED_MIDNIGHT', 'paused_midnight'),
|
||||||
('S5E_MIDNIGHT', 'same_minute_replay')]:
|
('S5E_MIDNIGHT', 'same_minute_replay')]:
|
||||||
|
|||||||
@@ -1,4 +1,67 @@
|
|||||||
# REPAIR43 — native evidence and formal acceptance pending
|
# REPAIR45 — whole unit remains incomplete
|
||||||
|
|
||||||
|
## REPAIR45 — implementation ready for submission
|
||||||
|
|
||||||
|
The supplied byte-verified M engine-free context resolved the REPAIR44 UID dependency.
|
||||||
|
UID controls: all 14 PASS, exit 0. Both supplied helper SHA-256 pins match exactly.
|
||||||
|
AST and explicit fresh BUILD-cfile py_compile passed for all eight touched Python
|
||||||
|
files, with python3 -B and PYTHONDONTWRITEBYTECODE=1. No source was changed in
|
||||||
|
REPAIR45; retained passing controls were not rerun. The no-pyc static check
|
||||||
|
passed again (exit 0); generated compile files exist only under allocated BUILD.
|
||||||
|
The prior UID failure remains recorded as failed, not replaced with a PASS.
|
||||||
|
|
||||||
|
Sequential check-only S1, S2a, S2b, S3, S4 and S5 each returned exit 2:
|
||||||
|
`ValueError: checkout is not clean`
|
||||||
|
The initial missing-tested-tree argument refusals are also retained. The later
|
||||||
|
attempt used the actual HEAD tree solely as a guard input, not a claim of final
|
||||||
|
Q, clean source or C. No engine started. Root executes clean exact-Q check-only
|
||||||
|
after automatic submission. Full argv/stdout/stderr and compile paths are in
|
||||||
|
REPAIR41_STATIC_CHECKS.json. No Git writes, Runner or native run were performed.
|
||||||
|
|
||||||
|
Implementation is ready; the whole original unit remains incomplete and P04
|
||||||
|
credit remains 0. Deferred Root conditions, in order: freeze final Q; affected
|
||||||
|
pure controls; clean exact-Q check-only; capacity check; one heavy lease with
|
||||||
|
fresh native S1–S4 and all ten S5 cases; independent Reader and adapters on actual
|
||||||
|
raw (including fresh Reader order positives); fresh collect; full 184 suite once;
|
||||||
|
index; --verify-only; registered validation before review; independent whole-unit
|
||||||
|
Opus review; normal prepare / exact C / integration / final / Root DB join /
|
||||||
|
ledger / main push. Native Reader and acceptance remain pending.
|
||||||
|
patience_release stays pending unless fresh S3 raw shows it. Product freeze,
|
||||||
|
M, allowed paths, REQUIRED membership/thresholds, all seven domains, G1/G2,
|
||||||
|
R40–R44 and the existing one-trailing-LF spec protocol remain unchanged.
|
||||||
|
|
||||||
|
# REPAIR44 — original whole unit incomplete
|
||||||
|
|
||||||
|
Worker status is **blocked**, not ready for Root native execution. UID pure
|
||||||
|
control could not read the supplied Q checkout's tools/run_all_tests.py
|
||||||
|
(PermissionError). See ../REPAIR41_STATUS.md and ../REPAIR41_STATIC_CHECKS.json.
|
||||||
|
AST/build compilation for every touched Python file and check-only S1–S5
|
||||||
|
remain unexecuted; resume worker verification before freezing a final Q.
|
||||||
|
|
||||||
|
Native Reader and acceptance remain pending. The current ten-case roster is
|
||||||
|
`S5A_PURE`, `S5B_DEPENDENCY`, `S5C_DESTRUCTION_COMMAND`, `S5D_DESTRUCTION_RAID`,
|
||||||
|
`S5D_IN_FLIGHT`, `S5D_PAID_BEFORE_INCIDENT`, `S5E_MIDNIGHT`, `S5F_EXIT`,
|
||||||
|
`S5G_SHIFT_1080`, `S5H_PAUSED_MIDNIGHT`.
|
||||||
|
|
||||||
|
The new case supplies a typed raw derivation for N completion/payment, public
|
||||||
|
event destruction after payment, and N+1 failure/release of the secondary.
|
||||||
|
It does not supply executed native evidence. The D05 destruction gate requires
|
||||||
|
it in addition to every existing command/guard/idle/in-flight gate.
|
||||||
|
patience_release stays pending unless fresh S3 raw proves it.
|
||||||
|
|
||||||
|
r35, r36, R40 native and R43 native remain FAILED. Q37 is a local PASS for its
|
||||||
|
own version only. R43 Writer 2749/0, seven Writer-only derivers plus G1/G2, twelve
|
||||||
|
pure controls and six check-only steps retain their limited historical scope;
|
||||||
|
none is independent Reader proof. Original credit 30/88, formal credit 16/88,
|
||||||
|
P04 credit 0; no new task/unit/worker or completion claim.
|
||||||
|
|
||||||
|
REPAIR41_STATIC_CHECKS.json records only worker checks actually executed.
|
||||||
|
Root must freeze final Q, then follow S5_ROOT_RUN.md, including fresh S1–S5,
|
||||||
|
Reader/adapters, collect, full 184 suite once, index, verify-only, registered
|
||||||
|
validation, independent review and normal integration. Historical text below
|
||||||
|
does not replace this order or the current ten-case roster.
|
||||||
|
|
||||||
|
# Historical REPAIR43 — native evidence and formal acceptance pending
|
||||||
|
|
||||||
The R42/R43 implementation batch now includes the public-restored G1/G2
|
The R42/R43 implementation batch now includes the public-restored G1/G2
|
||||||
journal shadows, independent typed adapter oracle, exact-N idle OBJECTIVE
|
journal shadows, independent typed adapter oracle, exact-N idle OBJECTIVE
|
||||||
|
|||||||
@@ -1,4 +1,75 @@
|
|||||||
# REPAIR43 submission — Root verification required
|
# REPAIR45 handoff
|
||||||
|
|
||||||
|
## REPAIR45 — implementation ready for submission
|
||||||
|
|
||||||
|
The supplied byte-verified M engine-free context resolved the REPAIR44 UID dependency.
|
||||||
|
UID controls: all 14 PASS, exit 0. Both supplied helper SHA-256 pins match exactly.
|
||||||
|
AST and explicit fresh BUILD-cfile py_compile passed for all eight touched Python
|
||||||
|
files, with python3 -B and PYTHONDONTWRITEBYTECODE=1. No source was changed in
|
||||||
|
REPAIR45; retained passing controls were not rerun. The no-pyc static check
|
||||||
|
passed again (exit 0); generated compile files exist only under allocated BUILD.
|
||||||
|
The prior UID failure remains recorded as failed, not replaced with a PASS.
|
||||||
|
|
||||||
|
Sequential check-only S1, S2a, S2b, S3, S4 and S5 each returned exit 2:
|
||||||
|
`ValueError: checkout is not clean`
|
||||||
|
The initial missing-tested-tree argument refusals are also retained. The later
|
||||||
|
attempt used the actual HEAD tree solely as a guard input, not a claim of final
|
||||||
|
Q, clean source or C. No engine started. Root executes clean exact-Q check-only
|
||||||
|
after automatic submission. Full argv/stdout/stderr and compile paths are in
|
||||||
|
REPAIR41_STATIC_CHECKS.json. No Git writes, Runner or native run were performed.
|
||||||
|
|
||||||
|
Implementation is ready; the whole original unit remains incomplete and P04
|
||||||
|
credit remains 0. Deferred Root conditions, in order: freeze final Q; affected
|
||||||
|
pure controls; clean exact-Q check-only; capacity check; one heavy lease with
|
||||||
|
fresh native S1–S4 and all ten S5 cases; independent Reader and adapters on actual
|
||||||
|
raw (including fresh Reader order positives); fresh collect; full 184 suite once;
|
||||||
|
index; --verify-only; registered validation before review; independent whole-unit
|
||||||
|
Opus review; normal prepare / exact C / integration / final / Root DB join /
|
||||||
|
ledger / main push. Native Reader and acceptance remain pending.
|
||||||
|
patience_release stays pending unless fresh S3 raw shows it. Product freeze,
|
||||||
|
M, allowed paths, REQUIRED membership/thresholds, all seven domains, G1/G2,
|
||||||
|
R40–R44 and the existing one-trailing-LF spec protocol remain unchanged.
|
||||||
|
|
||||||
|
# REPAIR44 — ten cases, final Q must be frozen by Root
|
||||||
|
|
||||||
|
**Worker blocked on an unreadable UID-check dependency; do not start native
|
||||||
|
execution from this partial repair.** See ../REPAIR41_STATUS.md. Remaining
|
||||||
|
worker AST/compile and check-only checks must finish before this Root order.
|
||||||
|
|
||||||
|
The complete roster is `S5A_PURE`, `S5B_DEPENDENCY`, `S5C_DESTRUCTION_COMMAND`,
|
||||||
|
`S5D_DESTRUCTION_RAID`, `S5D_IN_FLIGHT`, `S5D_PAID_BEFORE_INCIDENT`,
|
||||||
|
`S5E_MIDNIGHT`, `S5F_EXIT`, `S5G_SHIFT_1080`, `S5H_PAUSED_MIDNIGHT`.
|
||||||
|
CASES is sorted from CASE_TABLE; LABELS and all 23 slots derive from it.
|
||||||
|
Receipt membership is order-independent and rejects missing/duplicate/extra
|
||||||
|
cases or slots. Reader independently enumerates CASE_TABLE.
|
||||||
|
|
||||||
|
The new case completes and pays the primary at N, destroys through the public
|
||||||
|
automatic event in INCIDENTS_AND_EVENTS at N, and fails/releases the unfinished
|
||||||
|
secondary at N+1. See ../REPAIR44_SOURCE_FACTS.json and the REPAIR44 section in
|
||||||
|
../REPAIR41_STATUS.md. No Defense asset registration or guard bypass is used.
|
||||||
|
Run repair44_controls.py in addition to every existing pure control. Synthetic
|
||||||
|
typed controls are not native evidence. R43 Writer 2749/0 and Writer-only typed
|
||||||
|
analysis did not run the Reader; R43 native remains FAILED.
|
||||||
|
|
||||||
|
Authoritative Root order, after freezing the final Q:
|
||||||
|
|
||||||
|
1. Affected pure controls, including repair44_controls.py.
|
||||||
|
2. Check-only S1–S5 plan (after controls finish writing temporary fixtures).
|
||||||
|
3. Capacity check.
|
||||||
|
4. One heavy lease: fresh native S1–S5, all ten S5 cases.
|
||||||
|
5. Independent Reader and adapters on actual raw.
|
||||||
|
6. Fresh collect, recomputing the new D05 sub-gate from raw.
|
||||||
|
7. Full 184 exact-Q regression once.
|
||||||
|
8. Index.
|
||||||
|
9. --verify-only.
|
||||||
|
10. Registered validation.
|
||||||
|
11. Independent whole-unit Opus review.
|
||||||
|
12. Normal prepare / exact C / integration / final / Root DB join / ledger / main push.
|
||||||
|
|
||||||
|
No worker engine/native/full regression or Git write is authorized. Whole-unit
|
||||||
|
acceptance and patience_release remain pending. Local checks earn no credit.
|
||||||
|
|
||||||
|
# Historical REPAIR43 submission — superseded current roster
|
||||||
|
|
||||||
The R41 closed journal-field restriction and R42 raw-only spec stop are
|
The R41 closed journal-field restriction and R42 raw-only spec stop are
|
||||||
superseded. The spec passes the existing one-final-LF checker condition.
|
superseded. The spec passes the existing one-final-LF checker condition.
|
||||||
|
|||||||
+33
-3
@@ -6,12 +6,13 @@ const CASE_TABLE: Dictionary = {
|
|||||||
"S5C_DESTRUCTION_COMMAND": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_order_stop", "assert": "_assert_order"},
|
"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": 0, "labels": ["boundary", "held"], "prepare": "_prepare_idle_breach", "advance": "_advance_order", "stop": "_assert_idle_breach", "assert": "_assert_idle_order"},
|
"S5D_DESTRUCTION_RAID": {"expected_reserved_ids": 0, "labels": ["boundary", "held"], "prepare": "_prepare_idle_breach", "advance": "_advance_order", "stop": "_assert_idle_breach", "assert": "_assert_idle_order"},
|
||||||
"S5D_IN_FLIGHT": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_in_flight", "assert": "_assert_in_flight_order"},
|
"S5D_IN_FLIGHT": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_in_flight", "assert": "_assert_in_flight_order"},
|
||||||
|
"S5D_PAID_BEFORE_INCIDENT": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_paid_incident", "assert": "_assert_paid_incident_order"},
|
||||||
"S5G_SHIFT_1080": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_order_stop", "assert": "_assert_order"},
|
"S5G_SHIFT_1080": {"expected_reserved_ids": 1, "labels": ["boundary", "held"], "prepare": "_prepare_order", "advance": "_advance_order", "stop": "_assert_order_stop", "assert": "_assert_order"},
|
||||||
"S5H_PAUSED_MIDNIGHT": {"expected_reserved_ids": 1, "labels": ["boundary", "held", "recovered"], "prepare": "_prepare_order", "advance": "_advance_paused_midnight", "stop": "_assert_paused_midnight", "assert": "_assert_paused_midnight_order"},
|
"S5H_PAUSED_MIDNIGHT": {"expected_reserved_ids": 1, "labels": ["boundary", "held", "recovered"], "prepare": "_prepare_order", "advance": "_advance_paused_midnight", "stop": "_assert_paused_midnight", "assert": "_assert_paused_midnight_order"},
|
||||||
"S5E_MIDNIGHT": {"expected_reserved_ids": 1, "labels": ["boundary", "recalled"], "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"}
|
"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, "S5D_IN_FLIGHT": 420553, "S5E_MIDNIGHT": 424242, "S5F_EXIT": 420555, "S5G_SHIFT_1080": 420556, "S5H_PAUSED_MIDNIGHT": 424242}
|
const SEEDS: Dictionary = {"S5A_PURE": 420550, "S5B_DEPENDENCY": 420551, "S5C_DESTRUCTION_COMMAND": 420552, "S5D_DESTRUCTION_RAID": 420553, "S5D_IN_FLIGHT": 420553, "S5D_PAID_BEFORE_INCIDENT": 420558, "S5E_MIDNIGHT": 424242, "S5F_EXIT": 420555, "S5G_SHIFT_1080": 420556, "S5H_PAUSED_MIDNIGHT": 424242}
|
||||||
const GUEST: StringName = &"p04.s5.guest.a"
|
const GUEST: StringName = &"p04.s5.guest.a"
|
||||||
const REQUEST: StringName = &"p04.s5.request.a"
|
const REQUEST: StringName = &"p04.s5.request.a"
|
||||||
const QUEUED_GUEST: StringName = &"p04.s5.guest.b"
|
const QUEUED_GUEST: StringName = &"p04.s5.guest.b"
|
||||||
@@ -201,7 +202,7 @@ func _prepare_order() -> bool:
|
|||||||
if _duration <= 5: return false
|
if _duration <= 5: return false
|
||||||
_clock.advance_minutes(queue_at - _clock.absolute_minute)
|
_clock.advance_minutes(queue_at - _clock.absolute_minute)
|
||||||
_expect(facility.active_staff_ids == staff_ids, "ordinary physical attendance")
|
_expect(facility.active_staff_ids == staff_ids, "ordinary physical attendance")
|
||||||
var second: bool = _case in ["S5D_DESTRUCTION_RAID", "S5F_EXIT"]
|
var second: bool = _case in ["S5D_DESTRUCTION_RAID", "S5F_EXIT", "S5D_PAID_BEFORE_INCIDENT"]
|
||||||
_expect(_stock(facility.local_inventory_id, &"ingredient/basic_meal", 2 if second else 1, &"p04.s5.order.stock"), "actual reservable meals")
|
_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)
|
_queue(GUEST, REQUEST, _boundary if _case == "S5F_EXIT" else _boundary + _duration + 1)
|
||||||
_clock.advance_one_minute()
|
_clock.advance_one_minute()
|
||||||
@@ -213,6 +214,11 @@ func _prepare_order() -> bool:
|
|||||||
_expect(service.started_at + _duration == _boundary + (1 if _case == "S5D_IN_FLIGHT" else 0), "natural completion from snapshot duration")
|
_expect(service.started_at + _duration == _boundary + (1 if _case == "S5D_IN_FLIGHT" else 0), "natural completion from snapshot duration")
|
||||||
_price = service.price_snapshot
|
_price = service.price_snapshot
|
||||||
_duration = service.duration_minutes
|
_duration = service.duration_minutes
|
||||||
|
if _case == "S5D_PAID_BEFORE_INCIDENT":
|
||||||
|
_expect(definition.capacity >= 2 and facility.active_staff_ids.size() >= definition.staff_min, "definition supports concurrent services with ordinary staff")
|
||||||
|
if definition.capacity < 2: return false
|
||||||
|
_clock.advance_minutes(_boundary - 2 - _clock.absolute_minute)
|
||||||
|
_queue(QUEUED_GUEST, QUEUED_REQUEST, _boundary + _duration + 1)
|
||||||
if _case == "S5D_DESTRUCTION_RAID":
|
if _case == "S5D_DESTRUCTION_RAID":
|
||||||
_clock.advance_minutes(_boundary - 5 - _clock.absolute_minute)
|
_clock.advance_minutes(_boundary - 5 - _clock.absolute_minute)
|
||||||
_prepare_breach()
|
_prepare_breach()
|
||||||
@@ -229,6 +235,7 @@ func _prepare_order() -> bool:
|
|||||||
_recovery = {&"staff_ids": staff_ids, &"resume_minute": _boundary}
|
_recovery = {&"staff_ids": staff_ids, &"resume_minute": _boundary}
|
||||||
if _case == "S5D_IN_FLIGHT":
|
if _case == "S5D_IN_FLIGHT":
|
||||||
_guard_failure("G2", &"register_defense_asset", {&"raid_id": &"p04.s5.guard.raid", &"asset_id": _facility_id, &"kind": &"OBJECTIVE", &"max_integrity": 10000}, "A busy Facility cannot become a Defense asset.", {})
|
_guard_failure("G2", &"register_defense_asset", {&"raid_id": &"p04.s5.guard.raid", &"asset_id": _facility_id, &"kind": &"OBJECTIVE", &"max_integrity": 10000}, "A busy Facility cannot become a Defense asset.", {})
|
||||||
|
if _case in ["S5D_IN_FLIGHT", "S5D_PAID_BEFORE_INCIDENT"]:
|
||||||
_cmd(&"register_event_definition", {&"definition": {&"event_id": &"p04.s5.break", &"category": &"FLAVOR", &"priority": 100, &"foreground": false, &"transaction_policy": &"ROLLBACK_ALL", &"automatic_actions": [{&"action_id": &"break", &"type": &"SET_FACILITY_STATE", &"payload": {&"facility_id": _facility_id, &"conditions": {&"durability": 0, &"suspension_reason": &"DESTROYED"}}}]}})
|
_cmd(&"register_event_definition", {&"definition": {&"event_id": &"p04.s5.break", &"category": &"FLAVOR", &"priority": 100, &"foreground": false, &"transaction_policy": &"ROLLBACK_ALL", &"automatic_actions": [{&"action_id": &"break", &"type": &"SET_FACILITY_STATE", &"payload": {&"facility_id": _facility_id, &"conditions": {&"durability": 0, &"suspension_reason": &"DESTROYED"}}}]}})
|
||||||
if _case not in ["S5D_IN_FLIGHT", "S5H_PAUSED_MIDNIGHT"]:
|
if _case not in ["S5D_IN_FLIGHT", "S5H_PAUSED_MIDNIGHT"]:
|
||||||
_expect(service.elapsed_minutes == _duration - 1, "duration minus one at N-1")
|
_expect(service.elapsed_minutes == _duration - 1, "duration minus one at N-1")
|
||||||
@@ -370,7 +377,7 @@ func _assert_paused_midnight_order(before: Dictionary, point: Dictionary) -> voi
|
|||||||
|
|
||||||
func _advance_order(label: String) -> void:
|
func _advance_order(label: String) -> void:
|
||||||
if label == "boundary":
|
if label == "boundary":
|
||||||
if _case == "S5D_IN_FLIGHT": _cmd(&"enqueue_event", {&"event_id": &"p04.s5.break", &"actor_ids": [&"player"]}, _boundary)
|
if _case in ["S5D_IN_FLIGHT", "S5D_PAID_BEFORE_INCIDENT"]: _cmd(&"enqueue_event", {&"event_id": &"p04.s5.break", &"actor_ids": [&"player"]}, _boundary)
|
||||||
if _case == "S5C_DESTRUCTION_COMMAND": _cmd(&"set_facility_conditions", {&"facility_id": _facility_id, &"conditions": {&"durability": 0}}, _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 _case == "S5F_EXIT": _cmd(&"leave_facility_queue", {&"facility_id": _facility_id, &"request_id": QUEUED_REQUEST}, _boundary)
|
||||||
if label == "recalled":
|
if label == "recalled":
|
||||||
@@ -383,6 +390,29 @@ func _advance_order(label: String) -> void:
|
|||||||
else:
|
else:
|
||||||
_clock.advance_one_minute()
|
_clock.advance_one_minute()
|
||||||
|
|
||||||
|
func _assert_paid_incident(point: Dictionary) -> void:
|
||||||
|
_expect(point[&"service"][&"state"] == "COMPLETED" and point[&"service"][&"completed_at"] == _boundary, "primary paid at N")
|
||||||
|
_expect(point[&"facility"][&"durability"] == 0 and point[&"facility"][&"state"] == "BROKEN" and point[&"facility"][&"suspension_reason"] == "DESTROYED", "public event destruction after completion")
|
||||||
|
var secondary: Array = []
|
||||||
|
var facilities: Dictionary = point[&"snapshot"][&"systems"][&"runtime"][&"facilities"]
|
||||||
|
for instance: Dictionary in facilities[&"instances"]:
|
||||||
|
for service: Dictionary in instance[&"active_services"]:
|
||||||
|
if service[&"request_id"] == QUEUED_REQUEST: secondary.append(service)
|
||||||
|
for service: Dictionary in facilities[&"service_history"]:
|
||||||
|
if service[&"request_id"] == QUEUED_REQUEST: secondary.append(service)
|
||||||
|
_expect(secondary.size() == 1, "one secondary service without duplicate generation")
|
||||||
|
if secondary.size() != 1: return
|
||||||
|
_expect(secondary[0][&"state"] == ("ACTIVE" if point[&"minute"] == _boundary else "FAILED"), "secondary unfinished at N and failed at N+1")
|
||||||
|
if point[&"minute"] > _boundary:
|
||||||
|
_expect(secondary[0][&"failure_reason"] == "BROKEN" and secondary[0][&"completed_at"] == _boundary + 1, "secondary broken failure timestamp")
|
||||||
|
|
||||||
|
func _assert_paid_incident_order(before: Dictionary, point: Dictionary) -> void:
|
||||||
|
_assert_paid_incident(point)
|
||||||
|
_expect(point[&"wallets"][String(GUEST)] == before[&"wallets"][String(GUEST)] - _price, "one primary snapshot price debit")
|
||||||
|
_expect(point[&"wallets"][String(QUEUED_GUEST)] == before[&"wallets"][String(QUEUED_GUEST)], "secondary uncharged")
|
||||||
|
_assert_reservation(before, point, REQUEST, "CONSUMED", _boundary)
|
||||||
|
_assert_reservation(before, point, QUEUED_REQUEST, "ACTIVE" if point[&"minute"] == _boundary else "RELEASED", -1 if point[&"minute"] == _boundary else _boundary + 1)
|
||||||
|
|
||||||
func _assert_order_stop(point: Dictionary) -> void:
|
func _assert_order_stop(point: Dictionary) -> void:
|
||||||
if _case == "S5C_DESTRUCTION_COMMAND":
|
if _case == "S5C_DESTRUCTION_COMMAND":
|
||||||
_expect(point[&"service"][&"state"] == "FAILED" and point[&"service"][&"failure_reason"] == String(FacilityService.INTERRUPTION_BROKEN), "command destruction interrupts before payment")
|
_expect(point[&"service"][&"state"] == "FAILED" and point[&"service"][&"failure_reason"] == String(FacilityService.INTERRUPTION_BROKEN), "command destruction interrupts before payment")
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Engine-free REPAIR44 units. Synthetic typed inputs are never native evidence."""
|
||||||
|
import copy
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.dont_write_bytecode = True
|
||||||
|
import s5_order_adapter as a
|
||||||
|
import run_s5_native as wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def typed(value):
|
||||||
|
o = a.guard_oracle
|
||||||
|
def encode(v):
|
||||||
|
if isinstance(v, bool):
|
||||||
|
return o.atom(1, v)
|
||||||
|
if isinstance(v, int):
|
||||||
|
return o.atom(2, v)
|
||||||
|
if isinstance(v, str):
|
||||||
|
return o.atom(4, v)
|
||||||
|
if isinstance(v, list):
|
||||||
|
return o.array([encode(x) for x in v])
|
||||||
|
return o.strings_dict([(k, encode(v)) for k, v in v.items()])
|
||||||
|
return a.series.variant(encode(value))
|
||||||
|
|
||||||
|
|
||||||
|
def fixture():
|
||||||
|
"""Small source-shaped serializer unit for the deriver, not a game replay."""
|
||||||
|
n, price = 960, 25
|
||||||
|
primary = dict(service_id='primary', request_id=a.REQUEST, price_snapshot=price,
|
||||||
|
duration_minutes=45, started_at=n-45, elapsed_minutes=44,
|
||||||
|
state='ACTIVE', completed_at=-1, failure_reason='')
|
||||||
|
secondary = dict(service_id='secondary', request_id=a.SECOND_REQUEST, price_snapshot=price,
|
||||||
|
duration_minutes=45, started_at=n-1, elapsed_minutes=0,
|
||||||
|
state='ACTIVE', completed_at=-1, failure_reason='')
|
||||||
|
sale = dict(transaction_id='sale', category='SERVICE_SALE', amount=price,
|
||||||
|
absolute_minute=n, source_entity_id='facility', credit_account='GUEST_WALLET:'+a.GUEST)
|
||||||
|
reservation = dict(reservation_id='reservation.b', requester_id=a.SECOND_REQUEST, state='ACTIVE', terminal_at=-1)
|
||||||
|
def point(minute, completed=False, broken=False, failed=False):
|
||||||
|
s, second, r = copy.deepcopy((primary, secondary, reservation))
|
||||||
|
history = []
|
||||||
|
active = [s, second]
|
||||||
|
if completed:
|
||||||
|
s.update(state='COMPLETED', completed_at=n, elapsed_minutes=45)
|
||||||
|
history.append(s)
|
||||||
|
active.remove(s)
|
||||||
|
if failed:
|
||||||
|
second.update(state='FAILED', failure_reason='BROKEN', completed_at=n+1)
|
||||||
|
history.append(second)
|
||||||
|
active.remove(second)
|
||||||
|
r.update(state='RELEASED', terminal_at=n+1)
|
||||||
|
ledger = [copy.deepcopy(sale)] if completed else []
|
||||||
|
requests = [] if failed else [dict(request_id=a.SECOND_REQUEST)]
|
||||||
|
return dict(minute=minute, inputs=dict(boundary=n, price=price, duration=45, facility_id='facility'),
|
||||||
|
service=s, facility=dict(durability=0 if broken else 100, state='BROKEN' if broken else 'OPERATING',
|
||||||
|
suspension_reason='DESTROYED' if broken else ''),
|
||||||
|
ledger=ledger, wallets={a.GUEST: 50-price if completed else 50, a.SECOND: 50},
|
||||||
|
receipts=[dict(id='sale', minute=n, phase='FACILITY_COMPLETION', entries=copy.deepcopy(ledger))] if completed else [],
|
||||||
|
reservations=[r], requests={a.SECOND_REQUEST: {} if failed else dict(request_id=a.SECOND_REQUEST)},
|
||||||
|
active_services=len(active), snapshot=dict(systems=dict(runtime=dict(
|
||||||
|
facilities=dict(service_history=history, instances=[dict(active_services=active)], requests=requests,
|
||||||
|
known_service_ids=['primary', 'secondary'], known_request_ids=[a.REQUEST, a.SECOND_REQUEST],
|
||||||
|
next_service_sequence=3),
|
||||||
|
economy=dict(entries=copy.deepcopy(ledger), idempotency=[dict(key='service.payment.primary', transaction_id='sale')] if completed else []),
|
||||||
|
inventory=dict(idempotency_results=[dict(action='release', result=dict(reservation_id='reservation.b', ok=True))] if failed else [])))))
|
||||||
|
phases = []
|
||||||
|
for name, completed, broken in [('FACILITY_COMPLETION', False, False),
|
||||||
|
('VITALS_AND_ENVIRONMENT', True, False),
|
||||||
|
('INCIDENTS_AND_EVENTS', True, False), ('FACILITY_QUEUES', True, True)]:
|
||||||
|
p = point(n, completed, broken)
|
||||||
|
p['phase'] = name
|
||||||
|
phases.append(p)
|
||||||
|
return dict(before=point(n-1), boundary=point(n, True, True), held=point(n+1, True, True, True)), phases
|
||||||
|
|
||||||
|
|
||||||
|
def paid_controls():
|
||||||
|
original = fixture()
|
||||||
|
def derive(data):
|
||||||
|
points, phases = data
|
||||||
|
return a.paid_before_incident({k: typed(v) for k, v in points.items()}, [typed(v) for v in phases])
|
||||||
|
assert derive(original) == {'paid_before_incident': True, 'duplicate_generations': 0}
|
||||||
|
checks = []
|
||||||
|
def negative(name, change):
|
||||||
|
data = copy.deepcopy(original)
|
||||||
|
change(*data)
|
||||||
|
try:
|
||||||
|
derive(data)
|
||||||
|
except (ValueError, KeyError):
|
||||||
|
checks.append(name)
|
||||||
|
return
|
||||||
|
raise AssertionError('accepted mutation: ' + name)
|
||||||
|
runtime = lambda p: p['snapshot']['systems']['runtime']
|
||||||
|
second = lambda p: next(s for s in runtime(p)['facilities']['service_history'] if s['request_id'] == a.SECOND_REQUEST)
|
||||||
|
negative('sale-removed', lambda p, h: p['boundary']['ledger'].clear())
|
||||||
|
negative('sale-duplicated', lambda p, h: p['held']['ledger'].append(copy.deepcopy(p['held']['ledger'][0])))
|
||||||
|
negative('sale-after-incidents', lambda p, h: p['boundary']['receipts'][0].update(phase='FACILITY_QUEUES'))
|
||||||
|
negative('destruction-before-completion', lambda p, h: h[0]['facility'].update(durability=0))
|
||||||
|
negative('primary-not-completed', lambda p, h: p['boundary']['service'].update(state='ACTIVE'))
|
||||||
|
negative('secondary-charged', lambda p, h: p['held']['wallets'].update({a.SECOND: 25}))
|
||||||
|
negative('secondary-not-failed', lambda p, h: second(p['held']).update(state='ACTIVE'))
|
||||||
|
negative('secondary-failed-at-N', lambda p, h: second(p['held']).update(completed_at=960))
|
||||||
|
negative('reservation-not-released', lambda p, h: p['held']['reservations'][0].update(state='ACTIVE'))
|
||||||
|
negative('reservation-released-twice', lambda p, h: runtime(p['held'])['inventory']['idempotency_results'].append(copy.deepcopy(runtime(p['held'])['inventory']['idempotency_results'][0])))
|
||||||
|
negative('idempotency-missing', lambda p, h: runtime(p['held'])['economy']['idempotency'].clear())
|
||||||
|
negative('idempotency-duplicated', lambda p, h: runtime(p['held'])['economy']['idempotency'].append(copy.deepcopy(runtime(p['held'])['economy']['idempotency'][0])))
|
||||||
|
negative('wrong-financial-day', lambda p, h: p['held']['ledger'][0].update(absolute_minute=2400))
|
||||||
|
negative('AFTER-copy-tautology', lambda p, h: p.update(before=copy.deepcopy(p['held'])))
|
||||||
|
negative('phase-order-reversed', lambda p, h: h.reverse())
|
||||||
|
negative('duplicate-generation', lambda p, h: runtime(p['held'])['facilities']['service_history'].append(copy.deepcopy(second(p['held']))))
|
||||||
|
negative('hidden-generation-counter', lambda p, h: runtime(p['held'])['facilities'].update(next_service_sequence=4))
|
||||||
|
return checks
|
||||||
|
|
||||||
|
|
||||||
|
def roster_controls():
|
||||||
|
cases, slots = list(wrapper.CASE_TABLE), wrapper.SLOTS
|
||||||
|
old = [c for c in cases if c != 'S5D_PAID_BEFORE_INCIDENT']
|
||||||
|
assert sorted(old) != old, 'old R43 comparison must fail on actual insertion order'
|
||||||
|
assert wrapper.exact_roster(cases, slots)
|
||||||
|
assert wrapper.exact_roster(cases[::-1], slots[::-1])
|
||||||
|
assert not wrapper.exact_roster(cases[:-1], slots)
|
||||||
|
assert not wrapper.exact_roster(cases + [cases[0]], slots)
|
||||||
|
assert not wrapper.exact_roster(cases + ['UNKNOWN'], slots)
|
||||||
|
assert not wrapper.exact_roster(cases, slots[:-1])
|
||||||
|
assert not wrapper.exact_roster(cases, slots + ['UNKNOWN-slot'])
|
||||||
|
assert not wrapper.exact_roster(cases, slots + [slots[0]])
|
||||||
|
assert set(cases) == set(a.DERIVERS) | set(a.power.CASES)
|
||||||
|
import re
|
||||||
|
probe = wrapper.QA.read_text()
|
||||||
|
seeds = json.loads(re.search(r'^const SEEDS: Dictionary = (.*)$', probe, re.M)[1])
|
||||||
|
assert set(seeds) == set(cases)
|
||||||
|
for row in wrapper.CASE_TABLE.values():
|
||||||
|
for key in ('prepare', 'advance', 'stop', 'assert'):
|
||||||
|
assert 'func ' + row[key] + '(' in probe
|
||||||
|
# Reader obtains its own branches directly from CASE_TABLE (never Writer's list).
|
||||||
|
reader = probe.split('func _reader()', 1)[1]
|
||||||
|
assert 'for branch: String in CASE_TABLE:' in reader
|
||||||
|
expected_line = next(l for l in a.POWER_PATH.read_text().splitlines() if 'expected = set(CASES)' in l)
|
||||||
|
assert set(re.findall(r'"(S5[^"]+)"', expected_line)) | set(a.power.CASES) == set(cases)
|
||||||
|
root = Path(__file__).resolve().parents[1]
|
||||||
|
project = next(p for p in root.parents if (p / 'tools/check_p04_order_evidence.py').is_file())
|
||||||
|
checker = (project / 'tools/check_p04_order_evidence.py').read_text()
|
||||||
|
assert set(re.findall(r"['\"](S5[A-Z][A-Z0-9_]*)['\"]", checker)) == set(cases)
|
||||||
|
collector = (root / 'p04_native_series.py').read_text()
|
||||||
|
assert "set(order['cases']) == set(adapter.DERIVERS)" in collector
|
||||||
|
assert "set(power['cases']) == set(adapter.power.CASES)" in collector
|
||||||
|
assert 'order = adapter.derive(*arguments)' in collector
|
||||||
|
for name in ('S5_ROOT_RUN.md', 'PENDING.md'):
|
||||||
|
assert set(re.findall(r'`(S5[A-Z][A-Z0-9_]*)`', (root / 's5' / name).read_text())) == set(cases)
|
||||||
|
status = (root / 'REPAIR41_STATUS.md').read_text().split('## REPAIR44', 1)[1]
|
||||||
|
assert set(re.findall(r'`(S5[A-Z][A-Z0-9_]*)`', status.split('## ', 1)[0])) == set(cases)
|
||||||
|
wrapper.probe_guard(project)
|
||||||
|
patterns = [r'\bvar\s+\w+\s*=', r'\bfor\s+\w+\s+in\b',
|
||||||
|
r'\.(?:patience_remaining|elapsed_minutes|power_available|capacity|hold_until)\s*=(?!=)']
|
||||||
|
for regex, bad in zip(patterns, ['var x = 1', 'for x in values:', 'f.capacity = 2']):
|
||||||
|
assert not re.search(regex, probe) and re.search(regex, bad)
|
||||||
|
return ['R43-old-comparison-reproduced', 'insertion-order', 'reverse-order',
|
||||||
|
'missing-case', 'duplicate-case', 'unknown-case', 'missing-slot', 'extra-slot',
|
||||||
|
'duplicate-slot', 'probe-seeds-wrapper-reader-adapter-collector-checker-docs-name-sync',
|
||||||
|
'probe-guard-regex-self-check']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = Path(__file__).resolve().parents[1]
|
||||||
|
assert not list(root.rglob('*.pyc')), 'no generated bytecode under allowed execution paths'
|
||||||
|
print(json.dumps(dict(synthetic_units_only=True, formal_acceptance=False,
|
||||||
|
paid_mutations=paid_controls(), roster=roster_controls(), no_pyc=True), indent=2))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -43,10 +43,17 @@ def case_table(path):
|
|||||||
|
|
||||||
|
|
||||||
CASE_TABLE = case_table(QA)
|
CASE_TABLE = case_table(QA)
|
||||||
CASES = list(CASE_TABLE)
|
CASES = sorted(CASE_TABLE)
|
||||||
LABELS = {case: [label for label in row["labels"] if label != "duplicate_guard"]
|
LABELS = {case: [label for label in CASE_TABLE[case]["labels"] if label != "duplicate_guard"]
|
||||||
for case, row in CASE_TABLE.items()}
|
for case in CASES}
|
||||||
SLOTS = sorted(case + "-" + label for case in CASES for label in LABELS[case])
|
SLOTS = sorted(case + "-" + label for case in CASES for label in LABELS[case])
|
||||||
|
|
||||||
|
def exact_roster(branches, slots):
|
||||||
|
return (len(branches) == len(set(branches)) == len(CASES)
|
||||||
|
and sorted(branches) == CASES
|
||||||
|
and len(slots) == len(set(slots)) == len(SLOTS)
|
||||||
|
and sorted(slots) == SLOTS)
|
||||||
|
|
||||||
MATERIALS = [MANIFEST, BUILD / "audit-support/p04-review-repair22-r01/ACTUAL_CURRENT_PUBLIC_POWER_FUNCTIONS.json"]
|
MATERIALS = [MANIFEST, BUILD / "audit-support/p04-review-repair22-r01/ACTUAL_CURRENT_PUBLIC_POWER_FUNCTIONS.json"]
|
||||||
|
|
||||||
def r17_relocation_guard(root):
|
def r17_relocation_guard(root):
|
||||||
@@ -66,6 +73,13 @@ def r17_relocation_guard(root):
|
|||||||
def probe_guard(root):
|
def probe_guard(root):
|
||||||
probe = QA.read_text()
|
probe = QA.read_text()
|
||||||
import re
|
import re
|
||||||
|
seeds = re.findall(r"^const SEEDS: Dictionary = (.*)$", probe, re.M)
|
||||||
|
if len(seeds) != 1 or sorted(json.loads(seeds[0])) != CASES or sorted(case_table(QA)) != CASES:
|
||||||
|
raise ValueError("probe/seed canonical roster mismatch")
|
||||||
|
for case in CASES:
|
||||||
|
for key in ("prepare", "advance", "stop", "assert"):
|
||||||
|
if "func " + CASE_TABLE[case][key] + "(" not in probe:
|
||||||
|
raise ValueError("missing case dispatch function")
|
||||||
if ":=" in probe or re.search(r"\bvar\s+\w+\s*=", probe) or re.search(r"\bfor\s+\w+\s+in\b", probe):
|
if ":=" in probe or re.search(r"\bvar\s+\w+\s*=", probe) or re.search(r"\bfor\s+\w+\s+in\b", probe):
|
||||||
raise ValueError("explicit typed declarations/loops required")
|
raise ValueError("explicit typed declarations/loops required")
|
||||||
if re.search(r"\.(?:patience_remaining|elapsed_minutes|power_available|capacity|hold_until)\s*=(?!=)", probe):
|
if re.search(r"\.(?:patience_remaining|elapsed_minutes|power_available|capacity|hold_until)\s*=(?!=)", probe):
|
||||||
@@ -522,7 +536,7 @@ def main():
|
|||||||
receipt = r.read(out / ("raw/" + phase + ".json"))
|
receipt = r.read(out / ("raw/" + phase + ".json"))
|
||||||
r.require(receipt["checks"] > 0 and receipt["failures"] == 0,
|
r.require(receipt["checks"] > 0 and receipt["failures"] == 0,
|
||||||
"S5 actual outcome receipt")
|
"S5 actual outcome receipt")
|
||||||
r.require(sorted(receipt["branches"]) == CASES,
|
r.require(exact_roster(receipt["branches"], receipt["slots"]),
|
||||||
"exact one independent Writer/Reader case")
|
"exact one independent Writer/Reader case")
|
||||||
r.require(sorted(receipt["slots"]) == SLOTS, "all formal point slots")
|
r.require(sorted(receipt["slots"]) == SLOTS, "all formal point slots")
|
||||||
r.require(receipt["pid"] == row["actual_pid"], "actual native PID/receipt")
|
r.require(receipt["pid"] == row["actual_pid"], "actual native PID/receipt")
|
||||||
|
|||||||
@@ -138,6 +138,82 @@ def destruction_raid_r40(points, phases):
|
|||||||
return {'raid_sale_before_destruction': True, 'raid_unfinished_release': True}
|
return {'raid_sale_before_destruction': True, 'raid_unfinished_release': True}
|
||||||
|
|
||||||
|
|
||||||
|
def paid_before_incident(points, phases):
|
||||||
|
"""Phase-start snapshots bracket completion and the public automatic event."""
|
||||||
|
before, boundary, end = (points[k] for k in ('before', 'boundary', 'held'))
|
||||||
|
n = scalar(before, 'inputs', 'boundary')
|
||||||
|
completion = phase(phases, 'FACILITY_COMPLETION', n)
|
||||||
|
completed = phase(phases, 'VITALS_AND_ENVIRONMENT', n)
|
||||||
|
incident = phase(phases, 'INCIDENTS_AND_EVENTS', n)
|
||||||
|
queues = phase(phases, 'FACILITY_QUEUES', n)
|
||||||
|
require([phases.index(p) for p in (completion, completed, incident, queues)] ==
|
||||||
|
sorted(phases.index(p) for p in (completion, completed, incident, queues)),
|
||||||
|
'completion/event/queue phase order')
|
||||||
|
require(scalar(before, 'minute') == n - 1 and scalar(boundary, 'minute') == n
|
||||||
|
and scalar(end, 'minute') == n + 1, 'exact boundary points')
|
||||||
|
for p in (before, completion):
|
||||||
|
require(scalar(p, 'service', 'state') == 'ACTIVE' and not sales(p)
|
||||||
|
and scalar(p, 'service', 'started_at') + scalar(p, 'service', 'duration_minutes') == n
|
||||||
|
and scalar(p, 'service', 'elapsed_minutes') == scalar(p, 'service', 'duration_minutes') - 1
|
||||||
|
and scalar(p, 'facility', 'durability') > 0, 'independent pre-completion state')
|
||||||
|
sale = payment(before, completed, n)
|
||||||
|
for p in (completed, incident, queues, boundary, end):
|
||||||
|
require(payment(before, p, n).raw == sale.raw, 'identical surviving sale')
|
||||||
|
require([r.raw for r in rows(p, 'ledger') if scalar(r, 'category') == 'SERVICE_SALE'] == [sale.raw],
|
||||||
|
'one total sale; secondary never charged')
|
||||||
|
require(scalar(p, 'wallets', SECOND) == scalar(before, 'wallets', SECOND), 'unchanged second wallet')
|
||||||
|
receipts = [r for r in rows(p, 'receipts') if scalar(r, 'id') == scalar(sale, 'transaction_id')]
|
||||||
|
require(len(receipts) == 1 and scalar(receipts[0], 'phase') == 'FACILITY_COMPLETION'
|
||||||
|
and scalar(receipts[0], 'minute') == n, 'payment emitted in completion phase')
|
||||||
|
require(scalar(sale, 'absolute_minute') // 1440 + 1 == n // 1440 + 1,
|
||||||
|
'financial day derived from ledger absolute_minute')
|
||||||
|
require(scalar(completed, 'facility', 'durability') > 0
|
||||||
|
and scalar(incident, 'facility', 'durability') > 0, 'destruction not before incidents')
|
||||||
|
for p in (queues, boundary, end):
|
||||||
|
require(scalar(p, 'facility', 'durability') == 0 and scalar(p, 'facility', 'state') == 'BROKEN'
|
||||||
|
and scalar(p, 'facility', 'suspension_reason') == 'DESTROYED', 'event destruction at N')
|
||||||
|
|
||||||
|
def services(p):
|
||||||
|
facilities = field(p, 'snapshot', 'systems', 'runtime', 'facilities')
|
||||||
|
return (rows(facilities, 'service_history') +
|
||||||
|
[s for f in rows(facilities, 'instances') for s in rows(f, 'active_services')])
|
||||||
|
|
||||||
|
baseline = services(before)
|
||||||
|
ids = [scalar(s, 'service_id') for s in baseline]
|
||||||
|
require(len(ids) == len(set(ids)) == 2, 'exactly two independent original service IDs')
|
||||||
|
second_id = None
|
||||||
|
for p in (before, completion, completed, incident, queues, boundary, end):
|
||||||
|
current = services(p)
|
||||||
|
require(sorted(scalar(s, 'service_id') for s in current) == sorted(ids), 'zero duplicate generations')
|
||||||
|
for key in ('known_service_ids', 'known_request_ids', 'next_service_sequence'):
|
||||||
|
require(field(p, 'snapshot', 'systems', 'runtime', 'facilities', key).raw ==
|
||||||
|
field(before, 'snapshot', 'systems', 'runtime', 'facilities', key).raw,
|
||||||
|
'stable service/request generation bookkeeping: ' + key)
|
||||||
|
secondary = [s for s in current if scalar(s, 'request_id') == SECOND_REQUEST]
|
||||||
|
require(len(secondary) == 1, 'one secondary request/service join')
|
||||||
|
s = secondary[0]
|
||||||
|
if second_id is None:
|
||||||
|
second_id = scalar(s, 'service_id')
|
||||||
|
require(scalar(s, 'service_id') == second_id, 'secondary identity unchanged')
|
||||||
|
if p is end:
|
||||||
|
require(scalar(s, 'state') == 'FAILED' and scalar(s, 'failure_reason') == 'BROKEN'
|
||||||
|
and scalar(s, 'completed_at') == n + 1, 'secondary failed once at N+1')
|
||||||
|
else:
|
||||||
|
require(scalar(s, 'state') == 'ACTIVE' and scalar(s, 'elapsed_minutes') < scalar(s, 'duration_minutes')
|
||||||
|
and scalar(s, 'started_at') == n - 1, 'secondary unfinished through N')
|
||||||
|
reservation = [r for r in rows(p, 'reservations') if scalar(r, 'requester_id') == SECOND_REQUEST]
|
||||||
|
require(len(reservation) == 1 and scalar(reservation[0], 'state') == 'ACTIVE', 'secondary reservation held through N')
|
||||||
|
require(not [r for r in rows(p, 'snapshot', 'systems', 'runtime', 'inventory', 'idempotency_results')
|
||||||
|
if scalar(r, 'action') == 'release'
|
||||||
|
and scalar(r, 'result', 'reservation_id') == scalar(reservation[0], 'reservation_id')],
|
||||||
|
'no early secondary release')
|
||||||
|
release(before, end, SECOND_REQUEST, n + 1)
|
||||||
|
require(not rows(end, 'snapshot', 'systems', 'runtime', 'facilities', 'requests')
|
||||||
|
and all(scalar(r, 'state') != 'ACTIVE' for r in rows(end, 'reservations'))
|
||||||
|
and scalar(end, 'active_services') == 0, 'no reservation or orphan request remains')
|
||||||
|
return {'paid_before_incident': True, 'duplicate_generations': 0}
|
||||||
|
|
||||||
|
|
||||||
def destruction_raid(points, phases):
|
def destruction_raid(points, phases):
|
||||||
before = points['before']
|
before = points['before']
|
||||||
n = scalar(before, 'inputs', 'boundary')
|
n = scalar(before, 'inputs', 'boundary')
|
||||||
@@ -333,7 +409,8 @@ def exit_order(points, phases):
|
|||||||
|
|
||||||
|
|
||||||
DERIVERS = {'S5C_DESTRUCTION_COMMAND': destruction_command, 'S5D_DESTRUCTION_RAID': destruction_raid,
|
DERIVERS = {'S5C_DESTRUCTION_COMMAND': destruction_command, 'S5D_DESTRUCTION_RAID': destruction_raid,
|
||||||
'S5D_IN_FLIGHT': destruction_in_flight, 'S5G_SHIFT_1080': shift_completion,
|
'S5D_IN_FLIGHT': destruction_in_flight, 'S5D_PAID_BEFORE_INCIDENT': paid_before_incident,
|
||||||
|
'S5G_SHIFT_1080': shift_completion,
|
||||||
'S5H_PAUSED_MIDNIGHT': paused_midnight, 'S5E_MIDNIGHT': midnight_day, 'S5F_EXIT': exit_order}
|
'S5H_PAUSED_MIDNIGHT': paused_midnight, 'S5E_MIDNIGHT': midnight_day, 'S5F_EXIT': exit_order}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+35
@@ -148,6 +148,41 @@ def main():
|
|||||||
return
|
return
|
||||||
raise ValueError('mutation accepted: ' + label)
|
raise ValueError('mutation accepted: ' + label)
|
||||||
|
|
||||||
|
paid = 'S5D_PAID_BEFORE_INCIDENT'
|
||||||
|
points, phases = cases[paid]
|
||||||
|
end, boundary = points['held'], points['boundary']
|
||||||
|
n = a.scalar(points['before'], 'inputs', 'boundary')
|
||||||
|
def changed_array(node, members):
|
||||||
|
start = 12 if node.raw[:4] == struct.pack('<I', 65564) else 8
|
||||||
|
return node.raw[:start-4] + struct.pack('<I', len(members)) + b''.join(r.raw for r in members)
|
||||||
|
sale = a.sales(end)[0]
|
||||||
|
ledger = a.field(end, 'ledger')
|
||||||
|
negative('paid-sale-removed', paid, end, ledger, changed_array(ledger, [r for r in ledger.value if r is not sale]))
|
||||||
|
negative('paid-sale-duplicated', paid, end, ledger, changed_array(ledger, ledger.value + [sale]))
|
||||||
|
receipt = next(r for r in a.rows(end, 'receipts') if a.scalar(r, 'id') == a.scalar(sale, 'transaction_id'))
|
||||||
|
negative('paid-sale-after-incidents', paid, end, a.field(receipt, 'phase'), mutation.scalar(4, 'FACILITY_QUEUES'))
|
||||||
|
pre = a.phase(phases, 'FACILITY_COMPLETION', n)
|
||||||
|
negative('paid-destruction-before-completion', paid, pre, a.field(pre, 'facility', 'durability'), mutation.scalar(2, 0))
|
||||||
|
negative('paid-primary-not-completed', paid, end, a.field(end, 'service', 'state'), mutation.scalar(4, 'ACTIVE'))
|
||||||
|
negative('paid-secondary-charged', paid, end, a.field(end, 'wallets', a.SECOND), mutation.scalar(2, a.scalar(end, 'wallets', a.SECOND)-1))
|
||||||
|
secondary = next(r for r in a.rows(end, 'snapshot', 'systems', 'runtime', 'facilities', 'service_history')
|
||||||
|
if a.scalar(r, 'request_id') == a.SECOND_REQUEST)
|
||||||
|
negative('paid-secondary-not-failed', paid, end, a.field(secondary, 'state'), mutation.scalar(4, 'ACTIVE'))
|
||||||
|
negative('paid-secondary-failed-at-N', paid, end, a.field(secondary, 'completed_at'), mutation.scalar(2, n))
|
||||||
|
reservation = next(r for r in a.rows(end, 'reservations') if a.scalar(r, 'requester_id') == a.SECOND_REQUEST)
|
||||||
|
negative('paid-reservation-held', paid, end, a.field(reservation, 'state'), mutation.scalar(4, 'ACTIVE'))
|
||||||
|
operations = a.field(end, 'snapshot', 'systems', 'runtime', 'inventory', 'idempotency_results')
|
||||||
|
released = next(r for r in operations.value if a.scalar(r, 'action') == 'release'
|
||||||
|
and a.scalar(r, 'result', 'reservation_id') == a.scalar(reservation, 'reservation_id'))
|
||||||
|
negative('paid-double-release', paid, end, operations, changed_array(operations, operations.value + [released]))
|
||||||
|
idem = a.field(end, 'snapshot', 'systems', 'runtime', 'economy', 'idempotency')
|
||||||
|
key = 'service.payment.' + a.scalar(end, 'service', 'service_id')
|
||||||
|
payment = next(r for r in idem.value if a.scalar(r, 'key') == key)
|
||||||
|
negative('paid-idempotency-missing', paid, end, idem, changed_array(idem, [r for r in idem.value if r is not payment]))
|
||||||
|
negative('paid-idempotency-duplicate', paid, end, idem, changed_array(idem, idem.value + [payment]))
|
||||||
|
negative('paid-wrong-day', paid, end, a.field(sale, 'absolute_minute'), mutation.scalar(2, n+1440))
|
||||||
|
negative('paid-AFTER-copy', paid, points['before'], points['before'], end.raw)
|
||||||
|
|
||||||
midnight = 'S5E_MIDNIGHT'
|
midnight = 'S5E_MIDNIGHT'
|
||||||
points, phases = cases[midnight]
|
points, phases = cases[midnight]
|
||||||
n = a.scalar(points['before'], 'inputs', 'boundary')
|
n = a.scalar(points['before'], 'inputs', 'boundary')
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ def derive(root, writer_sha, reader_sha):
|
|||||||
writer = json.loads(raw.pin(root / "writer.json", writer_sha), object_pairs_hook=unique)
|
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)
|
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(writer["pid"] != reader["pid"] and writer["profile"] != reader["profile"], "independent reader required")
|
||||||
expected = set(CASES) | {"S5C_DESTRUCTION_COMMAND", "S5D_DESTRUCTION_RAID", "S5D_IN_FLIGHT", "S5E_MIDNIGHT", "S5F_EXIT", "S5G_SHIFT_1080", "S5H_PAUSED_MIDNIGHT"}
|
expected = set(CASES) | {"S5C_DESTRUCTION_COMMAND", "S5D_DESTRUCTION_RAID", "S5D_IN_FLIGHT", "S5D_PAID_BEFORE_INCIDENT", "S5E_MIDNIGHT", "S5F_EXIT", "S5G_SHIFT_1080", "S5H_PAUSED_MIDNIGHT"}
|
||||||
historical_roster = set(CASES) | {"S5C_DESTRUCTION_COMMAND", "S5D_DESTRUCTION_RAID", "S5E_MIDNIGHT", "S5F_EXIT"}
|
historical_roster = set(CASES) | {"S5C_DESTRUCTION_COMMAND", "S5D_DESTRUCTION_RAID", "S5E_MIDNIGHT", "S5F_EXIT"}
|
||||||
require(set(writer["branches"]) == set(reader["branches"]) and
|
require(set(writer["branches"]) == set(reader["branches"]) and
|
||||||
set(writer["branches"]) in (set(CASES), historical_roster, expected), "exact pair or full case table roster")
|
set(writer["branches"]) in (set(CASES), historical_roster, expected), "exact pair or full case table roster")
|
||||||
|
|||||||
@@ -1157,7 +1157,8 @@ def combine_native_series(directory, native):
|
|||||||
'D05-P04-DESTRUCTION': [('S5C_DESTRUCTION_COMMAND', 'command_destruction_before_completion'),
|
'D05-P04-DESTRUCTION': [('S5C_DESTRUCTION_COMMAND', 'command_destruction_before_completion'),
|
||||||
('S5D_DESTRUCTION_RAID', 'G1'), ('S5D_IN_FLIGHT', 'G2'),
|
('S5D_DESTRUCTION_RAID', 'G1'), ('S5D_IN_FLIGHT', 'G2'),
|
||||||
('S5D_DESTRUCTION_RAID', 'idle_objective_breach'),
|
('S5D_DESTRUCTION_RAID', 'idle_objective_breach'),
|
||||||
('S5D_IN_FLIGHT', 'in_flight_destruction')],
|
('S5D_IN_FLIGHT', 'in_flight_destruction'),
|
||||||
|
('S5D_PAID_BEFORE_INCIDENT', 'paid_before_incident')],
|
||||||
'D05-P04-MIDNIGHT-DAY': [('S5E_MIDNIGHT', 'midnight_close_upkeep_before_sale'),
|
'D05-P04-MIDNIGHT-DAY': [('S5E_MIDNIGHT', 'midnight_close_upkeep_before_sale'),
|
||||||
('S5E_MIDNIGHT', 'midnight_new_day_sale')],
|
('S5E_MIDNIGHT', 'midnight_new_day_sale')],
|
||||||
'D05-P04-EXIT': [('S5F_EXIT', 'command_exit_before_start'), ('S5F_EXIT', 'planned_exit_after_completion')],
|
'D05-P04-EXIT': [('S5F_EXIT', 'command_exit_before_start'), ('S5F_EXIT', 'planned_exit_after_completion')],
|
||||||
|
|||||||
Reference in New Issue
Block a user