P04-01: 同時発生の更新規約

This commit is contained in:
Agent Control Runner
2026-10-18 11:25:54 +09:00
parent 1b08d6b0fc
commit 27b18b75c9
5 changed files with 306 additions and 17 deletions
@@ -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())