P04-01: 同時発生の更新規約
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# Repair24 — source-ready submission
|
||||
|
||||
Bounded continuation of P04-01 request-repair24; tests NOT RUN.
|
||||
Existing wrapper edits and the untracked identity fixture were read first and
|
||||
preserved/corrected. Only this execution subtree was written. No Git, engine,
|
||||
Runner, agent, commit or integration operation was performed.
|
||||
|
||||
Changed source/runbook SHA256 (exact bytes):
|
||||
|
||||
| File | SHA256 |
|
||||
| --- | --- |
|
||||
| s4/run_s4_native.py | dda495d33566eae14c8a707e77f8ec9dc6c7bd043076a091e90dd53f6a7490db |
|
||||
| p04_native_series.py | 348197759c169c2094db3b1114ca3abe5525b8d4bc9aca611d4579871a130b40 |
|
||||
| s4/engine_identity_negative_fixtures.py | f9148ef79cb62ec6631e7e3f23e1d3b062434f7152977aab3b9d18d82672255e |
|
||||
| s4/S4_ROOT_RUN.md | c1a00e3dad8d91d28df1a7f868f6e4e905f1df721baac964865e341c84356135 |
|
||||
|
||||
This new status document records the hashes above; its own hash must be taken
|
||||
from the submitted checkout, outside its own contents.
|
||||
|
||||
Wrapper pins changed: the own-B bare Godot copy is replaced with exactly
|
||||
`/Applications/Godot.app/Contents/MacOS/Godot`, rejecting symlinks and any
|
||||
different resolved path. Its constant SHA remains
|
||||
`c7cccbf8fb143e34e02fd6521e09be2c2b974f0d5db080b19071c9c570718ccf`.
|
||||
Engine identity no longer depends on an old cache runner-input. Fresh NO-CACHE
|
||||
is the default at plan and native collection. Optional explicit cache mode
|
||||
rejects failed receipts before reading their inputs or cache contents.
|
||||
No default cache or cache PASS is required. No engine is copied, re-signed or
|
||||
modified, and no codesign/xattr/security operation is added.
|
||||
|
||||
Before-launch, during-collection and explicit after-cleanup re-pins retain the
|
||||
full runtime descriptor (path/resolved path, bytes, SHA, device, inode, mode,
|
||||
mtime and ctime). Runner-input and execution retain equal before/during/after
|
||||
identity records and execution retains labeled observations. fixed_guard still
|
||||
re-pins the engine. The verifier permits only this exact installed engine
|
||||
outside B, reads/hashes it exactly and checks the recorded identities.
|
||||
Fixed inputs and QA remain own-B only; actual command[0] must equal the pin.
|
||||
|
||||
Defaults and Root staging are now:
|
||||
`p04-s4-native-r24`, `p04-s4-plan-r24.json`,
|
||||
`audit-support/p04-s4-source-r24`. Only RUNS S4 changes to r24.
|
||||
C/S1-S3 bindings, other series and the frozen C block (20916) are unchanged.
|
||||
Source1338, parse316, sole QA override, default-player protection, owned
|
||||
four-distinct-PID capture, live-engine refusal, disk admission, fresh output,
|
||||
cleanup-before-fixed-guard, formal Writer/Reader, NO_POWER, typed declarations,
|
||||
forbidden mutations/bypasses and mana constants guards remain.
|
||||
|
||||
Untouched checker: SHA256
|
||||
`a61c5b496e656f60c66898e42500bc9a2d45f947690ce8f5f19a03984ebbc850`,
|
||||
78399 B. Untouched probe: SHA256
|
||||
`ceb592d853fd50063f20496c7b6df05257528dbe1c0d0d80bc6a8ccb1f9dd6d7`.
|
||||
All 1338 game files are unchanged; no game source was written. No new claim of
|
||||
executed 1338-file verification is made.
|
||||
|
||||
The formal reviewer's five findings are carried forward unchanged, with no
|
||||
closure claimed. Their individual review text was not supplied in this dispatch
|
||||
or found in the local execution records searched; it is not reconstructed here.
|
||||
Main 9b remains frozen at original 13/88. Support 53cb remains review pending.
|
||||
D05 remains pending. No acceptance denominator, specification, main integration
|
||||
or original completion state changes.
|
||||
|
||||
r22 is an immutable failed proof and remains ineligible. Diagnostics:
|
||||
`audit-support/p04-root-d393-s4-r01/ENGINE_STAGING_DIAGNOSTICS.json`.
|
||||
Its pre-banner staged-copy failure is an environment/staging fault; no product
|
||||
logic or probe/checker repair is claimed. Root uses the installed executable
|
||||
directly and preserves r22. Do not rerun S1-S3, C or full178.
|
||||
|
||||
Validation: static AST parsing and in-memory compile completed for the wrapper,
|
||||
series verifier and identity fixture; no module was imported or executed.
|
||||
Read-only SHA/byte inspection completed for the four listed files, checker and
|
||||
probe. These are source checks only. Tests NOT RUN: identity fixtures, all other
|
||||
fixtures/suites, check-only plan generation, native S4, full178, registered
|
||||
validation and independent review. No unexecuted result is reported as passed.
|
||||
|
||||
Registered validation stays exit 2 until Root generates the current
|
||||
MANIFEST.json collection; the gate is not changed. This is the carried-forward
|
||||
expected gate state, not a newly executed validation result. Root execution,
|
||||
current exact-version evidence and formal independent review remain pending.
|
||||
@@ -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-r22'}
|
||||
's2b': 'p04-s2b-native-r02', 's3': 'p04-s3-native-r01', 's4': 'p04-s4-native-r24'}
|
||||
# Native descriptors pinned from literal files, never ROOT result passed fields.
|
||||
NATIVE_PINS = {
|
||||
's1': ('1e26d9585396da9415747d87d77b70f23425a3ee0714e4fca114748f9479fd4e', '01372beb0ffec181c892d3b4e88bce32001e08fb2007938d7bf19135511a7acc', '0b6d11eb34d8af64b22cb806caeb06eed4ec521fa9ee24d1204ea185345e655c'),
|
||||
@@ -968,8 +968,33 @@ def power_stop(s):
|
||||
'service_id': sid, 'transaction_id': paid[0]['transaction_id'], 'priority_approved': False}
|
||||
|
||||
|
||||
S4_ENGINE_PATH = '/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
S4_ENGINE_SHA256 = 'c7cccbf8fb143e34e02fd6521e09be2c2b974f0d5db080b19071c9c570718ccf'
|
||||
|
||||
|
||||
def verify_s4_engine(pin, identity):
|
||||
require(pin['path'] == S4_ENGINE_PATH and pin['sha256'] == S4_ENGINE_SHA256,
|
||||
'S4 exact installed engine pin required')
|
||||
path = ordinary(pin['path'])
|
||||
require(str(path.resolve(strict=True)) == S4_ENGINE_PATH, 'S4 engine resolved path')
|
||||
before = path.stat()
|
||||
require(type(pin['bytes']) is int, 'S4 recorded engine bytes required')
|
||||
checked(path.read_bytes(), pin, 'S4 installed engine')
|
||||
after = path.stat()
|
||||
fields = {'bytes': 'st_size', 'mtime_ns': 'st_mtime_ns', 'mode': 'st_mode',
|
||||
'device': 'st_dev', 'inode': 'st_ino', 'ctime_ns': 'st_ctime_ns'}
|
||||
require(all(getattr(before, f) == getattr(after, f) for f in fields.values()),
|
||||
'S4 engine changed while reading')
|
||||
ordinary(path)
|
||||
require(pin['resolved_path'] == S4_ENGINE_PATH and
|
||||
all(pin[k] == getattr(after, f) for k, f in fields.items()), 'S4 runtime engine descriptor')
|
||||
require(set(identity) == {'before', 'during', 'after'} and identity['before'] == pin and
|
||||
identity['after'] == pin and isinstance(identity['during'], list) and identity['during'] and
|
||||
all(value == pin for value in identity['during']), 'S4 before/during/after engine identity')
|
||||
|
||||
|
||||
class S4Series(Series):
|
||||
"""Fresh S4: all verifier inputs live in own B; profile paths are provenance."""
|
||||
"""Fresh S4: own-B materials and exact installed engine; profiles are provenance."""
|
||||
def __init__(self, build):
|
||||
self.name, self.build, self.run = 's4', Path(build), RUNS['s4']
|
||||
self.base = self.build / self.run
|
||||
@@ -993,10 +1018,16 @@ class S4Series(Series):
|
||||
require(inputs['QA_overrides'] == ['tests/s3/test_runtime_staff_assignment.gd'], 'S4 sole QA override')
|
||||
selected[inputs['QA_overrides'][0]] = digest(qa.read_bytes())
|
||||
require(selected == inputs['selected_source_map'], 'S4 selected source map')
|
||||
for pin in inputs['fixed_input_pins'] + [inputs['QA'], inputs['engine']]:
|
||||
for pin in inputs['fixed_input_pins'] + [inputs['QA']]:
|
||||
path = Path(pin['path'])
|
||||
require(path.is_relative_to(self.build), 'S4 material outside own B')
|
||||
self.read_build(path.relative_to(self.build).as_posix(), pin)
|
||||
verify_s4_engine(inputs['engine'], execution['engine_identity'])
|
||||
require(inputs['engine_identity'] == execution['engine_identity'], 'S4 input/execution engine identity')
|
||||
observations = execution['engine_observations']
|
||||
require(any(row['stage'] == 'after-cleanup' for row in observations) and
|
||||
all(row.get('descriptor') == inputs['engine'] for row in observations),
|
||||
'S4 runtime engine observations')
|
||||
require(execution['error'] is None and execution['guard_errors'] == [] and execution['cleanup_errors'] == [] and
|
||||
[p['phase'] for p in execution['phases']] == ['import', 'parse', 'writer', 'reader'], 'S4 native phase/guard failure')
|
||||
for phase in execution['phases']:
|
||||
|
||||
@@ -6,26 +6,24 @@ source batch is auto-submitted. Do not rerun C/S1/S2a/S2b/S3. Do not run the ful
|
||||
product suite now. Preserve all existing raw and REPAIR17–21 history.
|
||||
|
||||
From the clean auto-submitted checkout, stage these three exact reviewed files
|
||||
in the fresh own-B source directory. Copy the installed engine executable there as an independently pinned native input. This staging is a Root action, not a worker
|
||||
execution. The wrapper refuses QA outside own B. All input/QA/source footprints
|
||||
below are within the registered B; external manifest paths are lookup keys and
|
||||
in the fresh own-B source directory. Run the installed executable directly; do not stage or copy it. This staging is a Root action, not a worker
|
||||
execution. The wrapper refuses QA outside own B. QA and fixed inputs stay within registered B; only the exact installed engine is external; external manifest paths are lookup keys and
|
||||
provenance only. Never open their original production locations.
|
||||
|
||||
```sh
|
||||
export B=/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build
|
||||
export E=docs/plans/original-completion-2026-10-02/execution/p04-01
|
||||
export PYTHONDONTWRITEBYTECODE=1
|
||||
mkdir "$B/audit-support/p04-s4-source-r23"
|
||||
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-r23/"
|
||||
cp /Applications/Godot.app/Contents/MacOS/Godot "$B/audit-support/p04-s4-source-r23/Godot"
|
||||
python3 "$B/audit-support/p04-s4-source-r23/run_s4_native.py" \
|
||||
mkdir "$B/audit-support/p04-s4-source-r24"
|
||||
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-r24/"
|
||||
python3 "$B/audit-support/p04-s4-source-r24/run_s4_native.py" \
|
||||
--project-root "$B/audit-support/p04-r17-full-inputs-r01/product" \
|
||||
--output "$B/p04-s4-native-r22" --plan "$B/p04-s4-plan-r23.json" \
|
||||
--godot "$B/audit-support/p04-s4-source-r23/Godot" --check-only
|
||||
python3 "$B/audit-support/p04-s4-source-r23/run_s4_native.py" \
|
||||
--output "$B/p04-s4-native-r24" --plan "$B/p04-s4-plan-r24.json" \
|
||||
--godot /Applications/Godot.app/Contents/MacOS/Godot --check-only
|
||||
python3 "$B/audit-support/p04-s4-source-r24/run_s4_native.py" \
|
||||
--project-root "$B/audit-support/p04-r17-full-inputs-r01/product" \
|
||||
--output "$B/p04-s4-native-r22" --plan "$B/p04-s4-plan-r23.json" \
|
||||
--godot "$B/audit-support/p04-s4-source-r23/Godot"
|
||||
--output "$B/p04-s4-native-r24" --plan "$B/p04-s4-plan-r24.json" \
|
||||
--godot /Applications/Godot.app/Contents/MacOS/Godot
|
||||
```
|
||||
|
||||
The first invocation only prepares the pinned plan: zero engine launches. The
|
||||
@@ -39,20 +37,18 @@ inputs. Reader uses only the existing IO1 formal package mapping.
|
||||
|
||||
Exact input footprints:
|
||||
|
||||
- Current S4 wrapper SHA256:
|
||||
`6d5f4e05e87607413bfb5498dc9c9e17c2bfd96bf751c9e645050ca6f8e69d5c`.
|
||||
The plan pins these exact bytes; `p04_native_series.py` checks the wrapper
|
||||
against the current source file dynamically. Historical r22 receipts remain
|
||||
unchanged and do not describe this r23 wrapper.
|
||||
- Current wrapper SHA256 is recorded in `../REPAIR24_STATUS.md`. The plan pins
|
||||
its exact bytes and Stage R checks them against the current source checkout.
|
||||
- `B/audit-support/p04-r17-full-inputs-r01/MANIFEST.json`, SHA256
|
||||
`a15f29fa12537f6d8aaf7cabea390922a9f16e3eb9c10981e5742aafc8c4c8a8`.
|
||||
- All 1338 files below that relocation's `product/`, each matched to the
|
||||
manifest by bytes/SHA. No source is omitted and no old path is followed.
|
||||
- Its `fixed/6ce6b28c5985e8a4f13b78bfeb1f1e09f6216d874fb01e0656ec1633bfa01cd7/completion_marker_contracts.json`.
|
||||
- `B/audit-support/p04-review-repair22-r01/ACTUAL_CURRENT_PUBLIC_POWER_FUNCTIONS.json`.
|
||||
- The three staged S4 files above, pinned by the plan, and the staged native
|
||||
executable at B/audit-support/p04-s4-source-r23/Godot, pinned before native
|
||||
admission and checked unchanged after collection. The only stage override
|
||||
- The three staged S4 files above, pinned by the plan, and the installed executable
|
||||
`/Applications/Godot.app/Contents/MacOS/Godot`, pinned directly against the
|
||||
constant SHA before launch, during collection, and explicitly after cleanup.
|
||||
Before/during/after descriptors are retained in runner-input and execution. The only stage override
|
||||
is `tests/s3/test_runtime_staff_assignment.gd` with the S4 probe. Harness and
|
||||
kitchen fixture are the unchanged product files; inherited sources are
|
||||
included in the full1338 map. The parse roster is all316 `.gd` inputs.
|
||||
@@ -61,14 +57,15 @@ Exact input footprints:
|
||||
the actual full import. All316 scripts are parsed before Writer and Reader.
|
||||
- The engine SHA256 is
|
||||
`c7cccbf8fb143e34e02fd6521e09be2c2b974f0d5db080b19071c9c570718ccf`,
|
||||
matching the installed executable and preserved r22 staged executable during
|
||||
source preparation. Fresh mode does not obtain engine identity from a cache.
|
||||
required directly of the installed executable. Fresh mode does not obtain engine identity from a cache.
|
||||
- Optional `--cache-run` retains the registered path, passed-run, complete-source
|
||||
and engine identity guards. The known red run remains ineligible. The commands
|
||||
above use no cache. Preserve the old r22 staging and plan unchanged.
|
||||
above use no cache. Preserve the old r22 staging and plan unchanged. r22 is an immutable failed
|
||||
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-r23.json` and the fresh
|
||||
`B/p04-s4-native-r22/**`: private selected source stage, complete phase receipts
|
||||
Exact output footprints are `B/p04-s4-plan-r24.json` and the fresh
|
||||
`B/p04-s4-native-r24/**`: 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`,
|
||||
@@ -109,10 +106,9 @@ capacity and consumer allocation. Transient `_last_report` is cleared on normal
|
||||
restore and is not part of Runtime snapshot equality. The derived
|
||||
`related_facility_operating` flag is measured separately and checked after restore.
|
||||
|
||||
After successful S4, Root can perform the eight local suites and fresh read-only
|
||||
R collection described in EVIDENCE_COLLECTION.md. S4 is missing until the actual
|
||||
collection succeeds. Subsequent index/cross-gate work is not a source-preparation
|
||||
blocker. Rebind support53cb through its normal registered task against the new
|
||||
source. Preserve the21615-check proof. Only if exact final1339 evidence is
|
||||
required, perform one full run after all fixes, S4, local checks, eight suites
|
||||
and rebind are bundled. Never splice different-version raw or claim1339 identity.
|
||||
This source-only dispatch authorizes no worker execution. Root stages the three
|
||||
files, creates the r24 plan with --check-only, then collects once to the fresh
|
||||
r24 output. 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
|
||||
and formal acceptance remain pending. D05 remains pending.
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Root-only engine identity controls; tests NOT RUN by worker."""
|
||||
import copy
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
from unittest.mock import patch
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
HERE = Path(__file__).resolve().parent
|
||||
spec = importlib.util.spec_from_file_location("series", HERE.parent / "p04_native_series.py")
|
||||
series = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(series)
|
||||
spec = importlib.util.spec_from_file_location("s4", HERE / "run_s4_native.py")
|
||||
s4 = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(s4)
|
||||
|
||||
|
||||
def run():
|
||||
# Read only the real installed executable. Never copy or write an engine.
|
||||
pin = s4.engine_pin(s4.ENGINE)
|
||||
identity = dict(before=pin, during=[pin], after=pin)
|
||||
results = []
|
||||
|
||||
def reject(label, action):
|
||||
try:
|
||||
action()
|
||||
except (ValueError, OSError, KeyError, TypeError) as caught:
|
||||
results.append(dict(case=label, result="rejected", error=str(caught)))
|
||||
else:
|
||||
raise AssertionError("negative accepted: " + label)
|
||||
|
||||
# Same bytes/SHA cannot admit an own-B bare copy or another outside-B path.
|
||||
for label, path in [
|
||||
("copied bare engine in B with same SHA", s4.BUILD / "audit-support/p04-s4-source-r24/Godot"),
|
||||
("other outside-B path", Path("/Applications/OtherGodot.app/Contents/MacOS/Godot")),
|
||||
]:
|
||||
other = dict(pin, path=str(path))
|
||||
reject(label, lambda other=other: series.verify_s4_engine(other, identity))
|
||||
reject(label + " wrapper", lambda path=path: s4.engine_pin(path))
|
||||
reject("SHA mismatch", lambda: series.verify_s4_engine(dict(pin, sha256="0" * 64), identity))
|
||||
with patch.object(s4, "ENGINE_SHA256", "0" * 64):
|
||||
reject("wrapper SHA mismatch", lambda: s4.engine_pin(s4.ENGINE))
|
||||
changed = copy.deepcopy(identity)
|
||||
changed["after"]["inode"] += 1
|
||||
reject("after-identity mismatch", lambda: series.verify_s4_engine(pin, changed))
|
||||
reject("wrapper after-identity mismatch",
|
||||
lambda: s4.engine_pin(s4.ENGINE, dict(pin, inode=pin["inode"] + 1)))
|
||||
series.verify_s4_engine(pin, identity)
|
||||
results.append(dict(case="exact installed path", result="accepted"))
|
||||
return dict(scope="read-only engine identity fixtures", results=results, formal_acceptance=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(json.dumps(run(), indent=2, sort_keys=True))
|
||||
@@ -8,6 +8,7 @@ import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import stat
|
||||
import sys
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
@@ -17,7 +18,7 @@ PRODUCT = BUILD / "audit-support/p04-r17-full-inputs-r01/product"
|
||||
CACHE_RUN = BUILD / "p04-final-product-full-r01"
|
||||
TEST = "tests/s3/test_runtime_staff_assignment.gd"
|
||||
QA = HERE / "p04_s4_power_probe.gd"
|
||||
ENGINE = HERE / "Godot"
|
||||
ENGINE = Path("/Applications/Godot.app/Contents/MacOS/Godot")
|
||||
ENGINE_SHA256 = "c7cccbf8fb143e34e02fd6521e09be2c2b974f0d5db080b19071c9c570718ccf"
|
||||
MANIFEST = BUILD / "audit-support/p04-r17-full-inputs-r01/MANIFEST.json"
|
||||
MANIFEST_SHA = "a15f29fa12537f6d8aaf7cabea390922a9f16e3eb9c10981e5742aafc8c4c8a8"
|
||||
@@ -69,24 +70,52 @@ def pin(path):
|
||||
data = path.read_bytes()
|
||||
return dict(path=str(path), bytes=len(data), sha256=hashlib.sha256(data).hexdigest())
|
||||
|
||||
def engine_pin(path, expected=None):
|
||||
path = Path(path)
|
||||
if path != ENGINE or any(p.is_symlink() for p in (path, *path.parents)):
|
||||
raise ValueError("exact installed engine required; no symlink or relocated input")
|
||||
if path.resolve(strict=True) != ENGINE:
|
||||
raise ValueError("installed engine resolved path changed")
|
||||
before = path.stat()
|
||||
if not stat.S_ISREG(before.st_mode):
|
||||
raise ValueError("installed engine must be regular")
|
||||
digest = hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
after = path.stat()
|
||||
fields = ("st_dev", "st_ino", "st_size", "st_mtime_ns", "st_ctime_ns", "st_mode")
|
||||
if any(getattr(before, k) != getattr(after, k) for k in fields):
|
||||
raise ValueError("engine changed while hashing")
|
||||
if any(p.is_symlink() for p in (path, *path.parents)) or path.resolve(strict=True) != ENGINE:
|
||||
raise ValueError("engine path changed while hashing")
|
||||
value = dict(path=str(path), resolved_path=str(path.resolve(strict=True)),
|
||||
bytes=after.st_size, mtime_ns=after.st_mtime_ns, mode=after.st_mode,
|
||||
device=after.st_dev, inode=after.st_ino, ctime_ns=after.st_ctime_ns, sha256=digest)
|
||||
if digest != ENGINE_SHA256:
|
||||
raise ValueError("engine differs from installed engine constant")
|
||||
if expected is not None and value != expected:
|
||||
raise ValueError("engine identity changed")
|
||||
return value
|
||||
|
||||
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-r22")
|
||||
parser.add_argument("--plan", type=Path, default=BUILD / "p04-s4-plan-r23.json")
|
||||
parser.add_argument("--output", type=Path, default=BUILD / "p04-s4-native-r24")
|
||||
parser.add_argument("--plan", type=Path, default=BUILD / "p04-s4-plan-r24.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)
|
||||
parser.add_argument("--check-only", action="store_true")
|
||||
args = parser.parse_args()
|
||||
if args.godot.resolve() != ENGINE.resolve():
|
||||
raise ValueError("use the exact own-B staged engine")
|
||||
engine_descriptor = engine_pin(args.godot)
|
||||
if args.cache_run is not None and args.cache_run.resolve() != CACHE_RUN.resolve():
|
||||
raise ValueError("only registered own-B full-run cache")
|
||||
root = args.project_root.resolve()
|
||||
out = args.output.resolve()
|
||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.resolve()):
|
||||
raise ValueError("plan/output must stay in task build")
|
||||
if out.exists() or out.is_symlink():
|
||||
raise ValueError("fresh output required")
|
||||
if args.check_only and (args.plan.exists() or args.plan.is_symlink()):
|
||||
raise ValueError("fresh plan required")
|
||||
r = module("s4_standard_runner", root / "tools/run_all_tests.py")
|
||||
# Preserve the reviewed source_refs -> exactly one QA override order.
|
||||
source_before = r.source_refs(root)
|
||||
@@ -103,6 +132,10 @@ def main():
|
||||
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
||||
cache_note = None
|
||||
cache_receipts = []
|
||||
if args.cache_run is not None:
|
||||
# Reject failed caches before reading their inputs or cache contents.
|
||||
r.require(r.read(args.cache_run / "runner-ended.json")["passed"] is True,
|
||||
"failed cache is ineligible")
|
||||
for leaf in (["runner-ended.json", "runner-input.json"] if args.cache_run is not None else []):
|
||||
path = args.cache_run / leaf
|
||||
try:
|
||||
@@ -116,29 +149,37 @@ def main():
|
||||
QA_overrides=[TEST], fixed_input_pins=fixed,
|
||||
cache_run=str(args.cache_run) if args.cache_run is not None else None,
|
||||
import_mode="cache" if args.cache_run is not None else "fresh",
|
||||
engine_sha256=ENGINE_SHA256,
|
||||
engine_sha256=ENGINE_SHA256, engine=engine_descriptor,
|
||||
cache_receipts=cache_receipts, cache_access=cache_note,
|
||||
phases=["import", "parse", "writer", "reader"],
|
||||
native_engine_launches=0, whole_goal_accepted=False, unit_accepted=False)
|
||||
# Check-only only reads source/materials and writes the plan in task build.
|
||||
# It deliberately does not read default-player data, inspect processes or stat Godot.
|
||||
# Reads engine identity; never launches Godot or inspects players/processes.
|
||||
if args.check_only:
|
||||
args.plan.parent.mkdir(parents=True, exist_ok=True)
|
||||
if args.plan.exists():
|
||||
r.require(r.read(args.plan) == plan, "existing plan differs; use a fresh plan path")
|
||||
else:
|
||||
r.write(args.plan, plan)
|
||||
r.write(args.plan, plan)
|
||||
print(json.dumps(dict(check_only=True, engines=0, source_files=len(source_before),
|
||||
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
||||
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
||||
return 0
|
||||
r.require(root == PRODUCT.resolve() and len(source_before) == 1338, "Root native requires product 1338; worker plan is not native evidence")
|
||||
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
||||
engine_descriptor = None
|
||||
engine_observations = []
|
||||
engine_identity = dict(before=engine_descriptor, during=[], after=None)
|
||||
def repin(label):
|
||||
try:
|
||||
value = engine_pin(args.godot, engine_descriptor)
|
||||
engine_observations.append(dict(stage=label, descriptor=value))
|
||||
if label == "after-cleanup":
|
||||
engine_identity["after"] = value
|
||||
else:
|
||||
engine_identity["during"].append(value)
|
||||
except BaseException as caught:
|
||||
engine_observations.append(dict(stage=label, error=str(caught)))
|
||||
raise
|
||||
def fixed_guard():
|
||||
repin("cleanup-fixed-guard")
|
||||
template_guard(root)
|
||||
if engine_descriptor is not None:
|
||||
r.require(pin(engine_descriptor["path"]) == engine_descriptor, "engine changed during collection")
|
||||
for value in fixed + cache_receipts:
|
||||
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
||||
fixed_guard()
|
||||
@@ -147,20 +188,16 @@ def main():
|
||||
# Native cache admission remains Root-only and fails closed.
|
||||
r.require(cache_note is None, "Root must read exact cache receipts: " + str(cache_note))
|
||||
r.require(r.read(old / "runner-ended.json")["passed"], "ended cache run must have passed")
|
||||
old_map = r.read(old / "runner-input.json")["selected_source_map"]
|
||||
cache_input = r.read(old / "runner-input.json")
|
||||
r.require(cache_input["engine_sha256"] == ENGINE_SHA256, "cache engine identity")
|
||||
old_map = cache_input["selected_source_map"]
|
||||
current_map = {n: p["sha256"] for n, p in source_before.items()}
|
||||
r.require({k: v for k, v in old_map.items() if k != "tools/check_p04_order_evidence.py"} == current_map and len(old_map) == 1339, "immutable full cache: all 1338 product inputs equal; checker is not parsed/executed by product suites")
|
||||
protected = r.default_player(root)
|
||||
outer = module("s4_owned_outer", r.SUPPORT / "owned_outer.py")
|
||||
r.require(not outer.native.helper["live_engines"](), "another Godot owns CPU")
|
||||
engine = args.godot.resolve()
|
||||
r.require(engine.is_file(), "Root native Godot path")
|
||||
engine_descriptor = pin(engine)
|
||||
r.require(engine_descriptor["sha256"] == ENGINE_SHA256,
|
||||
"exact reviewed staged engine; no environment substitution")
|
||||
if old is not None:
|
||||
r.require(engine_descriptor["sha256"] == r.read(old / "runner-input.json")["engine_sha256"],
|
||||
"staged engine matches preserved full proof; no environment substitution")
|
||||
engine = ENGINE
|
||||
repin("native-admission")
|
||||
r.require(shutil.disk_usage(out.parent).free >= 1024**3 + engine.stat().st_size + 136*1024**2,
|
||||
"reviewed native disk admission")
|
||||
r.require(not out.exists(), "fresh output required; preserve previous attempts")
|
||||
@@ -225,7 +262,7 @@ def main():
|
||||
r.require(TEST not in policy["suite_policies"], "no normal suite watchdog/policy override")
|
||||
r.write(out / "contracts.json", contracts)
|
||||
r.write(out / "runner-input.json", dict(plan, owner_runner_pid=os.getpid(),
|
||||
wrapper_sha256=r.sha(__file__), QA=pin(QA), engine=engine_descriptor, runner_sha256=r.sha(root / "tools/run_all_tests.py"),
|
||||
wrapper_sha256=r.sha(__file__), QA=pin(QA), engine=engine_descriptor, engine_identity=engine_identity, runner_sha256=r.sha(root / "tools/run_all_tests.py"),
|
||||
default_player_before=protected, fixed_input_pins=fixed,
|
||||
functional_watchdog_seconds=1200, source_adoption=False))
|
||||
diagnostics = module("s4_diagnostics", r.SUPPORT / "diagnostic_gate.py")
|
||||
@@ -240,6 +277,8 @@ def main():
|
||||
if phase == "import" and old is None:
|
||||
r.require(not (stage / ".godot").exists() and not (stage / ".godot").is_symlink(),
|
||||
"fresh private .godot absent at actual import")
|
||||
repin("before-" + phase)
|
||||
r.write(out / "engine-identity.json", engine_observations)
|
||||
row = r.execute_phase(str(engine), stage, out, phase, test, selected, expected,
|
||||
previous, policy, contracts, paths, public, protected, root,
|
||||
outer, markers, diagnostics, owners, audio)
|
||||
@@ -260,6 +299,7 @@ def main():
|
||||
"exact one independent Writer/Reader case")
|
||||
r.require(sorted(receipt["slots"]) == SLOTS, "all formal point slots")
|
||||
r.require(receipt["pid"] == row["actual_pid"], "actual native PID/receipt")
|
||||
repin("after-collection")
|
||||
writer = r.read(out / "raw/writer.json")
|
||||
reader = r.read(out / "raw/reader.json")
|
||||
r.require(writer["pid"] != reader["pid"] and writer["profile"] != reader["profile"], "distinct formal processes")
|
||||
@@ -268,11 +308,19 @@ def main():
|
||||
except BaseException as caught:
|
||||
error = type(caught).__name__ + ": " + str(caught)
|
||||
finally:
|
||||
cleanup, cleanup_errors = outer.finish_captured(outer.OWNED)
|
||||
try:
|
||||
cleanup, cleanup_errors = outer.finish_captured(outer.OWNED)
|
||||
except BaseException as caught:
|
||||
cleanup_errors.append(str(caught))
|
||||
try:
|
||||
r.write(out / "outer-owned-finally.json", dict(cleanup=cleanup, errors=cleanup_errors))
|
||||
except BaseException as caught:
|
||||
guards.append("finally receipt: " + type(caught).__name__ + ": " + str(caught))
|
||||
# Explicit re-pin after cleanup is independent of other fixed-input guards.
|
||||
try:
|
||||
repin("after-cleanup")
|
||||
except BaseException as caught:
|
||||
guards.append(type(caught).__name__ + ": " + str(caught))
|
||||
# Fixed guard always follows ownership cleanup, even if setup or an engine failed.
|
||||
try:
|
||||
fixed_guard()
|
||||
@@ -318,6 +366,19 @@ def main():
|
||||
r.write(out / "formal-relocation.json", relocated)
|
||||
r.write(out / "raw-inventory.json", r.inventory(out / "raw"))
|
||||
r.write(out / "PID-set.json", dict(owner_runner_pid=os.getpid(), engine_PIDs=pids))
|
||||
try:
|
||||
repin("after-output-collection")
|
||||
except BaseException as caught:
|
||||
guards.append(str(caught))
|
||||
passed = False
|
||||
execution["passed"] = False
|
||||
r.write(out / "engine-identity.json", engine_observations)
|
||||
execution["engine_observations"] = engine_observations
|
||||
execution["engine_identity"] = engine_identity
|
||||
if (out / "runner-input.json").is_file():
|
||||
final_inputs = r.read(out / "runner-input.json")
|
||||
final_inputs["engine_identity"] = engine_identity
|
||||
r.write(out / "runner-input.json", final_inputs)
|
||||
r.write(out / "execution.json", execution)
|
||||
r.write(out / "runner-ended.json", dict(execution, ended=r.now()))
|
||||
print(json.dumps(dict(passed=passed, error=error, guard_errors=guards, output=str(out))))
|
||||
|
||||
Reference in New Issue
Block a user