Preserve EQ S2 evidence and source-backed S3a continuation

This commit is contained in:
Codex
2026-10-21 08:47:37 +09:00
parent e29e743ab3
commit f50e2752bc
10 changed files with 1004 additions and 82 deletions
@@ -0,0 +1 @@
{"action":"request-repair","task_id":"P28-02-EQ","reason":"Stage S2 run 558b96b3fe5e462296e85bc591622d1c ended as planned after 846.159 s: formal status blocked with the low finding 'stage S2 complete, next S3'. This is a staged checkpoint, not a failure. No S, repairs 4, no active run. Root preserved 30 files and 6 raw pins (retained-s2-558b96b-r01/RETURN.json SHA 6f4f2b8ce8be7c4236368ffde9bbbd2805748a894b95ea8f42385169fdc78129) and joined the local results (ROOT_S2_LOCAL_JOIN_558B96B.json SHA bbe7975d20c08f4af6dde4ba87f30ec7e3c80bf86ca321fc6d2a6a73cc8dde84). The unit runs went 68, then 71, then 72 tests, each with exit code 0, and the final output SHA 9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698 matches the raw stdout. The S1 comparator, all 43 S1 test bodies, the failure history and the frozen materials are unchanged; tracked source is unchanged and every change is inside eq/. The 72 local tests are not acceptance. A read-only static check, confirmed by Root against the source, found two checker false-PASS defects for S3 to fix. First, check_eq.py:109 accepts an empty or partial phase-key set. Second, check_eq.py:147-150 accepts a single snapshot_published/state_updated line instead of the actual per-minute count and order. Because S2 took 846 s, close to the unchanged 900-second limit, S3 is split into S3a and S3b in EQ_S3_STAGE_PLAN.txt without changing any requirement. S3a is the two checker fixes with negative tests plus E3 rejection. S3b is E4 cache staleness and E5 ownership. SPEC, TASK, the 6 conditions, eq/references, eq/registration and clarifications r01, r02 and r03 are unchanged. Request the normal repair so the same W continues with S3a. Decided by Claude Opus 5.5 in the Desktop control session (message 328); not a CLI commander result."}
@@ -0,0 +1 @@
{"action":"run","task_id":"P28-02-EQ","reason":"Use only after Root verifies through the normal gates: repair_ready, repairs 5, no S submitted, no active run, and the S1 and S2 files still present unchanged in the W. Run repair 5 of P28-02-EQ once on the same W from base 2549cf7d6992560b850bbd11934e3c14b39a1988 with the single worker codex gpt-6-astra, doing only stage S3a of EQ_S3_STAGE_PLAN.txt, under EQ_STAGED_IMPLEMENTATION_PLAN r01 and r02. Start by reading eq/PROGRESS.md and eq/IMPLEMENTATION.md and reuse the S1/S2 types, paths, record schema, API and notes without redesign. Do not delete or rewrite S1/S2 code or test bodies, except for the two checker fixes and fixes a failing test requires. Keep the failure history. S3a scope: (1) check_eq.py:109 must require each checkpoint's immutable-snapshot phase keys to be exactly {0..10}, with negative tests for empty, missing, out-of-range and duplicate representations. (2) check_eq.py:147-150 must check, for every minute of the 30 measured ticks, the actual count and order of snapshot_published then state_updated emitted by _publish_snapshot (simulation_runtime.gd:12616-12621), bound to that minute's checkpoint. The expected count comes from the recorded actual connection state, because state_updated alone is emitted when snapshot_published has no connection (:12619). Scenario signals are kept in a separate interval record. Add negative tests for missing, partial, duplicated, reordered and shifted minutes and for scenario-signal contamination. (3) E3 rejection in a dedicated scenario interval for both R and O: restore_snapshot, SimulationSnapshot.validate and load_from_path each receive at least one input with a missing key, a wrong type, an out-of-range value, a duplicate ID (published_ids and facility ID) and a world.bin tamper under r03 D3. The inputs are built from a deep copy of B1 by fixed rules, with no randomness or time. Record the return value and code, the before/after full S/K/C, and the event difference and count: a direct restore emits 0 SAVE_* events; a failed load emits exactly 1 SAVE_LOAD_FAILED equal to X(B, ev_fail) after r03 normalization. A product failure is recorded as an existing defect, never as PASS. Add checker rules and tests for these. State-changing calls are allowed only inside the listed scenario interval, and check_eq.py's static allowance is limited to that. Run the engine-free python3 test_eq.py until every existing test passes, save the raw output, update PROGRESS.md, and end S3a with formal status blocked and the finding 'stage S3a complete (not a failure; next is S3b)'. Do not submit. Deliver as the one supplementary key EQ_S3_STAGE_PLAN.txt, both staged plans and this decision; clarifications r01, r02 and r03 stay read-only in build/eq-staged-readonly-r04. No engine, no git write or commit, no product change, no full regression; SPEC, TASK, eq/references and eq/registration stay unchanged. Ordinary implementation choices are recorded without stopping; block only for undecided matters affecting original product spec, values, permissions, billing or original acceptance. The remaining order is S3b, then S4 and submission, then Root native in 7 phases, then both validations, then a fresh independent Opus review of all 6 conditions, then the normal integration and final. No original credit (23/88, 4/30); the 900-second timeout is unchanged. Quota fallback only on structured provider quota, once, same role, Antigravity claude-opus-5-5-high; any other failure is blocked. Decided by Claude Opus 5.5 in the Desktop control session (message 328); not a CLI commander result."}
@@ -0,0 +1 @@
{"action":"run","task_id":"P28-02-EQ","reason":"Supersedes DESKTOP_EQ_S3A_RUN_DECISION.json, which is kept unchanged as history. DESKTOP_EQ_S3A_REPAIR_DECISION.json stays valid as written: its facts (S2 checkpoint, the two checker defects, the S3a/S3b split) are unchanged by this correction. Use only after Root verifies through the normal gates: repair_ready, repairs 5, no S submitted, no active run, and the S1 and S2 files still present unchanged in the W. Run repair 5 of P28-02-EQ once on the same W from base 2549cf7d6992560b850bbd11934e3c14b39a1988 with the single worker codex gpt-6-astra, doing only stage S3a as defined in EQ_S3_STAGE_PLAN.txt and replaced in part by EQ_S3_STAGE_PLAN_R02.txt, under EQ_STAGED_IMPLEMENTATION_PLAN r01 and r02. Start by reading eq/PROGRESS.md and eq/IMPLEMENTATION.md and reuse the S1/S2 types, paths, schema, API and notes without redesign. Do not delete or rewrite S1/S2 code or test bodies, except for the two checker fixes and fixes a failing test requires. Keep the failure history. S3a scope: (1) check_eq.py:109 must require the exact phase-key set {0..10}. (2) check_eq.py:147-150 must require exactly one snapshot_published then state_updated pair for each of the 30 measured minutes, bound to the checkpoint minute and to a recorded connection inventory that contains the probe's own snapshot_published connection. A missing probe connection fails; it is never downgraded to a state-only expectation. The product's unconnected case is out of this interval's scope, and scenario signals are kept separate. (3) E3 uses the source-backed table. restore_snapshot returns its bool with code null and reason 'API returns bool only'. validate returns its full {ok, errors} with code null and reason 'API returns ok/errors only'. load_from_path returns a real code, and a missing code there is a failure. Missing key, wrong type and out-of-range are applied to all three APIs by fixed rules (clock removal, string absolute_minute and speed 9 for the Dictionary APIs; checksum_world removal, string format_version and an unsupported format_version for the package). Duplicate published_ids is applied to restore and, if SaveService.save_snapshot accepts it, to load; it is NA for envelope validate. Duplicate facility is applied in R and is NA in O when B1 actually has 0 facilities, recorded with the count and with no construction, no R substitution and no invented values. world.bin tamper is load only, by r03 D3. Record full before/after S/K/C, the event difference and count (0 for restore and validate; exactly 1 SAVE_LOAD_FAILED equal to X(B, ev_fail) for failed loads), and the applied/NA table. Mismatches are kept as existing-defect candidates; envelope validate accepting an internal duplicate is not called a product defect. Add the listed checker rules and negative tests. State-changing calls are allowed only inside the listed scenario interval. Run the engine-free python3 test_eq.py until every existing test passes, save the raw output, update PROGRESS.md, and end S3a with formal status blocked and the finding 'stage S3a complete (not a failure; next is S3b)'. Do not submit. Deliver as the one supplementary key both S3 plans, both staged plans and this decision; clarifications r01, r02 and r03 stay read-only in build/eq-staged-readonly-r04. No engine, no git write or commit, no product change, no full regression; SPEC, TASK, eq/references and eq/registration stay unchanged. Ordinary implementation choices are recorded without stopping; block only for undecided matters affecting original product spec, values, permissions, billing or original acceptance. The remaining order is S3b, then S4 and submission, then Root native in 7 phases, then both validations, then a fresh independent Opus review of all 6 conditions, then the normal integration and final. No original credit (23/88, 4/30); the 900-second timeout is unchanged. Quota fallback only on structured provider quota, once, same role, Antigravity claude-opus-5-5-high; any other failure is blocked. Decided by Claude Opus 5.5 in the Desktop control session (message 330); not a CLI commander result."}
@@ -0,0 +1,477 @@
{
"at_jst": "2026-10-21T08:46:08.565024+09:00",
"plan_id": "P28-02",
"support_project": "the-tree-p28-02-eq",
"support_task": "P28-02-EQ",
"base": "2549cf7d6992560b850bbd11934e3c14b39a1988",
"stage": "S2 local evidence only",
"actual_run": {
"id": "558b96b3fe5e462296e85bc591622d1c",
"task_id": "P28-02-EQ",
"role": "implementer",
"service": "codex",
"status": "finished",
"pid": 12205,
"started": 1792537978.637717,
"finished": 1792538824.796691,
"exit_code": 0,
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p28-02-eq/runs/558b96b3fe5e462296e85bc591622d1c",
"api_cost_usd": null,
"estimated_cost_usd": null,
"subscription_usage": null,
"usage_json": "{\"input_tokens\": 2214984, \"cached_input_tokens\": 2007168, \"cache_write_input_tokens\": 0, \"output_tokens\": 41770, \"reasoning_output_tokens\": 4112}"
},
"retained_return": {
"path": "artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/RETURN.json",
"bytes": 28328,
"sha256": "6f4f2b8ce8be7c4236368ffde9bbbd2805748a894b95ea8f42385169fdc78129"
},
"local_raw_join": {
"path": "artifacts/original-completion-2026-10-02/p28-02-root-control-r01/ROOT_S2_LOCAL_JOIN_558B96B.json",
"bytes": 1496,
"sha256": "bbe7975d20c08f4af6dde4ba87f30ec7e3c80bf86ca321fc6d2a6a73cc8dde84"
},
"local_unit": {
"at_jst": "2026-10-21T08:29:18.393150+09:00",
"stage": "S2",
"actual_run": "558b96b3fe5e462296e85bc591622d1c",
"retained_return_sha256": "6f4f2b8ce8be7c4236368ffde9bbbd2805748a894b95ea8f42385169fdc78129",
"unit_output_sha256": "9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698",
"actual_unit_counts": [
68,
71,
72
],
"embedded_test_exit_codes": [
0,
0,
0
],
"final_unit_checks": 72,
"all43_prior_S1_test_bodies_preserved": true,
"S1_final_output_preserved": true,
"frozen_and_historical_files_unchanged": [
"UNIT_OUTPUT_ATTEMPT_01.sha256",
"UNIT_OUTPUT_ATTEMPT_02.sha256",
"compare_versions.py",
"SPEC.md",
"UNIT_OUTPUT_ATTEMPT_02.txt",
"TASK_INSTRUCTIONS.md",
"UNIT_OUTPUT_ATTEMPT_01.txt",
"registration/CONFIG_PROPOSAL.json",
"registration/ACCEPTANCE_BASELINE.json",
"registration/ROOT_PROPOSAL_BYTE_TRANSFER.json",
"registration/REGISTRATION_PROPOSAL.json",
"references/OPUS_D2_SCOPE_CLARIFICATION.txt",
"references/OPUS_STARTUP_LIFECYCLE_CLARIFICATION.txt",
"references/OPT_CONTRACT_T1.md"
],
"all_tracked_source_unchanged": true,
"all_changes_in_allowed_scope": true,
"formal_EQ_accepted": false,
"all6_acceptance_pending": true,
"original_credit": 0,
"remaining_source_findings": "Two read-only pre-S3 findings: require full phase-handler key set and exact core snapshot/state signal coverage. Actual Opus judgment is required for the repair batch."
},
"all30_retained_files": [
{
"relative": "IMPLEMENTATION.md",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/IMPLEMENTATION.md",
"bytes": 16705,
"sha256": "382945c558161d5b83b5afb355d883d0741bb774eaca485b3a0c2052ed5348c4"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/IMPLEMENTATION.md",
"bytes": 16705,
"sha256": "382945c558161d5b83b5afb355d883d0741bb774eaca485b3a0c2052ed5348c4"
}
},
{
"relative": "PROGRESS.md",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/PROGRESS.md",
"bytes": 3911,
"sha256": "c461104c60775d3f9728a7c6e5e19554b33700578aead88c208741c5b2d4d052"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/PROGRESS.md",
"bytes": 3911,
"sha256": "c461104c60775d3f9728a7c6e5e19554b33700578aead88c208741c5b2d4d052"
}
},
{
"relative": "S2_SUPPLEMENTARY.json",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/S2_SUPPLEMENTARY.json",
"bytes": 19208,
"sha256": "26f23bd8650a2495fd93f4364cbb17cc34f9eb1568758d406bec12ae2dab83a7"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/S2_SUPPLEMENTARY.json",
"bytes": 19208,
"sha256": "26f23bd8650a2495fd93f4364cbb17cc34f9eb1568758d406bec12ae2dab83a7"
}
},
{
"relative": "SPEC.md",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/SPEC.md",
"bytes": 10693,
"sha256": "3791ccdcb87e8d71fe9205e1e692ebca9e0f974ea3b5fbc4fbb3943882131f1c"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/SPEC.md",
"bytes": 10693,
"sha256": "3791ccdcb87e8d71fe9205e1e692ebca9e0f974ea3b5fbc4fbb3943882131f1c"
}
},
{
"relative": "TASK_INSTRUCTIONS.md",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/TASK_INSTRUCTIONS.md",
"bytes": 2961,
"sha256": "f9937c3c7dff5a25ada453365d26c87fecf009d29518724f0c1e67d2b18afff3"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/TASK_INSTRUCTIONS.md",
"bytes": 2961,
"sha256": "f9937c3c7dff5a25ada453365d26c87fecf009d29518724f0c1e67d2b18afff3"
}
},
{
"relative": "UNIT_OUTPUT.sha256",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT.sha256",
"bytes": 82,
"sha256": "b1ca8148217f769c3d3933f74592d5f012972f956562f0ffb5283f34bfd46d98"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT.sha256",
"bytes": 82,
"sha256": "b1ca8148217f769c3d3933f74592d5f012972f956562f0ffb5283f34bfd46d98"
}
},
{
"relative": "UNIT_OUTPUT.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT.txt",
"bytes": 4693,
"sha256": "9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT.txt",
"bytes": 4693,
"sha256": "9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698"
}
},
{
"relative": "UNIT_OUTPUT_ATTEMPT_01.sha256",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_ATTEMPT_01.sha256",
"bytes": 93,
"sha256": "eed78af7775a79838e65ea3cb07e9fe09822d2d7a23007f294cbf0a0c98d1c7c"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_ATTEMPT_01.sha256",
"bytes": 93,
"sha256": "eed78af7775a79838e65ea3cb07e9fe09822d2d7a23007f294cbf0a0c98d1c7c"
}
},
{
"relative": "UNIT_OUTPUT_ATTEMPT_01.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_ATTEMPT_01.txt",
"bytes": 3368,
"sha256": "307486177b76602cbe68acae24c9560d501b3b866136d8e69802ec24c28e8be8"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_ATTEMPT_01.txt",
"bytes": 3368,
"sha256": "307486177b76602cbe68acae24c9560d501b3b866136d8e69802ec24c28e8be8"
}
},
{
"relative": "UNIT_OUTPUT_ATTEMPT_02.sha256",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_ATTEMPT_02.sha256",
"bytes": 93,
"sha256": "1de0c0052e66cc60668690bf43e29eb01808afd023525e517ba94beaab0db669"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_ATTEMPT_02.sha256",
"bytes": 93,
"sha256": "1de0c0052e66cc60668690bf43e29eb01808afd023525e517ba94beaab0db669"
}
},
{
"relative": "UNIT_OUTPUT_ATTEMPT_02.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_ATTEMPT_02.txt",
"bytes": 2699,
"sha256": "07144a7f1941162227f54fefd1961ed0f209e97282432723bbda534079582e4e"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_ATTEMPT_02.txt",
"bytes": 2699,
"sha256": "07144a7f1941162227f54fefd1961ed0f209e97282432723bbda534079582e4e"
}
},
{
"relative": "UNIT_OUTPUT_S1_FINAL.sha256",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S1_FINAL.sha256",
"bytes": 91,
"sha256": "91d9d408ed8d012f38ff892fa6712d129f4849d0ce0b579eaeb7cb1a3f84b704"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S1_FINAL.sha256",
"bytes": 91,
"sha256": "91d9d408ed8d012f38ff892fa6712d129f4849d0ce0b579eaeb7cb1a3f84b704"
}
},
{
"relative": "UNIT_OUTPUT_S1_FINAL.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S1_FINAL.txt",
"bytes": 2839,
"sha256": "cdca0cdd551ce76c6100c4dd90e04559551f9d88c054a19a2bc6a77e6572ae15"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S1_FINAL.txt",
"bytes": 2839,
"sha256": "cdca0cdd551ce76c6100c4dd90e04559551f9d88c054a19a2bc6a77e6572ae15"
}
},
{
"relative": "UNIT_OUTPUT_S2_ATTEMPT_01.sha256",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S2_ATTEMPT_01.sha256",
"bytes": 96,
"sha256": "579254585137adf932f5e4a0eaa2b0ecd67d275ece6c7199bdafbee4b48f4f5d"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S2_ATTEMPT_01.sha256",
"bytes": 96,
"sha256": "579254585137adf932f5e4a0eaa2b0ecd67d275ece6c7199bdafbee4b48f4f5d"
}
},
{
"relative": "UNIT_OUTPUT_S2_ATTEMPT_01.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S2_ATTEMPT_01.txt",
"bytes": 4395,
"sha256": "25953dfc5f8bc3759ae66f6403b162100fb0217c4476f308616b8ab78a2cc67e"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S2_ATTEMPT_01.txt",
"bytes": 4395,
"sha256": "25953dfc5f8bc3759ae66f6403b162100fb0217c4476f308616b8ab78a2cc67e"
}
},
{
"relative": "UNIT_OUTPUT_S2_ATTEMPT_02.sha256",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S2_ATTEMPT_02.sha256",
"bytes": 96,
"sha256": "f4094cc3a8924b79316f473b8b4027a4743036d9d9cf8b2ad0c492ff7b581756"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S2_ATTEMPT_02.sha256",
"bytes": 96,
"sha256": "f4094cc3a8924b79316f473b8b4027a4743036d9d9cf8b2ad0c492ff7b581756"
}
},
{
"relative": "UNIT_OUTPUT_S2_ATTEMPT_02.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S2_ATTEMPT_02.txt",
"bytes": 4617,
"sha256": "e26c986dda41b83143723e4c1c5b2ff1051a36b9a947b319341a2239cc3188de"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S2_ATTEMPT_02.txt",
"bytes": 4617,
"sha256": "e26c986dda41b83143723e4c1c5b2ff1051a36b9a947b319341a2239cc3188de"
}
},
{
"relative": "UNIT_OUTPUT_S2_ATTEMPT_03.sha256",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S2_ATTEMPT_03.sha256",
"bytes": 96,
"sha256": "d8f8f7a9be6b2fb1618a1ff03f9af5aa0e397373c5e8f9716dc47befa6e3bb83"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S2_ATTEMPT_03.sha256",
"bytes": 96,
"sha256": "d8f8f7a9be6b2fb1618a1ff03f9af5aa0e397373c5e8f9716dc47befa6e3bb83"
}
},
{
"relative": "UNIT_OUTPUT_S2_ATTEMPT_03.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/UNIT_OUTPUT_S2_ATTEMPT_03.txt",
"bytes": 4693,
"sha256": "9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/UNIT_OUTPUT_S2_ATTEMPT_03.txt",
"bytes": 4693,
"sha256": "9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698"
}
},
{
"relative": "check_eq.py",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/check_eq.py",
"bytes": 17595,
"sha256": "59e303d6dc3e14ec22b290b3fa102a6249eec68363565c070cca6e9e9f24cac8"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/check_eq.py",
"bytes": 17595,
"sha256": "59e303d6dc3e14ec22b290b3fa102a6249eec68363565c070cca6e9e9f24cac8"
}
},
{
"relative": "compare_versions.py",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py",
"bytes": 32313,
"sha256": "058f3fef57c2ebe6951a48d85d570a110b982e08a13c805c244fec7d5e9a0fe8"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/compare_versions.py",
"bytes": 32313,
"sha256": "058f3fef57c2ebe6951a48d85d570a110b982e08a13c805c244fec7d5e9a0fe8"
}
},
{
"relative": "eq_probe.gd",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/eq_probe.gd",
"bytes": 23575,
"sha256": "7ad4556885b2c44a57f1857f978edc35a9bc02467f9f5d852d0220ecabbcb5fe"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/eq_probe.gd",
"bytes": 23575,
"sha256": "7ad4556885b2c44a57f1857f978edc35a9bc02467f9f5d852d0220ecabbcb5fe"
}
},
{
"relative": "references/OPT_CONTRACT_T1.md",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/references/OPT_CONTRACT_T1.md",
"bytes": 13952,
"sha256": "ad9f3d76f3500b39263fb898d7c64588b4b47c9e11b456f938195261fd054d16"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/references/OPT_CONTRACT_T1.md",
"bytes": 13952,
"sha256": "ad9f3d76f3500b39263fb898d7c64588b4b47c9e11b456f938195261fd054d16"
}
},
{
"relative": "references/OPUS_D2_SCOPE_CLARIFICATION.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/references/OPUS_D2_SCOPE_CLARIFICATION.txt",
"bytes": 5598,
"sha256": "5775e7b512d9e90dbcfbcb181f5b64dc0fa8207e0947c0a4a6a5c9195565f9bd"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/references/OPUS_D2_SCOPE_CLARIFICATION.txt",
"bytes": 5598,
"sha256": "5775e7b512d9e90dbcfbcb181f5b64dc0fa8207e0947c0a4a6a5c9195565f9bd"
}
},
{
"relative": "references/OPUS_STARTUP_LIFECYCLE_CLARIFICATION.txt",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/references/OPUS_STARTUP_LIFECYCLE_CLARIFICATION.txt",
"bytes": 5996,
"sha256": "967aebf27ff412f7a16ce771ef7d68abf8cfde0bb76ed19cf6dbf2817ca7acc6"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/references/OPUS_STARTUP_LIFECYCLE_CLARIFICATION.txt",
"bytes": 5996,
"sha256": "967aebf27ff412f7a16ce771ef7d68abf8cfde0bb76ed19cf6dbf2817ca7acc6"
}
},
{
"relative": "registration/ACCEPTANCE_BASELINE.json",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/registration/ACCEPTANCE_BASELINE.json",
"bytes": 2981,
"sha256": "84628bc21205387f8a7143031bdc50c9f68a767d350e6c34b32e0ba1c7059337"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/registration/ACCEPTANCE_BASELINE.json",
"bytes": 2981,
"sha256": "84628bc21205387f8a7143031bdc50c9f68a767d350e6c34b32e0ba1c7059337"
}
},
{
"relative": "registration/CONFIG_PROPOSAL.json",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/registration/CONFIG_PROPOSAL.json",
"bytes": 821,
"sha256": "775fbbb97cda8b4d4991defdf7871b0fc79f489f4dea34c1733d4830426cf1df"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/registration/CONFIG_PROPOSAL.json",
"bytes": 821,
"sha256": "775fbbb97cda8b4d4991defdf7871b0fc79f489f4dea34c1733d4830426cf1df"
}
},
{
"relative": "registration/REGISTRATION_PROPOSAL.json",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/registration/REGISTRATION_PROPOSAL.json",
"bytes": 4733,
"sha256": "9590fc853a4df8d50cc0d269d23bd9c844dc6931590ff6f24ebf95bb54a8d135"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/registration/REGISTRATION_PROPOSAL.json",
"bytes": 4733,
"sha256": "9590fc853a4df8d50cc0d269d23bd9c844dc6931590ff6f24ebf95bb54a8d135"
}
},
{
"relative": "registration/ROOT_PROPOSAL_BYTE_TRANSFER.json",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/registration/ROOT_PROPOSAL_BYTE_TRANSFER.json",
"bytes": 4778,
"sha256": "63197f650849084f769e487a76458361886a37090042f1e351851c75b0384da2"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/registration/ROOT_PROPOSAL_BYTE_TRANSFER.json",
"bytes": 4778,
"sha256": "63197f650849084f769e487a76458361886a37090042f1e351851c75b0384da2"
}
},
{
"relative": "test_eq.py",
"source": {
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py",
"bytes": 35903,
"sha256": "ad33d971c545cabf367aa6f231fd1c5b21cec4ba7cf531f36ba8ed2a2bf57f62"
},
"retained": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p28-02-root-control-r01/retained-s2-558b96b-r01/eq/test_eq.py",
"bytes": 35903,
"sha256": "ad33d971c545cabf367aa6f231fd1c5b21cec4ba7cf531f36ba8ed2a2bf57f62"
}
}
],
"remaining_checker_findings": {
"path": "artifacts/original-completion-2026-10-02/p28-02-root-control-r01/ROOT_S2_PRE_S3_SOURCE_NOTES.json",
"bytes": 1322,
"sha256": "02b175327af0170e3188e6909a85efb987fbf016278b71bbec963572174629ec"
},
"stage_code_committed": false,
"formal_EQ_accepted": false,
"original_credit": 0,
"scope": "Local unit/raw/source-preservation evidence. The two checker omissions require correction in S3a; native and all formal gates remain pending."
}
@@ -0,0 +1,82 @@
{
"at_jst": "2026-10-21T08:46:08.565024+09:00",
"plan_id": "P28-02",
"project": "the-tree-p28-02-eq",
"task": "P28-02-EQ",
"stage": "S3a",
"base": "2549cf7d6992560b850bbd11934e3c14b39a1988",
"state_at_observation": "implementing",
"repairs": 5,
"submitted": null,
"actual_run": {
"id": "32288e966a844f5baec4dc931bc281a5",
"task_id": "P28-02-EQ",
"role": "implementer",
"service": "codex",
"status": "running",
"pid": 24130,
"started": 1792539888.089719,
"finished": null,
"exit_code": null,
"artifact": "/Users/korizatou114/Library/Application Support/agent-control/the-tree-p28-02-eq/runs/32288e966a844f5baec4dc931bc281a5"
},
"actual_process_observation": "24130 24100 01:20 Ss /Applications/ChatGPT.app/Contents/Resources/codex-cli/bin/../CodexCLI.app/Contents/MacOS/codex",
"root_exec_session": 21040,
"actual_Opus_session": "local_a7f85421-3eed-4482-8030-c0dca669573a",
"actual_Opus_response": 332,
"actual_decision_reason_origin_note": "Unmodified actual decision reason labels previous message330; actual response332 supplied correction after request331.",
"actual_Opus_materials": [
{
"path": "docs/plans/original-completion-2026-10-02/execution/p28-02/EQ_S3_STAGE_PLAN.txt",
"bytes": 6033,
"sha256": "ecbfb00691017fbd35027df8fa9ca6f82c761a5a3389568fe44b1babcfca308a"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p28-02/EQ_S3_STAGE_PLAN_R02.txt",
"bytes": 7223,
"sha256": "566e3ad98f9d47136ff4d4932f81c0a7f9fc96321a6f08ba944a9f1e736e6caa"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p28-02/DESKTOP_EQ_S3A_REPAIR_DECISION.json",
"bytes": 1805,
"sha256": "2b5309d2d6312ee0de85a068c3e39d5cdeaae1939c4f80c9b20b9908d8478952"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p28-02/DESKTOP_EQ_S3A_RUN_DECISION.json",
"bytes": 3620,
"sha256": "77888e140d101580255592da9b2a5a0d83f05a87aeec2c370c6094179ab0de5b"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p28-02/DESKTOP_EQ_S3A_RUN_DECISION_R02.json",
"bytes": 4136,
"sha256": "9eb8992b8c60d38abb166e6d5d5c8cfa3c61d4f3b1f31d6dc9b5839c6df62569"
}
],
"normal_repair_job": "eb21a9fe66824bf287705a3d47c6ccdc",
"normal_repair_succeeded": true,
"normal_RUN_input": {
"path": "artifacts/original-completion-2026-10-02/p28-02-root-control-r01/actual-desktop-EQ-S3A-RUN-input-r06/RECORDED.json",
"bytes": 242,
"sha256": "9f99174da30d79860fd52a0c13b9f3ce80e857548dfc632e73cc55d2ba459fb9"
},
"actual_context": {
"path": "artifacts/original-completion-2026-10-02/p28-02-root-control-r01/eq-staged-s3a-owner-run-input-r06/RUN_STARTED.json",
"bytes": 795,
"sha256": "adcaf4ebe7defc694c8895cc31bc93a39aeeefa35cab459827a2076a23d254da"
},
"all30_retained_S1_S2_files_verified_before_launch": true,
"source_backed_API_applicability_and_delivery_readonly_check": "Prior four material conflicts resolved; no engine/test/edit/dispatch by helper; does not replace independent formal Opus all6 review.",
"S2_local_evidence": {
"path": "docs/plans/original-completion-2026-10-02/execution/p28-02/EQ_S2_LOCAL_READINESS_558B96B.json",
"bytes": 25387,
"sha256": "83af15a50f294b0ccbb1c8d8e85df2321a8e9aa1cb615dc7079df1f6dc92e344"
},
"formal_EQ_accepted": false,
"original_credit": 0,
"original_completed": 23,
"original_total": 88,
"packages_completed": 4,
"packages_total": 30,
"partial_credit": false,
"next": "Follow actual S3a run32288e966a844f5baec4dc931bc281a5/PID24130/rootexec21040. Retain terminal code/raw, join actual unit exits/SHA, then actual Opus S3b decision. No duplicate worker/engine. S3b E4/E5, S4 submission, exact native7, both validations, fresh independent all6 review and normal integration/final remain mandatory."
}
@@ -0,0 +1,52 @@
EQ_S3_STAGE_PLAN(P28-02-EQ。EQ_STAGED_IMPLEMENTATION_PLAN r01/r02 の段階 S3 を、S3a と S3b に分ける。理由: S2 は 846.159 秒で、Runner の900秒の上限に近かったため。要求の範囲は変えない。SPEC、TASK、6条件、eq/references、eq/registration、補足 r01/r02/r03 は変更しない)
共通
- 最初に eq/PROGRESS.md と eq/IMPLEMENTATION.md を読み、S1/S2 の型・path・record schema・API・notes を再利用する。再設計しない。
- S1/S2 のコードと試験の本体を消さない。書き直さない(S3 で直すと決めた checker の2点と、失敗した試験が求める修正を除く)。
- 失敗の履歴は、PROGRESS.md と UNIT_OUTPUT に残す。各段階の終わりに、engine を使わない python3 test_eq.py の全件 PASS まで直し、生出力を保存する。
- 状態を変える呼出しは、SPEC §3.3 (b) の、列挙した scenario の専用の区間の中でだけ許可する。check_eq.py の静的な許可も、その区間と列挙した操作に限る。
- engine の起動、git への書込み、製品の変更、全回帰はしない。SPEC、TASK、eq/references、eq/registration は変更しない。
S3a(次の run)
1. checker の修正 1(eq/check_eq.py:109)
- 各 checkpoint の immutable snapshot の phase の key の集合が、正確に {0,…,10} であることを要求する(空の dict や、一部の欠落を拒否する)。
- 負の試験を加える: 空、1つの欠落、範囲外の key、重複した key の表現。
2. checker の修正 2(eq/check_eq.py:147-150)
- 測定の区間の30 tick の各分について、製品の _publish_snapshot(autoload/simulation_runtime.gd:12616-12621)が出す snapshot_published → state_updated を、実際の回数と順序で記録したものを、その分の checkpoint と結びつけて検査する。
- 各分に、ちょうど1組であること(snapshot_published に接続した受け手が無い場合は、製品の条件 :12619 のとおり state_updated だけになるので、probe の側で接続を記録し、期待値をその実際の接続の状態から決める)。
- 順序は snapshot_published が先。
- 分の番号は、checkpoint の minute と一致すること。
- scenario の区間で出た追加の signal は、別の区間の記録に入れる。測定の区間の記録には混ぜない。
- 負の試験を加える: 欠落、一部の分だけ、重複、順序の改ざん、分のずれ、scenario の signal の混入。
3. E3 失敗時の拒否(専用の scenario の区間。R と O の両方)
- restore_snapshot、SimulationSnapshot.validate、load_from_path の3つの API に、次の不正な入力を、それぞれ1件以上与える:
- 欠けた key
- 違う型
- 範囲外の値
- 重複した ID(published_ids、facility の ID)
- world.bin の改ざん(r03 の D3 の固定の規則)
- 不正な入力は、B1 の snapshot の deep copy から、固定の規則で作る。乱数や時刻を使わない。
- 記録すること:
- 戻り値と code
- 前後の S/K/C 層(同じ PID の中で完全に比べる)
- 全イベントの差分と、その件数(r02 の T4: 直接の restore は0件、load の失敗は SAVE_LOAD_FAILED がちょうど1件で、X(B, ev_fail) と r03 の正規化の後で完全一致すること)
- check_eq.py: E3 の記録の形式と矛盾の検査を加える。製品の失敗(不正な入力が受理された、状態が変わった、など)は、「既存の不具合」として記録する。PASS で補わない。
- 試験を加える: E3 の正常の記録と、拒否の場合(code の欠落、件数の不一致、拒否の前後の状態の変化を見逃すこと)。
4. 終わり: PROGRESS.md を更新し、正式な JSON の status を blocked にし、findings を「段階 S3a 完了(失敗ではない。次は S3b)」とする。
S3b(S3a の後の run)
1. E4 キャッシュの古さ(専用の区間。R と O)
- 場面: 状態を変えるコマンド(建設のコマンドを1件、通常の command queue を通す)、tick(advance_minutes(1))、restore_snapshot、load_from_path、状態を変えないコマンド。
- 各場面の直後の create_snapshot() と latest_snapshot を、完全な typed tree(r02 の A)で記録する。版の間の比較は compare_versions.py で行う。
- 件数: 直接の restore は SAVE_* が0件、load の成功は SAVE_LOADED がちょうど1件(X(P, ev_load))。
2. E5 所有権(専用の区間)
- 対象: create_snapshot() の戻り値、latest_snapshot、snapshot_published と state_updated の引数。
- 外から内: 入れ子の dict と配列を変更した後に、内部の状態、次の create_snapshot()、latest_digest が変わっていないかを、完全な typed tree で確かめる。
- 内から外: 次の tick の後に、既に返した値が変わっていないかを確かめる。
- 予想される aliasing(latest_snapshot と signal の引数が同じ object であること)による live の変化は、「既存の不具合」として、変わった path と値を全て記録する。その後の検査は、新しい baseline から始める。harness による無断の変更とは区別する。
3. check_eq.py と試験: E4/E5 の記録の検査と、正常と拒否の試験を加える。
4. 終わり: PROGRESS.md を更新し、正式な JSON の status を blocked にし、findings を「段階 S3b 完了(失敗ではない。次は S4)」とする。
その後
- S4: run_eq.py と verify_eq.py、bundle の試験、全件 PASS の後に正式に提出する。
- その後に、Root の native(7 phase)→ 両方の validation → 別の新しい Opus による全6条件のレビュー → 通常の統合と final、の順序で進める。
@@ -0,0 +1,54 @@
EQ_S3_STAGE_PLAN r02(P28-02-EQ。EQ_S3_STAGE_PLAN(r01)の分け方(S3a = checker の2点の修正 + E3、S3b = E4/E5)、共通の規則、S3b、その後の順序は、そのまま有効。この r02 は、実際の API に合わせて、S3a の「checker の修正 2」と「E3」を置き換えて確定する。SPEC、TASK、6条件、eq/references、eq/registration、補足 r01/r02/r03、段階の計画 r01/r02 は変更しない)
1. checker の修正 1(eq/check_eq.py:109): r01 のとおり(phase の key の集合が正確に {0..10}、負の試験)。
2. checker の修正 2(eq/check_eq.py:147-150。r01 を置き換える)
- probe は、自分の observer を snapshot_published に接続している。そのため、製品の _publish_snapshot(autoload/simulation_runtime.gd:12616-12621)は、毎 tick、snapshot_published を出してから state_updated を出す(:12619 の条件が真になる)。
- 測定の区間の30 tick の各分について、**ちょうど1組の snapshot_published → state_updated** を要求し、その分の checkpoint の minute と結びつける。
- 測定の開始の時点で、snapshot_published と state_updated の接続の一覧(get_connections() の、接続先の object と method)を記録し、その中に probe 自身の接続があることを要求する。probe の接続が無い場合は、期待を「state_updated だけ」に下げることはせず、失敗にする。
- 製品で受け手が接続されていない場合の動作(state_updated だけ)は、この区間の対象の外とする。試験もしない。
- scenario の区間で出た signal は、別の区間の記録に入れ、測定の区間には混ぜない。
- 負の試験を加える:
- 欠落、一部の分だけ、重複、順序の改ざん、分のずれ
- scenario の signal の混入
- probe の接続が一覧に無いのに合格にすること
- 期待を state_updated だけに下げること
3. E3 失敗時の拒否(専用の scenario の区間。r01 を置き換える)
3.1 各 API の実際の戻り値(架空の code は作らない)
- SimulationRuntime.restore_snapshot(Dictionary) -> bool(:587): 戻り値の bool を、そのまま記録する。code は null とし、理由を "API returns bool only" とする。
- SimulationSnapshot.validate(Dictionary) -> {ok, errors}(scripts/core/simulation_snapshot.gd:16-43): 返った dict の全体(ok と、errors の全件)を、そのまま記録する。code は null とし、理由を "API returns ok/errors only" とする。
- load_from_path(String) -> Dictionary(:4223): 実際の code を記録する。この API で code が欠けていれば、それは失敗として拒否する(上の2つの「API に code が無い」とは区別する)。
3.2 不正の分類と、それを適用する API(source に基づく表。適用しないものは、理由つきの NA として記録し、PASS に補わない)
| 分類 | restore_snapshot(Dictionary) | validate(Dictionary。envelope の外形だけを検査) | load_from_path(package) |
|---|---|---|---|
| 欠けた key | 適用: B1 の deep copy から clock を削除 → false を期待 | 適用: clock を削除 → errors に missing_clock を期待 | 適用: package の manifest.json から checksum_world を削除 → INVALID_MANIFEST を期待 |
| 違う型 | 適用: clock.absolute_minute を文字列 "x" に → false | 適用: 同じ → errors に invalid_absolute_minute | 適用: manifest.json の format_version を文字列に → INVALID_MANIFEST |
| 範囲外の値 | 適用: clock.speed を 9 に → false | 適用: 同じ → errors に invalid_speed | 適用: manifest.json の format_version を、対応していない大きな整数に → UNSUPPORTED_FORMAT(自動の migration を試みた場合は、その実際の code と、migration_attempted を記録) |
| 重複した ID(published_ids) | 適用: systems.runtime.domain_events.published_ids に、既存の ID を1つ追加 → false(DomainEventStream.restore_snapshot、scripts/core/domain_event_stream.gd:113-140 が拒否) | NA: validate は envelope の外形だけで、runtime の内部を検査しない(:16-43)。実際の戻り値(ok:true を予想)は記録するが、不具合とはしない | 適用(公開の API で作れる場合): 重複を入れた snapshot を SaveService.save_snapshot で、固定の user:// の path に保存し、load_from_path で読む。save が拒否した場合は、その実際の code を記録し、load の側は理由つきの NA にする |
| 重複した ID(facility) | R で適用: 施設の instance の配列で、最初の entry を複製 → false(FacilityService.restore_snapshot、scripts/facility/facility_service.gd:701-703 が拒否)。O で NA: B1 の施設の件数が実際に0のとき、複製する既存の entry が無いため(件数を記録する)。施設を建設すること、R の B1 で代用すること、製品の値を作ることはしない | NA: 上と同じ理由 | R で、published_ids と同じ方法で適用。O で NA(理由は同じ) |
| world.bin の改ざん | NA: Dictionary の API は package を読まない | NA: 同じ | 適用: r03 の D3 の固定の規則 → CHECKSUM_MISMATCH を期待 |
- 不正な入力は、B1 の deep copy と、固定の user:// の相対 path と、固定の規則だけで作る。乱数・時刻・PID を使わない(r03 の D1〜D3)。
- 期待の結果は、上の source に基づくものとして記録する。実際の結果が期待と違う場合(たとえば、不正な入力が受理された)は、「既存の不具合の候補」として、全ての記録とともに残す。ただし、envelope の validate が runtime の内部の重複を受理することは、その API の範囲の外なので、不具合とは断定しない。
3.3 各操作で記録し、検査すること
- 前後の S/K/C 層(同じ PID の中で、完全に比べる)。拒否された場合は、変化が無いこと。
- 全イベントの差分と、その件数。restore_snapshot と validate は0件。load_from_path の失敗は SAVE_LOAD_FAILED がちょうど1件で、X(B, ev_fail) と、r03 の正規化の後で完全一致すること。
- 適用と NA の表を、そのまま report に入れる。fresh の whole-unit レビューが、適用の条件を判定できるようにする。
3.4 試験(test_eq.py)
- 正常の記録。
- 拒否の場合:
- restore と validate の架空の code
- load の code の欠落を合格にすること
- NA を PASS として数えること
- O の施設の重複を、件数が0なのに適用したと記録すること
- 拒否の前後の状態の変化を見逃すこと
- 件数の不一致
- envelope の validate が重複を受理したことを、製品の不具合と断定すること
4. 終わり: r01 のとおり(PROGRESS.md を更新し、正式な JSON の status を blocked にし、findings を「段階 S3a 完了(失敗ではない。次は S3b)」とする)。