#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """Validate the consumed Phase-1.0H one-shot device result.""" from __future__ import annotations import argparse import json from pathlib import Path import subprocess from typing import Any PHASE = "PHASE_1_0H_STARTUP_ARGUMENT_ONE_SHOT_DEVICE_RESULT" STATUS = "ONE_SHOT_AUTHORIZATION_CONSUMED_FLIP_SUBMIT_FAILED" ARTIFACT_SHA256 = "822f2cf1f4d33a514d2bdd88fde40ad580dda5d85f537362ef6dff2eafcb56b6" TRACE_SHA256 = "858a205afcf682a498d8bc11947b67d2446098883a61f6871e31df4d950d0a61" STAGES = [ "D00", "D01", "D02", "I00", "I01", "I02", "I03", "D12", "I04", "I05", "I06", "I07", "I08", "I09", "I10", "D10", "I11", "I12", "I13", "I14", "D03", "D05", "D06", "D07", "D04", ] AUTHORIZATION_FIELDS = ( "ps5_connection_authorized", "device_transfer_authorized", "device_execution_authorized", "result_receive_authorized", "installation_authorized", "autoload_authorized", "device_write_authorized", "automatic_retry", ) DELIVERABLES = ( "docs/retroarch/phase-1.0h-device-result.md", "manifests/retroarch/phase-1.0h-device-result.json", "tools/validate_retroarch_phase10h_result.py", "tests/test_retroarch_phase10h_result.py", ) def load_json(path: Path) -> dict[str, Any]: value = json.loads(path.read_text(encoding="utf-8")) if not isinstance(value, dict): raise ValueError("result manifest is not an object") return value def all_false(record: dict[str, Any], fields: tuple[str, ...]) -> bool: return all(record.get(field) is False for field in fields) def result_is_exact(record: dict[str, Any]) -> bool: raw = record.get("raw_results", {}) return ( record.get("magic") == "CHD10H01" and record.get("frame_size") == 64 and record.get("frame_count") == len(STAGES) == 25 and record.get("stages") == STAGES and raw == { "D02": 0, "D12_shutdown_reason": 6, "D12_first_error": 118, "D10": 1, "I11": 0, "D05": 1309671680, "D06": 0, "D07": -1, "D04": -1, } and record.get("last_frame") == "D04" and record.get("runloop_terminal_frame_present") is False and record.get("classification") == "STARTUP_ARGUMENT_FIX_PROVEN_VIDEOOUT_BUFFERS_READY_FLIP_SUBMIT_FAILED" ) def transport_is_one_shot(record: dict[str, Any]) -> bool: return ( record.get("connect_count") == 1 and record.get("sendall_count") == 1 and record.get("bytes_sent") == 1845152 and record.get("shutdown_write_count") == 1 and record.get("received_byte_count") == 3953 and record.get("raw_stream_stored_bytes") == 3953 and record.get("raw_stream_truncated") is False and record.get("retry_count") == 0 and record.get("reconnect_count") == 0 and record.get("close_called") is True and record.get("remote_eof_observed") is True ) def validate(root: Path) -> list[str]: errors: list[str] = [] for relative in DELIVERABLES: if not (root / relative).is_file(): errors.append(f"missing deliverable: {relative}") try: record = load_json(root / "manifests/retroarch/phase-1.0h-device-result.json") except (OSError, ValueError, json.JSONDecodeError) as error: return errors + [str(error)] if record.get("phase") != PHASE or record.get("status") != STATUS: errors.append("phase/status mismatch") artifact = record.get("artifact", {}) if not ( artifact.get("sha256") == ARTIFACT_SHA256 and artifact.get("size") == 1845152 and artifact.get("execution_eligible") is False and artifact.get("transfer_eligible") is False and artifact.get("installation_eligible") is False and artifact.get("tracked") is False ): errors.append("artifact is not exact and consumed") authorization = record.get("authorization", {}) if authorization.get("consumed") is not True or authorization.get("authority_inherited_by_future_action") is not False: errors.append("authorization is reusable") if not all_false(record.get("current_authorizations", {}), AUTHORIZATION_FIELDS): errors.append("a current authorization remains active") actions = record.get("performed_actions", {}) if not ( actions.get("ps5_connected") is True and actions.get("files_transferred") is True and actions.get("target_execution_performed") is True and actions.get("result_received_from_device") is True and actions.get("retry_performed") is False and actions.get("reconnect_performed") is False and actions.get("videoout_flip_submit_attempted") is True and actions.get("videoout_flip_submit_succeeded") is False ): errors.append("performed action record is incomplete") if not transport_is_one_shot(record.get("transport", {})): errors.append("transport is not exact one-shot") trace = record.get("trace", {}) if trace.get("sha256") != TRACE_SHA256 or trace.get("tracked") is not False or trace.get("parser_errors") != []: errors.append("trace identity/parser result mismatch") if not result_is_exact(record.get("protocol_result", {})): errors.append("frame sequence or raw results mismatch") source = record.get("source_binding", {}) if not ( source.get("startup_argument_fix_reached_i04") is True and source.get("write_firewall_triggered") is True and source.get("exact_blocked_write_operation") == "UNOBSERVED" and source.get("first_flip_submit_raw") == -1 and source.get("sdl_init_raw") == -1 and source.get("visible_presentation") == "UNPROVEN" and source.get("complete_cleanup") == "UNPROVEN" ): errors.append("source binding overclaims or omits blockers") tracked = subprocess.run( ["git", "ls-files"], cwd=root, capture_output=True, text=True, check=True ).stdout.splitlines() if any(path.lower().endswith((".elf", ".self", ".sprx", ".pkg", ".map")) for path in tracked): errors.append("target artifact is tracked") return errors def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--root", type=Path, required=True) args = parser.parse_args() errors = validate(args.root.resolve()) if errors: for error in errors: print(f"ERROR: {error}") return 1 print("Phase-1.0H consumed device result validation passed") return 0 if __name__ == "__main__": raise SystemExit(main())