#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """Host-only policy mutation tests for Phase-1.0F.""" from __future__ import annotations import argparse import importlib.util from pathlib import Path import sys from typing import Callable def load_validator(path: Path): spec = importlib.util.spec_from_file_location("phase10f_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 require(condition: bool, message: str) -> None: if not condition: raise RuntimeError(message) def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--root", type=Path, required=True) args = parser.parse_args() root = args.root.resolve() validator = load_validator(root / "tools/validate_retroarch_phase10f.py") record = validator.load_json( root / "manifests/retroarch/phase-1.0f-startup-interval.json" ) phase10e = validator.load_json( root / "manifests/retroarch/phase-1.0e-result-channel.json" ) cases: list[tuple[str, Callable[[], None]]] = [] def case(name: str): def register(function: Callable[[], None]) -> Callable[[], None]: cases.append((name, function)) return function return register @case("01 all authorizations are false") def _() -> None: require(validator.all_false(record["authorizations"], validator.AUTHORIZATION_FIELDS), "authorization active") @case("02 later connection authorization fails") def _() -> None: value = dict(record["authorizations"]) value["ps5_connection_authorized"] = True require(not validator.all_false(value, validator.AUTHORIZATION_FIELDS), "connection accepted") @case("03 no device action is recorded") def _() -> None: require(validator.all_false(record["phase_actions"], validator.ACTION_FIELDS), "device action recorded") @case("04 exact reproducible artifact passes") def _() -> None: require(validator.artifact_is_exact(record["artifact"]), "artifact rejected") @case("05 differing second build fails") def _() -> None: value = dict(record["artifact"]) value["clean_build_sha256"] = [validator.ARTIFACT_SHA256, "0" * 64] require(not validator.artifact_is_exact(value), "mismatch accepted") @case("06 execution eligibility fails") def _() -> None: value = dict(record["artifact"]) value["execution_eligible"] = True require(not validator.artifact_is_exact(value), "eligibility accepted") @case("07 bounded F protocol passes") def _() -> None: require(validator.protocol_is_bounded(record["result_protocol"]), "protocol rejected") @case("08 Phase E magic fails") def _() -> None: value = dict(record["result_protocol"]) value["magic"] = "CHD10E01" require(not validator.protocol_is_bounded(value), "old magic accepted") @case("09 interval notification fails") def _() -> None: value = dict(record["result_protocol"]) value["interval_notification_calls"] = 1 require(not validator.protocol_is_bounded(value), "notification accepted") @case("10 target retry fails") def _() -> None: value = dict(record["result_protocol"]) value["target_write_retry"] = True require(not validator.protocol_is_bounded(value), "retry accepted") @case("11 all fifteen interval callsites are bound") def _() -> None: require(validator.interval_callsites_are_complete(record["interval_callsites"]), "callsites rejected") @case("12 duplicate callsite address fails") def _() -> None: values = [dict(item) for item in record["interval_callsites"]] values[-1]["address"] = values[0]["address"] require(not validator.interval_callsites_are_complete(values), "duplicate accepted") @case("13 ELF and imports match Phase E") def _() -> None: require(validator.elf_is_closed(record["elf"], phase10e), "ELF rejected") @case("14 RWX segment fails") def _() -> None: value = dict(record["elf"]) value["program_headers"] = [dict(item) for item in record["elf"]["program_headers"]] value["program_headers"][0]["flags"] = "RWE" require(not validator.elf_is_closed(value, phase10e), "RWX accepted") @case("15 new socket import fails") def _() -> None: value = dict(record["elf"]) value["undefined_symbols"] = list(record["elf"]["undefined_symbols"]) + ["socket"] value["undefined_symbol_count"] += 1 require(not validator.elf_is_closed(value, phase10e), "socket accepted") @case("16 init array fails") def _() -> None: value = dict(record["elf"]) value["init_array_size"] = 8 require(not validator.elf_is_closed(value, phase10e), "init array accepted") @case("17 parser is offline only") def _() -> None: require(validator.parser_is_offline_only(record["host_parser"]), "parser rejected") @case("18 live interval activation fails") def _() -> None: value = dict(record["host_parser"]) value["live_interval_activation_available"] = True require(not validator.parser_is_offline_only(value), "live activation accepted") @case("19 prior RUN C authority is not inherited") def _() -> None: prior = record["prior_evidence"] require(prior["authorization_consumed"] is True and prior["authority_inherited"] is False, "authority inherited") @case("20 Phase F tests are not hardware evidence") def _() -> None: require(record["tests"]["hardware_evidence_from_phase10f"] is False, "offline test promoted") @case("21 startup remains side-effecting") def _() -> None: require(record["startup_effects"]["side_effect_free"] is False, "side effects hidden") @case("22 inactive approval grants nothing") def _() -> None: text = (root / "docs/approvals/phase-1.0f-device-test-template.md").read_text(encoding="utf-8") require("ps5_connection_authorized=false" in text and "result_receive_authorized=false" in text, "template authorizes action") @case("23 no target artifact is tracked") def _() -> None: tracked = validator.git(root, "ls-files").splitlines() require(not any(path.lower().endswith((".elf", ".self", ".sprx", ".pkg", ".map")) for path in tracked), "artifact tracked") @case("24 normalized disassembly is reproducible") def _() -> None: require( record["static_reachability"]["normalized_disassembly_sha256"] == [validator.DISASSEMBLY_SHA256] * 2, "disassembly mismatch", ) failures: list[str] = [] for name, function in cases: try: function() print(f"PASS {name}") except Exception as error: # noqa: BLE001 - mutation harness failures.append(f"{name}: {error}") print(f"FAIL {name}: {error}") if failures: return 1 print(f"Phase-1.0F policy tests passed: {len(cases)}") return 0 if __name__ == "__main__": raise SystemExit(main())