P04-01: 同時発生の更新規約
This commit is contained in:
@@ -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