P04-01: 同時発生の更新規約
This commit is contained in:
+72
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"validation": "py_compile and ast only",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py",
|
||||||
|
"py_compile": "passed",
|
||||||
|
"ast.parse": "passed",
|
||||||
|
"ast.required_functions": "passed",
|
||||||
|
"ast.no_fixed_counts": "passed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/s5_wrapper_fixtures.py",
|
||||||
|
"py_compile": "passed",
|
||||||
|
"ast.parse": "passed"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fixtures": [
|
||||||
|
{
|
||||||
|
"name": "partial-triple",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "non-hex",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "short",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mixed-modes",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "historical-native",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "no-flags",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fresh-q",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "historical-check-only",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "git-dirty-file",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "git-untracked-file",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "git-wrong-head-tree",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "git-wrong-submission",
|
||||||
|
"status": "unexecuted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "git-wrong-main",
|
||||||
|
"status": "unexecuted"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"accepted": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# REPAIR35 — submitted preparation, no acceptance credit
|
||||||
|
|
||||||
|
Scope is the S5 wrapper fresh-Q mode, pure mode-selection fixtures and status
|
||||||
|
documents only. The wrapper now binds M/S/Q_tree, the clean checkout carrier,
|
||||||
|
selection authority, selected source bytes and Q marker contracts. Fixed-input
|
||||||
|
rechecks require identical provenance. Cache comparisons remove only checker
|
||||||
|
and TEST from both maps and otherwise compare keys and hashes. R17 is explicitly
|
||||||
|
check-only/read-only. Fresh-Q counts are derived; historical material is listed
|
||||||
|
as historical_not_inputs rather than pinned as fresh-Q input.
|
||||||
|
|
||||||
|
R34 structural C, Root normal_c_join, probe, adapter, ownership/PID/cleanup,
|
||||||
|
Writer/Reader, formal mirror and inventory remain unchanged. Product, Clock,
|
||||||
|
values, tests/, Runner, core and Owner CLI were read-only. No Git commands,
|
||||||
|
engines, Runner operations or fixture execution were performed. No /tmp or
|
||||||
|
permission additions were used. A shell heredoc could not be created by the
|
||||||
|
environment; that edit attempt exited before running Python or changing files.
|
||||||
|
Edits were then applied directly in place.
|
||||||
|
|
||||||
|
Only py_compile and AST static validation are recorded in
|
||||||
|
REPAIR35_STATIC_CHECKS.json. Pure fixtures (partial triple, non-hex, short,
|
||||||
|
mixed modes, historical native, no flags, full triple, historical check-only)
|
||||||
|
and all five Root Git negatives are **unexecuted**. No functional pass is claimed.
|
||||||
|
|
||||||
|
Pending: S5 destruction/midnight/exit drivers; fresh Q for S1–S4 and collector;
|
||||||
|
184 suites / 329 parse; truthful index; Root run order; Root exact-candidate
|
||||||
|
qualification. Root next builds Qt and parentless X, stages under its own B,
|
||||||
|
then runs check-only, pure fixtures and Git negatives as described in
|
||||||
|
s5/S5_ROOT_RUN.md. No native/batch admission until the pending prerequisites
|
||||||
|
are ready.
|
||||||
|
|
||||||
|
All 7 domains + EV, formal 16/88, original 30/88, P04 credit 0, all six D05
|
||||||
|
approvals, frozen M c0ea009b28a7649aca6a433a1a24dc0be5e7ab81 and allowed_paths
|
||||||
|
remain fixed. This is an internal step of P04-01, no new counted unit and no
|
||||||
|
completion claim. Unchanged support gates including owned_outer.py were not
|
||||||
|
read or executed; their qualification remains with Root, as recorded in the
|
||||||
|
direction. Source commit identity was not independently checked because Git
|
||||||
|
commands are prohibited for this worker.
|
||||||
@@ -6,10 +6,45 @@ Both use public resource commands, observed recovery, formal packages, independe
|
|||||||
Reader replay, phase raw and resource-command replay receipts. The bath has no
|
Reader replay, phase raw and resource-command replay receipts. The bath has no
|
||||||
item reservation; the dependent case retains and consumes the actual meal ID.
|
item reservation; the dependent case retains and consumes the actual meal ID.
|
||||||
|
|
||||||
`run_s5_native.py` retains the S4 ownership/engine/cleanup safeguards and historical
|
`run_s5_native.py` retains the S4 ownership/engine/cleanup safeguards. REPAIR35
|
||||||
template bindings. It is not fresh-Q plumbing. Do not run it against Q or start
|
adds fresh-Q input binding and separates historical R17 relocation checks from
|
||||||
the once-only native/full batch until the separately pending identity work is
|
the unchanged probe checks. All source and parse counts are derived. Historical
|
||||||
finished. No old S1–S4 record is renamed or reused as fresh proof.
|
R17 requires `--historical-r17 --check-only` and is read-only. Only historical
|
||||||
|
mode defaults `--project-root` to PRODUCT. Fresh-Q requires an explicit root and
|
||||||
|
all three full lowercase HEX40 inputs. R17 MANIFEST and repair22 power-functions
|
||||||
|
JSON are historical_not_inputs in fresh-Q plans, never fresh-Q fixed pins.
|
||||||
|
No old S1–S4 record is renamed or reused as fresh proof.
|
||||||
|
|
||||||
|
REPAIR35 is check-only only; no native/batch admission until S5
|
||||||
|
destruction/midnight/exit, S1–S4/collector fresh Q, 184 suites / 329 parse and the
|
||||||
|
truthful index are ready. Root run order and exact-candidate qualification also
|
||||||
|
remain pending. The native implementation is retained for later Root admission;
|
||||||
|
this change and a check-only plan give no admission or acceptance credit.
|
||||||
|
|
||||||
|
After final S35, Root alone performs these steps (not performed by the worker):
|
||||||
|
|
||||||
|
1. Set S to the final submission and M to
|
||||||
|
`c0ea009b28a7649aca6a433a1a24dc0be5e7ab81`; derive Qt with
|
||||||
|
`git merge-tree --write-tree "$M" "$S"`.
|
||||||
|
2. Create X with `git commit-tree "$Qt" -m 'nonproduction Q checkout'` with
|
||||||
|
**no parents**, then create a clean worktree at X. X is a nonproduction
|
||||||
|
checkout carrier of Q, never normal Runner C. R34 and Root normal_c_join
|
||||||
|
remain unchanged.
|
||||||
|
3. Stage the s5 directory under Root's own B, the registered BUILD directory.
|
||||||
|
4. Run only the check-only path, with fresh output and plan paths:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
BUILD_OUTPUT_DIR="$B" python3 "$B/.../run_s5_native.py" \
|
||||||
|
--project-root "$wt" --main "$M" --submission "$S" --tested-tree "$Qt" \
|
||||||
|
--check-only --plan "$B/p04-s5-plan-r35.json" --output "$B/p04-s5-native-r35"
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Run `s5_wrapper_fixtures.py` separately. Its JSON always has accepted=false.
|
||||||
|
6. In separate controlled check-only cases, require rejection for: a dirty file;
|
||||||
|
an untracked file; HEAD tree unequal to --tested-tree; wrong --submission;
|
||||||
|
--main unequal to the frozen anchor. Preserve each actual rejection receipt
|
||||||
|
and restore a clean carrier between cases. These Git negatives and all pure
|
||||||
|
fixtures are unexecuted in this worker submission. No engine runs.
|
||||||
|
|
||||||
Root later stages the wrapper, probe and this document in its own build area.
|
Root later stages the wrapper, probe and this document in its own build area.
|
||||||
The adapter takes `--raw-root`, `--writer-sha256`, `--reader-sha256` from verified
|
The adapter takes `--raw-root`, `--writer-sha256`, `--reader-sha256` from verified
|
||||||
@@ -19,4 +54,5 @@ measurement keys. It does not qualify source, engine, settings or full evidence.
|
|||||||
S5 destruction, midnight and exit cases remain unimplemented. The preserved
|
S5 destruction, midnight and exit cases remain unimplemented. The preserved
|
||||||
`PENDING.md` is historical partial31 text; this document records only the added,
|
`PENDING.md` is historical partial31 text; this document records only the added,
|
||||||
unexecuted power pair. D05 six approvals, A01, frozen M, 16/88 and P04 credit 0
|
unexecuted power pair. D05 six approvals, A01, frozen M, 16/88 and P04 credit 0
|
||||||
are unchanged. Root alone runs engines and scratch fixtures.
|
are unchanged. All 7 domains + EV and original 30/88 remain fixed. Root alone
|
||||||
|
performs later qualification; no engine is authorized by REPAIR35.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import hashlib
|
|||||||
import importlib.util
|
import importlib.util
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import stat
|
import stat
|
||||||
@@ -29,7 +30,7 @@ LABELS = {case: ["boundary", "held", "recovered"] for case in CASES}
|
|||||||
SLOTS = sorted(case + "-" + label for case in CASES for label in LABELS[case])
|
SLOTS = sorted(case + "-" + label for case in CASES for label in LABELS[case])
|
||||||
MATERIALS = [MANIFEST, BUILD / "audit-support/p04-review-repair22-r01/ACTUAL_CURRENT_PUBLIC_POWER_FUNCTIONS.json"]
|
MATERIALS = [MANIFEST, BUILD / "audit-support/p04-review-repair22-r01/ACTUAL_CURRENT_PUBLIC_POWER_FUNCTIONS.json"]
|
||||||
|
|
||||||
def template_guard(root):
|
def r17_relocation_guard(root):
|
||||||
if root != PRODUCT.resolve() or not HERE.is_relative_to(BUILD.resolve()):
|
if root != PRODUCT.resolve() or not HERE.is_relative_to(BUILD.resolve()):
|
||||||
raise ValueError("Root must stage this exact QA/wrapper/plan inside own B")
|
raise ValueError("Root must stage this exact QA/wrapper/plan inside own B")
|
||||||
if pin(MANIFEST)["sha256"] != MANIFEST_SHA:
|
if pin(MANIFEST)["sha256"] != MANIFEST_SHA:
|
||||||
@@ -42,6 +43,8 @@ def template_guard(root):
|
|||||||
if Path(row["relocated"]).resolve() != root / name or any(
|
if Path(row["relocated"]).resolve() != root / name or any(
|
||||||
actual[k] != source[k] or actual[k] != row[k] for k in ("bytes", "sha256")):
|
actual[k] != source[k] or actual[k] != row[k] for k in ("bytes", "sha256")):
|
||||||
raise ValueError("relocated product differs: " + name)
|
raise ValueError("relocated product differs: " + name)
|
||||||
|
|
||||||
|
def probe_guard(root):
|
||||||
probe = QA.read_text()
|
probe = QA.read_text()
|
||||||
import re
|
import re
|
||||||
if ":=" in probe or re.search(r"\bvar\s+\w+\s*=", probe) or re.search(r"\bfor\s+\w+\s+in\b", probe):
|
if ":=" in probe or re.search(r"\bvar\s+\w+\s*=", probe) or re.search(r"\bfor\s+\w+\s+in\b", probe):
|
||||||
@@ -96,20 +99,94 @@ def engine_pin(path, expected=None):
|
|||||||
raise ValueError("engine identity changed")
|
raise ValueError("engine identity changed")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
C_REL = "docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json"
|
||||||
|
|
||||||
|
|
||||||
|
def select_mode(args):
|
||||||
|
"""Pure CLI mode selection; no filesystem or Git access."""
|
||||||
|
triple = (args.main, args.submission, args.tested_tree)
|
||||||
|
if any(value is not None for value in triple):
|
||||||
|
if (not all(isinstance(value, str) and re.fullmatch(r"[0-9a-f]{40}", value)
|
||||||
|
for value in triple) or args.historical_r17):
|
||||||
|
raise ValueError("fresh-q requires a full HEX40 triple without --historical-r17")
|
||||||
|
return "fresh-q"
|
||||||
|
if args.historical_r17 and args.check_only:
|
||||||
|
return "historical-r17-readonly"
|
||||||
|
raise ValueError("historical R17 is read-only; require --historical-r17 --check-only")
|
||||||
|
|
||||||
|
|
||||||
|
def fresh_q_guard(root, M, S, Qt):
|
||||||
|
gate = module("s5_gate", root / "tools/check_p04_order_evidence.py")
|
||||||
|
gate.require(Path(gate.__file__).resolve() == root / gate.CHECKER_PATH
|
||||||
|
and not root.is_symlink(), "fresh-q checker/root location")
|
||||||
|
gate.require(M == gate.MAIN_ANCHOR, "fresh-q main anchor")
|
||||||
|
commit, tree, entries = gate.actual_checkout()
|
||||||
|
gate.require(tree == Qt and commit != S and commit != M, "fresh-q checkout carrier")
|
||||||
|
gate.require(Path(os.environ["BUILD_OUTPUT_DIR"]).resolve() == BUILD.resolve(),
|
||||||
|
"fresh-q own BUILD_OUTPUT_DIR")
|
||||||
|
with gate.isolated_objects():
|
||||||
|
for value in (M, S):
|
||||||
|
gate.require(gate.git_bytes("cat-file", "-t", value) == b"commit\n", "commit input")
|
||||||
|
gate.submission_role(S)
|
||||||
|
composed = gate.git_bytes("-c", "rerere.enabled=false", "merge-tree", "--write-tree", M, S).decode().strip()
|
||||||
|
gate.require(re.fullmatch(r"[0-9a-f]{40}", composed) is not None and composed == Qt,
|
||||||
|
"fresh-q recomputed tree")
|
||||||
|
gate.require(hashlib.sha256(gate.git_bytes("show", M + ":tools/run_all_tests.py")).hexdigest()
|
||||||
|
== gate.SELECTION_SHA, "selection authority")
|
||||||
|
gate.require(gate.product_manifest(gate.tree_entries(M)) == gate.product_manifest(entries),
|
||||||
|
"fresh-q product unchanged")
|
||||||
|
sel = gate.selected_manifest(entries, require_checker=True)
|
||||||
|
r = module("s5_guard_runner", root / "tools/run_all_tests.py")
|
||||||
|
source_before = r.source_refs(root)
|
||||||
|
gate.require(source_before.keys() == sel.keys() and TEST in sel,
|
||||||
|
"fresh-q selected source keys")
|
||||||
|
gate.require({name: {key: value[key] for key in ("bytes", "sha256")}
|
||||||
|
for name, value in source_before.items()} == sel, "fresh-q selected bytes")
|
||||||
|
gate.require(C_REL in entries, "fresh-q contracts entry")
|
||||||
|
blob = gate.git_bytes("cat-file", "blob", entries[C_REL][1])
|
||||||
|
contract_pin = pin(root / C_REL)
|
||||||
|
gate.require(contract_pin["bytes"] == len(blob)
|
||||||
|
and contract_pin["sha256"] == hashlib.sha256(blob).hexdigest(),
|
||||||
|
"fresh-q contracts pin")
|
||||||
|
build = BUILD.resolve()
|
||||||
|
gate.require(HERE.is_relative_to(build), "fresh-q staged HERE inside BUILD")
|
||||||
|
for staged in [HERE, *HERE.rglob("*")]:
|
||||||
|
current = build
|
||||||
|
for part in staged.relative_to(build).parts:
|
||||||
|
current = current / part
|
||||||
|
gate.require(not current.is_symlink(), "fresh-q staged symlink")
|
||||||
|
gate.require(staged.is_dir() or stat.S_ISREG(staged.stat().st_mode),
|
||||||
|
"fresh-q staged regular file")
|
||||||
|
return dict(M=M, S=S, Q_tree=Qt, recomputed_Q=composed, checkout_commit=commit,
|
||||||
|
checkout_role="nonproduction Root checkout carrier of tree Q; NOT normal Runner C",
|
||||||
|
selected_manifest_sha256=gate.manifest_digest(sel), selected_file_count=len(sel),
|
||||||
|
product_file_count=len(sel)-1, selection_authority_sha256=gate.SELECTION_SHA)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument("--project-root", type=Path, default=PRODUCT)
|
parser.add_argument("--project-root", type=Path, default=None)
|
||||||
parser.add_argument("--output", type=Path, default=BUILD / "p04-s5-native-r32")
|
parser.add_argument("--output", type=Path, default=BUILD / "p04-s5-native-r32")
|
||||||
parser.add_argument("--plan", type=Path, default=BUILD / "p04-s5-plan-r32.json")
|
parser.add_argument("--plan", type=Path, default=BUILD / "p04-s5-plan-r32.json")
|
||||||
parser.add_argument("--cache-run", type=Path, default=None,
|
parser.add_argument("--cache-run", type=Path, default=None,
|
||||||
help="optional passed registered cache; default is fresh, without cache access")
|
help="optional passed registered cache; default is fresh, without cache access")
|
||||||
parser.add_argument("--godot", type=Path, default=ENGINE)
|
parser.add_argument("--godot", type=Path, default=ENGINE)
|
||||||
parser.add_argument("--check-only", action="store_true")
|
parser.add_argument("--check-only", action="store_true")
|
||||||
|
parser.add_argument("--main")
|
||||||
|
parser.add_argument("--submission")
|
||||||
|
parser.add_argument("--tested-tree")
|
||||||
|
parser.add_argument("--historical-r17", action="store_true")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
mode = select_mode(args)
|
||||||
|
if mode == "fresh-q" and args.project_root is None:
|
||||||
|
raise ValueError("fresh-q requires explicit --project-root")
|
||||||
|
project_root = args.project_root if args.project_root is not None else PRODUCT
|
||||||
|
if project_root.is_symlink():
|
||||||
|
raise ValueError("project root symlink")
|
||||||
engine_descriptor = engine_pin(args.godot)
|
engine_descriptor = engine_pin(args.godot)
|
||||||
if args.cache_run is not None and args.cache_run.resolve() != CACHE_RUN.resolve():
|
if args.cache_run is not None and args.cache_run.resolve() != CACHE_RUN.resolve():
|
||||||
raise ValueError("only registered own-B full-run cache")
|
raise ValueError("only registered own-B full-run cache")
|
||||||
root = args.project_root.resolve()
|
root = project_root.resolve()
|
||||||
out = args.output.resolve()
|
out = args.output.resolve()
|
||||||
if not out.is_relative_to(BUILD.resolve()) or not args.plan.resolve().is_relative_to(BUILD.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")
|
raise ValueError("plan/output must stay in task build")
|
||||||
@@ -122,13 +199,19 @@ def main():
|
|||||||
source_before = r.source_refs(root)
|
source_before = r.source_refs(root)
|
||||||
refs = dict(source_before)
|
refs = dict(source_before)
|
||||||
refs[TEST] = pin(QA)
|
refs[TEST] = pin(QA)
|
||||||
template_guard(root)
|
provenance = None
|
||||||
|
if mode == "fresh-q":
|
||||||
|
provenance = fresh_q_guard(root, args.main, args.submission, args.tested_tree)
|
||||||
|
else:
|
||||||
|
r17_relocation_guard(root)
|
||||||
|
probe_guard(root)
|
||||||
expected = {n: dict(bytes=p["bytes"], sha256=p["sha256"]) for n, p in refs.items()}
|
expected = {n: dict(bytes=p["bytes"], sha256=p["sha256"]) for n, p in refs.items()}
|
||||||
fixed = [pin(p) for p in MATERIALS + [
|
contracts_path = root / C_REL if mode == "fresh-q" else CONTRACTS
|
||||||
|
fixed = [pin(p) for p in ([] if mode == "fresh-q" else MATERIALS) + [
|
||||||
QA, Path(__file__), HERE / "S5_ROOT_RUN.md",
|
QA, Path(__file__), HERE / "S5_ROOT_RUN.md",
|
||||||
root / "tests/transport/test_runtime_transport.gd",
|
root / "tests/transport/test_runtime_transport.gd",
|
||||||
root / "tests/staff/test_rescue_elevator.gd",
|
root / "tests/staff/test_rescue_elevator.gd",
|
||||||
CONTRACTS,
|
contracts_path,
|
||||||
]]
|
]]
|
||||||
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
selected = dict(root_before=source_before, map={n: p["sha256"] for n, p in refs.items()}, timeout=1200)
|
||||||
cache_note = None
|
cache_note = None
|
||||||
@@ -145,7 +228,11 @@ def main():
|
|||||||
cache_note = dict(path=str(path), error=type(caught).__name__ + ": " + str(caught),
|
cache_note = dict(path=str(path), error=type(caught).__name__ + ": " + str(caught),
|
||||||
required_before_native=True)
|
required_before_native=True)
|
||||||
break
|
break
|
||||||
plan = dict(protocol="p04-s5-preparation-v1", project_root=str(root), output=str(out), engine_path=str(args.godot.resolve()),
|
plan = dict(protocol=("p04-s5-fresh-q-v1" if mode == "fresh-q" else "p04-s5-historical-r17-readonly-v1"),
|
||||||
|
mode=mode, provenance=provenance, historical_r17=mode != "fresh-q",
|
||||||
|
native_admissible=False, fresh_q_evidence=False,
|
||||||
|
historical_not_inputs=[str(p) for p in MATERIALS] if mode == "fresh-q" else [],
|
||||||
|
project_root=str(root), output=str(out), engine_path=str(args.godot.resolve()),
|
||||||
source_before=source_before, selected_source_map=selected["map"],
|
source_before=source_before, selected_source_map=selected["map"],
|
||||||
QA_overrides=[TEST], fixed_input_pins=fixed,
|
QA_overrides=[TEST], fixed_input_pins=fixed,
|
||||||
cache_run=str(args.cache_run) if args.cache_run is not None else None,
|
cache_run=str(args.cache_run) if args.cache_run is not None else None,
|
||||||
@@ -163,7 +250,9 @@ def main():
|
|||||||
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
QA_overrides=[TEST], fixed_pins=len(fixed), plan=str(args.plan),
|
||||||
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
plan_sha256=r.sha(args.plan), cache_access=cache_note), ensure_ascii=False))
|
||||||
return 0
|
return 0
|
||||||
r.require(root == PRODUCT.resolve() and len(source_before) == 1338, "Root native requires product 1338; worker plan is not native evidence")
|
if mode != "fresh-q":
|
||||||
|
raise ValueError("historical R17 is read-only")
|
||||||
|
r.require(len(source_before) == provenance["selected_file_count"], "fresh-q selected count")
|
||||||
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
r.require(args.plan.is_file() and r.read(args.plan) == plan, "run exact check-only plan first")
|
||||||
engine_observations = []
|
engine_observations = []
|
||||||
engine_identity = dict(before=engine_descriptor, during=[], after=None)
|
engine_identity = dict(before=engine_descriptor, during=[], after=None)
|
||||||
@@ -180,7 +269,9 @@ def main():
|
|||||||
raise
|
raise
|
||||||
def fixed_guard():
|
def fixed_guard():
|
||||||
repin("cleanup-fixed-guard")
|
repin("cleanup-fixed-guard")
|
||||||
template_guard(root)
|
r.require(fresh_q_guard(root, args.main, args.submission, args.tested_tree) == provenance,
|
||||||
|
"fresh-q provenance changed")
|
||||||
|
probe_guard(root)
|
||||||
for value in fixed + cache_receipts:
|
for value in fixed + cache_receipts:
|
||||||
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
r.require(pin(value["path"]) == value, "fixed input changed: " + value["path"])
|
||||||
fixed_guard()
|
fixed_guard()
|
||||||
@@ -193,7 +284,10 @@ def main():
|
|||||||
r.require(cache_input["engine_sha256"] == ENGINE_SHA256, "cache engine identity")
|
r.require(cache_input["engine_sha256"] == ENGINE_SHA256, "cache engine identity")
|
||||||
old_map = cache_input["selected_source_map"]
|
old_map = cache_input["selected_source_map"]
|
||||||
current_map = {n: p["sha256"] for n, p in source_before.items()}
|
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")
|
excluded = {"tools/check_p04_order_evidence.py", TEST}
|
||||||
|
r.require({k: v for k, v in old_map.items() if k not in excluded}
|
||||||
|
== {k: v for k, v in current_map.items() if k not in excluded},
|
||||||
|
"immutable cache selected inputs except checker and QA override")
|
||||||
protected = r.default_player(root)
|
protected = r.default_player(root)
|
||||||
outer = module("s5_owned_outer", r.SUPPORT / "owned_outer.py")
|
outer = module("s5_owned_outer", r.SUPPORT / "owned_outer.py")
|
||||||
r.require(not outer.native.helper["live_engines"](), "another Godot owns CPU")
|
r.require(not outer.native.helper["live_engines"](), "another Godot owns CPU")
|
||||||
@@ -254,10 +348,10 @@ def main():
|
|||||||
whole_cache=cache_before, independent_inode=True,
|
whole_cache=cache_before, independent_inode=True,
|
||||||
ordinary_import_required=True, ordinary_parse_required=True))
|
ordinary_import_required=True, ordinary_parse_required=True))
|
||||||
paths = ["res://" + n for n in sorted(refs) if n.endswith(".gd")]
|
paths = ["res://" + n for n in sorted(refs) if n.endswith(".gd")]
|
||||||
r.require(len(paths) == 316, "complete 316-script parse roster")
|
r.require(len(paths) == sum(name.endswith(".gd") for name in refs), "complete derived parse roster")
|
||||||
r.write(out / "parse-paths.json", paths)
|
r.write(out / "parse-paths.json", paths)
|
||||||
markers = module("s5_markers", root / "tools/strict_test_markers.py")
|
markers = module("s5_markers", root / "tools/strict_test_markers.py")
|
||||||
contracts = markers.load_contracts(CONTRACTS)
|
contracts = markers.load_contracts(contracts_path)
|
||||||
contracts[TEST] = dict(test=TEST, template="S5 power: <checks> checks, <failures> failures", required=True)
|
contracts[TEST] = dict(test=TEST, template="S5 power: <checks> checks, <failures> failures", required=True)
|
||||||
policy = r.read(r.SUPPORT / "suite-policy.json")
|
policy = r.read(r.SUPPORT / "suite-policy.json")
|
||||||
r.require(TEST not in policy["suite_policies"], "no normal suite watchdog/policy override")
|
r.require(TEST not in policy["suite_policies"], "no normal suite watchdog/policy override")
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Pure select_mode fixtures; no Git, engine, temporary files or environment access."""
|
||||||
|
import argparse
|
||||||
|
import importlib.util
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
path = Path(__file__).parent / "run_s5_native.py"
|
||||||
|
spec = importlib.util.spec_from_file_location("s5_wrapper_fixture_target", path)
|
||||||
|
wrapper = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(wrapper)
|
||||||
|
cases = [
|
||||||
|
("partial-triple", argparse.Namespace(main="a" * 40, submission=None, tested_tree=None,
|
||||||
|
historical_r17=False, check_only=True), None),
|
||||||
|
("non-hex", argparse.Namespace(main="z" * 40, submission="b" * 40, tested_tree="c" * 40,
|
||||||
|
historical_r17=False, check_only=True), None),
|
||||||
|
("short", argparse.Namespace(main="a" * 39, submission="b" * 40, tested_tree="c" * 40,
|
||||||
|
historical_r17=False, check_only=True), None),
|
||||||
|
("mixed-modes", argparse.Namespace(main="a" * 40, submission="b" * 40, tested_tree="c" * 40,
|
||||||
|
historical_r17=True, check_only=True), None),
|
||||||
|
("historical-native", argparse.Namespace(main=None, submission=None, tested_tree=None,
|
||||||
|
historical_r17=True, check_only=False), None),
|
||||||
|
("no-flags", argparse.Namespace(main=None, submission=None, tested_tree=None,
|
||||||
|
historical_r17=False, check_only=False), None),
|
||||||
|
("fresh-q", argparse.Namespace(main="a" * 40, submission="b" * 40, tested_tree="c" * 40,
|
||||||
|
historical_r17=False, check_only=True), "fresh-q"),
|
||||||
|
("historical-check-only", argparse.Namespace(main=None, submission=None, tested_tree=None,
|
||||||
|
historical_r17=True, check_only=True),
|
||||||
|
"historical-r17-readonly"),
|
||||||
|
]
|
||||||
|
results = []
|
||||||
|
for name, args, expected in cases:
|
||||||
|
try:
|
||||||
|
actual = wrapper.select_mode(args)
|
||||||
|
passed = expected is not None and actual == expected
|
||||||
|
except ValueError:
|
||||||
|
actual = "ValueError"
|
||||||
|
passed = expected is None
|
||||||
|
results.append(dict(name=name, result=actual, passed=passed))
|
||||||
|
print(json.dumps(dict(accepted=False, fixtures=results, passed=all(r["passed"] for r in results))))
|
||||||
|
return 0 if all(r["passed"] for r in results) else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user