diff --git a/docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py b/docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py index 83c1447..fcfb184 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py +++ b/docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py @@ -17,7 +17,7 @@ MANIFEST_SHA256 = 'a15f29fa12537f6d8aaf7cabea390922a9f16e3eb9c10981e5742aafc8c4c MANIFEST_BYTES = 1244135 PRODUCT = '5f6bc11d6bb6e92d22d787989b219fef3a435bc1' RUNS = {'s1': 'p04-s1-native-r02', 's2a': 'p04-s2a-native-r03', - 's2b': 'p04-s2b-native-r02', 's3': 'p04-s3-native-r01', 's4': 'p04-s4-native-r27'} + 's2b': 'p04-s2b-native-r02', 's3': 'p04-s3-native-r01', 's4': 'p04-s4-native-r28'} # Native descriptors pinned from literal files, never ROOT result passed fields. NATIVE_PINS = { 's1': ('1e26d9585396da9415747d87d77b70f23425a3ee0714e4fca114748f9479fd4e', '01372beb0ffec181c892d3b4e88bce32001e08fb2007938d7bf19135511a7acc', '0b6d11eb34d8af64b22cb806caeb06eed4ec521fa9ee24d1204ea185345e655c'), diff --git a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/REPAIR28_BINDINGS.json b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/REPAIR28_BINDINGS.json new file mode 100644 index 0000000..40a4605 --- /dev/null +++ b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/REPAIR28_BINDINGS.json @@ -0,0 +1,38 @@ +{ + "status": "NOTRUN", + "task_id": "P04-01", + "starting_submission": "55f1fb49aaefa5c1b86de1c3eda72392ef6b58f2", + "source": "audit-support/p04-s4-source-r28", + "plan": "p04-s4-plan-r28.json", + "native": "p04-s4-native-r28", + "regression_status": "NOTRUN", + "native_status": "NOTRUN", + "unit_complete": false, + "D05": "pending", + "files": { + "s4/p04_s4_power_probe.gd": { + "bytes": 26912, + "sha256": "56f8e2786e3aff82097baa06afb4cd13e6e7c06c3d1afa43b9ee35c78a25a999" + }, + "s4/run_s4_native.py": { + "bytes": 23233, + "sha256": "2d3be39d2b310abac058e27336ac816c234043a0a1dd7b2c52d84994907dd31b" + }, + "s4/S4_ROOT_RUN.md": { + "bytes": 21862, + "sha256": "ff463e1e6ce8847f658eddc91f1cec3eab3bb8bcadd9a75272138e06083116a2" + }, + "s4/phase_cut_regression.py": { + "bytes": 3919, + "sha256": "1362078fdd819d057f1f1bab369b9629a11e089a3453da8af4ce21cec251dbad" + }, + "s4/receipt_lifecycle_fixtures.py": { + "bytes": 12340, + "sha256": "629571495787fdcda82a6a74d98649d4ea424d6fc9c27c5cafa55d4b2881c71f" + }, + "p04_native_series.py": { + "bytes": 75900, + "sha256": "c1cc5d49dbf4c8422a2208297c665fde8abd569e2c9f8239603d8218ae1ed8fb" + } + } +} diff --git a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/S4_ROOT_RUN.md b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/S4_ROOT_RUN.md index 3cfecc3..d200eae 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/S4_ROOT_RUN.md +++ b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/S4_ROOT_RUN.md @@ -1,4 +1,4 @@ -# S4 finite Root collection — NOT RUN +# S4 finite Root collection r28 — NOT RUN This adds only the existing `power_stop` evidence obligation. It adds no counted condition, product change, acceptance or priority approval. Run once after this @@ -16,15 +16,15 @@ export E=docs/plans/original-completion-2026-10-02/execution/p04-01 export PYTHONDONTWRITEBYTECODE=1 python3 "$E/s4/engine_identity_negative_fixtures.py" python3 "$E/s4/receipt_lifecycle_fixtures.py" -mkdir "$B/audit-support/p04-s4-source-r27" -cp "$E/s4/run_s4_native.py" "$E/s4/p04_s4_power_probe.gd" "$E/s4/S4_ROOT_RUN.md" "$B/audit-support/p04-s4-source-r27/" -python3 "$B/audit-support/p04-s4-source-r27/run_s4_native.py" \ +mkdir "$B/audit-support/p04-s4-source-r28" +cp "$E/s4/run_s4_native.py" "$E/s4/p04_s4_power_probe.gd" "$E/s4/S4_ROOT_RUN.md" "$B/audit-support/p04-s4-source-r28/" +python3 "$B/audit-support/p04-s4-source-r28/run_s4_native.py" \ --project-root "$B/audit-support/p04-r17-full-inputs-r01/product" \ - --output "$B/p04-s4-native-r27" --plan "$B/p04-s4-plan-r27.json" \ + --output "$B/p04-s4-native-r28" --plan "$B/p04-s4-plan-r28.json" \ --godot /Applications/Godot.app/Contents/MacOS/Godot --check-only -python3 "$B/audit-support/p04-s4-source-r27/run_s4_native.py" \ +python3 "$B/audit-support/p04-s4-source-r28/run_s4_native.py" \ --project-root "$B/audit-support/p04-r17-full-inputs-r01/product" \ - --output "$B/p04-s4-native-r27" --plan "$B/p04-s4-plan-r27.json" \ + --output "$B/p04-s4-native-r28" --plan "$B/p04-s4-plan-r28.json" \ --godot /Applications/Godot.app/Contents/MacOS/Godot ``` @@ -69,8 +69,8 @@ Exact input footprints: proof and remains ineligible. Its diagnostics are at `audit-support/p04-root-d393-s4-r01/ENGINE_STAGING_DIAGNOSTICS.json`. -Exact output footprints are `B/p04-s4-plan-r27.json` and the fresh -`B/p04-s4-native-r27/**`: private selected source stage, complete phase receipts +Exact output footprints are `B/p04-s4-plan-r28.json` and the fresh +`B/p04-s4-native-r28/**`: private selected source stage, complete phase receipts and logs, raw JSON/Variant points and all phase observations, full source maps, PID and cleanup receipts. `formal/{writer,reader}/S4-{boundary,held,recovered}/` mirrors all four formal members (`journal.log`, `manifest.json`, `thumbnail.png`, @@ -112,8 +112,8 @@ restore and is not part of Runtime snapshot equality. The derived `related_facility_operating` flag is measured separately and checked after restore. This source-only dispatch authorizes no worker execution. Root stages the three -files, creates the r27 plan with --check-only, then collects once to the fresh -r27 output. Do not read or write r24 outputs, cleanup, stages or plans. +files, creates the r28 plan with --check-only, then collects once to the fresh +r28 output. Do not read or write r24 outputs, cleanup, stages or plans. Do not rerun S1-S3, C or full178. No engine copy, signing, xattr, codesign call or security-setting change is part of this procedure. Native evidence, registered validation, independent review, support53cb rebind @@ -258,3 +258,48 @@ Root re-runs only the fresh S4 collection and any needed fixture validation, using the r27 commands above. Exact-version evidence, registered validation, independent review, D05 and original acceptance remain pending; this is submitted preparation, not completion. + +## REPAIR28 phase cut (source-only; NOTRUN) + +Root's supplied r27 own-B diagnosis is preserved as history: import, parse and +Writer passed (934 checks, zero failures); Reader ran 1445 checks with exactly +one failure, complete phase count. ACTUAL_TYPED_PHASE_DIAGNOSIS.json reports +all 121 actual Reader phase .var files byte-identical to matching Writer files. +This worker did not open or rerun those raw materials. Keep all r27 failed raw, +formals, logs, source stages, plans and diagnosis unchanged. + +The kernel applies commands at the old minute, advances absolute_minute, then +emits TIME_BOUNDARIES and the remaining phases. The new helper includes minute +960 APPLY_COMMANDS using the enum key expression used by the Writer. It also +includes all later rows. Before byte comparison the probe asserts the exact +121-entry kernel roster, uniqueness, and Writer order. Both existing complete +phase count and complete typed var_to_bytes equality checks remain unchanged. +Writer row data, typed staff fix, runtime SERVERS, Clock and raw format stay +unchanged. + +The current RUNS s4 binding, wrapper defaults and disposable lifecycle fixture +path names use r28. Only these path strings change in the wrapper and lifecycle +fixture; their engine/lifecycle behavior is unchanged. Stage the three current +files using the commands at the top to create fresh source-r28, plan-r28 and +native-r28 paths. Do not reuse r27 as passing evidence. + +Regression control status: NOTRUN. Root supplies full paths to ALL 132 actual +r27 Writer phase .var files and ALL 121 actual Reader phase .var files: +python3 "$E/s4/phase_cut_regression.py" --writer --reader +Use actual own-B raw paths supplied by Root, not fabricated fixtures or old +external provenance paths. Paths may be in any argument order; the control +reconstructs kernel order from typed minute/phase, checks the complete Writer +and Reader rosters, then compares unchanged full bytes. It requires old cut +120/rejected, new cut 121/equal, deleted boundary APPLY_COMMANDS/rejected and +duplicate/rejected. Mutations are in-memory lists only. Its result is a raw +regression control, never an engine/native/acceptance PASS. Missing raw paths +remain a Root execution input, not a worker-generated substitute. + +Worker made source edits and calculated bindings only; no tests, fixtures, +Git, engine, Runner, agents or commits. The normal validation on submitted +55f1fb49aaefa5c1b86de1c3eda72392ef6b58f2 ran once and exited 2 because the current +MANIFEST is missing (Root-supplied history). The gate, checker a61, 1338 inputs, +C/S1-3/full178 artifacts, five carried formal review findings, and frozen +original 13/88 main 9b remain unchanged. D05, independent review, exact-version +native proof and original unit acceptance remain pending. This repair does +not complete the unit. diff --git a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd index 10fc030..f5c937b 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd +++ b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd @@ -366,6 +366,25 @@ func _load_point(path: String, expected: Dictionary) -> bool: _expect(var_to_bytes(_runtime.create_snapshot()) == var_to_bytes(expected[&"snapshot"]), "all restored typed fields equal Writer") return restored +func _is_replayed_phase(row: Dictionary) -> bool: + return int(row[&"minute"]) > _boundary or (int(row[&"minute"]) == _boundary and row[&"phase"] == SimulationKernel.TickPhase.keys()[SimulationKernel.TickPhase.APPLY_COMMANDS]) + +func _assert_expected_phase_roster(references: Array) -> void: + var expected_pairs: Array = [] + for minute: int in range(_boundary, _boundary + 11): + for phase: int in range(SimulationKernel.TickPhase.size()): + expected_pairs.append([minute if phase == SimulationKernel.TickPhase.APPLY_COMMANDS else minute + 1, SimulationKernel.TickPhase.keys()[phase]]) + var actual_pairs: Array = [] + var seen: Dictionary = {} + for reference: Dictionary in references: + var row: Dictionary = _read(reference) + var pair: Array = [int(row[&"minute"]), row[&"phase"]] + _expect(not seen.has(pair), "expected phase roster has no duplicate minute/phase") + seen[pair] = true + actual_pairs.append(pair) + _expect(references.size() == 121 and expected_pairs.size() == 121, "expected phase roster exactly 11 phases x 11 replayed minutes") + _expect(actual_pairs == expected_pairs, "expected phase roster in Writer/kernel order with no missing minute/phase") + func _reader() -> void: var file: FileAccess = FileAccess.open(_evidence_dir.path_join("writer.json"), FileAccess.READ) _expect(file != null, "Writer receipt") @@ -416,7 +435,8 @@ func _reader() -> void: replay_refs[label] = _write(label + "-replay", actual) var expected_phases: Array = [] for reference: Dictionary in writer_case[&"phases"]: - if int(_read(reference)[&"minute"]) > _boundary: expected_phases.append(reference) + if _is_replayed_phase(_read(reference)): expected_phases.append(reference) + _assert_expected_phase_roster(expected_phases) _expect(_phases.size() == expected_phases.size(), "complete phase count") if _phases.size() == expected_phases.size(): for index: int in range(_phases.size()): diff --git a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/phase_cut_regression.py b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/phase_cut_regression.py new file mode 100644 index 0000000..93af4b2 --- /dev/null +++ b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/phase_cut_regression.py @@ -0,0 +1,83 @@ +"""Read actual r27 phase .var paths only; no engine, fixtures or acceptance claim. + +Root supplies every Writer and Reader phase file via --writer and --reader. +Argument order is immaterial: observation order is reconstructed from kernel +phase/minute keys, never from lexicographic filenames. Typed bytes stay intact. +""" +import argparse +import hashlib +import json +from pathlib import Path +import sys + +sys.dont_write_bytecode = True +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) +from p04_native_series import require, variant + +PHASES = ('APPLY_COMMANDS', 'TIME_BOUNDARIES', 'MANA', 'CONSTRUCTION', + 'LOGISTICS', 'FACILITY_COMPLETION', 'VITALS_AND_ENVIRONMENT', + 'INCIDENTS_AND_EVENTS', 'FACILITY_QUEUES', 'AI_DECISIONS', 'PUBLISH_SNAPSHOT') +BOUNDARY = 960 +ROSTER = [(minute if phase == PHASES[0] else minute + 1, phase) + for minute in range(BOUNDARY, BOUNDARY + 11) for phase in PHASES] + + +def load(paths, role): + rows, pins = [], [] + for path in paths: + require(path.is_absolute() and path.is_file() and not path.is_symlink(), 'full regular raw path required') + require(path.name.startswith(role + '-S4-phase-') and path.suffix == '.var', 'actual role phase .var required') + raw = path.read_bytes() + node = variant(raw) + minute, phase = node.at('minute'), node.at('phase') + require(minute.kind == 2 and phase.kind == 4 and phase.value in PHASES, 'typed minute/phase') + rows.append(((minute.value, phase.value), raw)) + pins.append(dict(path=str(path), bytes=len(raw), sha256=hashlib.sha256(raw).hexdigest())) + rows.sort(key=lambda row: (row[0][0] + (row[0][1] == PHASES[0]), PHASES.index(row[0][1]))) + return rows, pins + + +def validate(expected, reader): + require(len(expected) == len(reader) == 121, 'complete phase count') + require([key for key, _ in expected] == ROSTER, 'Writer roster missing/duplicate/order') + require([key for key, _ in reader] == ROSTER, 'Reader roster missing/duplicate/order') + require(all(a == b for a, b in zip(expected, reader)), 'same phase order and all typed phase bytes') + + +def rejected(expected, reader): + try: + validate(expected, reader) + except ValueError: + return True + raise ValueError('negative control unexpectedly accepted') + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--writer', nargs='+', type=Path, required=True) + parser.add_argument('--reader', nargs='+', type=Path, required=True) + args = parser.parse_args() + writer, wpins = load(args.writer, 'writer') + reader, rpins = load(args.reader, 'reader') + require(len(writer) == 132 and len({key for key, _ in writer}) == 132, 'complete unique actual Writer input') + require([key for key, _ in writer] == + [(minute if phase == PHASES[0] else minute + 1, phase) + for minute in range(BOUNDARY - 1, BOUNDARY + 11) for phase in PHASES], + 'full Writer kernel roster') + old = [row for row in writer if row[0][0] > BOUNDARY] + new = [row for row in writer if row[0][0] > BOUNDARY or + (row[0][0] == BOUNDARY and row[0][1] == PHASES[0])] + require(len(old) == 120, 'old cut must produce 120') + old_rejected = rejected(old, reader) + validate(new, reader) + require(new[0][0] == (BOUNDARY, PHASES[0]), 'boundary APPLY_COMMANDS first') + deleted_rejected = rejected(new[1:], reader) + duplicated_rejected = rejected([new[0], *new], reader) + print(json.dumps(dict(status='CONTROL_CONFIRMED', engine_run=False, acceptance=False, + old_count=len(old), old_rejected=old_rejected, new_count=len(new), + all_typed_bytes_in_order=True, deleted_apply_rejected=deleted_rejected, + duplicate_rejected=duplicated_rejected, writer=wpins, reader=rpins), indent=2)) + + +if __name__ == '__main__': + main() diff --git a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/receipt_lifecycle_fixtures.py b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/receipt_lifecycle_fixtures.py index fbe6795..d167300 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/receipt_lifecycle_fixtures.py +++ b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/receipt_lifecycle_fixtures.py @@ -107,8 +107,8 @@ def case(base, failure=None): descriptor = dict(path=str(engine), resolved_path=str(engine), bytes=st.st_size, sha256=r.sha(engine), mtime_ns=st.st_mtime_ns, mode=st.st_mode, device=st.st_dev, inode=st.st_ino, ctime_ns=st.st_ctime_ns) - out = base / 'p04-s4-native-r27' - plan = base / 'p04-s4-plan-r27.json' + out = base / 'p04-s4-native-r28' + plan = base / 'p04-s4-plan-r28.json' attempts, created, phases = Counter(), {}, [] cleanup_calls = [] real_write, real_inventory = r.write, r.inventory diff --git a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py index a8ec441..b743e5f 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py +++ b/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py @@ -99,8 +99,8 @@ def engine_pin(path, expected=None): def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--project-root", type=Path, default=PRODUCT) - parser.add_argument("--output", type=Path, default=BUILD / "p04-s4-native-r27") - parser.add_argument("--plan", type=Path, default=BUILD / "p04-s4-plan-r27.json") + parser.add_argument("--output", type=Path, default=BUILD / "p04-s4-native-r28") + parser.add_argument("--plan", type=Path, default=BUILD / "p04-s4-plan-r28.json") parser.add_argument("--cache-run", type=Path, default=None, help="optional passed registered cache; default is fresh, without cache access") parser.add_argument("--godot", type=Path, default=ENGINE)