#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """Mutation guardrails for Phase-1.0AC dormant-adapter evidence.""" from __future__ import annotations import argparse from copy import deepcopy import importlib.util from pathlib import Path import sys def load(path: Path): spec = importlib.util.spec_from_file_location("phase10ac_validator", path) assert spec and spec.loader module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--root", type=Path, required=True) args = parser.parse_args() root = args.root.resolve() validator = load(root / "tools/validate_retroarch_phase10ac.py") original = validator.load_json( root / "manifests/retroarch/phase-1.0ac-dormant-adapter.json") cases = [] def mutation(name, function): cases.append((name, function)) mutation("01 activation rejected", lambda r: r["activation"].update(active=True)) mutation("02 target rejected", lambda r: r["activation"].update(target_address="device.invalid")) mutation("03 adapter activation hash rejected", lambda r: r["activation"].update(adapter_sha256="00" * 32)) mutation("04 connection authority rejected", lambda r: r["authorizations"].update(ps5_connection_authorized=True)) mutation("05 request authority rejected", lambda r: r["authorizations"].update(device_request_authorized=True)) mutation("06 result authority rejected", lambda r: r["authorizations"].update(result_receive_authorized=True)) mutation("07 retry rejected", lambda r: r["authorizations"].update(automatic_retry=True)) mutation("08 reconnect rejected", lambda r: r["authorizations"].update(reconnect_authorized=True)) mutation("09 live protocol rejected", lambda r: r["adapter"].update(live_adapter_protocol_present=True)) mutation("10 network import rejected", lambda r: r["adapter"].update(network_import_present=True)) mutation("11 real clock rejected", lambda r: r["adapter"].update(real_clock_present=True)) mutation("12 address rejected", lambda r: r["adapter"].update(address_present=True)) mutation("13 receipt requirement preserved", lambda r: r["adapter"].update(precommitted_receipt_required=False)) mutation("14 EOF rejection preserved", lambda r: r["lifecycle"].update(remote_eof_rejected=False)) mutation("15 deadline race rule preserved", lambda r: r["lifecycle"].update(deadline_wins_readiness_race=False)) mutation("16 remote cleanup not promoted", lambda r: r["lifecycle"].update(remote_cleanup_proven=True)) mutation("17 live implementation stop required", lambda r: r["hard_stops"].update(live_adapter_implementation=False)) mutation("18 live adapter decision rejected", lambda r: r["decision"].update(live_adapter_allowed=True)) mutation("19 performed device action rejected", lambda r: r["performed_actions"].update(ps5_connected=True)) mutation("20 hardware proof rejected", lambda r: r["tests"].update(hardware_claim_from_host_test=True)) failures = [] for name, mutate in cases: value = deepcopy(original); mutate(value) if validator.validate_record(value): print(f"PASS {name}") else: failures.append(name); print(f"FAIL {name}: mutation accepted") if failures: return 1 print(f"Phase-1.0AC guardrails passed: {len(cases)}") return 0 if __name__ == "__main__": raise SystemExit(main())