Files
chimera-gfx-Public/tools/validate_retroarch_phase10q.py
Chimera GFX release export a6037502d7
phase0-ci / build-and-audit (push) Successful in 2m14s
Publish Chimera GFX source
2026-09-03 03:27:14 +02:00

285 lines
13 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
"""Validate Phase-1.0Q public VideoOut evidence and fail-closed decision."""
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
import subprocess
from typing import Any
PHASE = "PHASE_1_0Q_PUBLIC_VIDEOOUT_EVIDENCE"
STATUS = "PUBLIC_VIDEOOUT_EVIDENCE_INSUFFICIENT_PARAMETER_CHANGE_BLOCKED"
SDK_COMMIT = "d2e2e585740362976a39fdd5ccf390f199a7bc37"
SDL_COMMIT = "0baf4ac49382b537ba449901b5b6d0d189bb1fbb"
AUTHORIZATION_FIELDS = (
"target_build_authorized", "ps5_connection_authorized",
"device_transfer_authorized", "device_execution_authorized",
"result_receive_authorized", "installation_authorized",
"autoload_authorized", "device_write_authorized", "automatic_retry",
)
def load_json(path: Path) -> dict[str, Any]:
value = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(value, dict):
raise ValueError("evidence manifest is not an object")
return value
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def all_false(record: dict[str, Any], fields: tuple[str, ...]) -> bool:
return all(record.get(field) is False for field in fields)
def network_scope_is_bounded(record: dict[str, Any]) -> bool:
return (
record.get("github_metadata") is True
and record.get("official_source_archives") is True
and record.get("arbitrary_mirrors") is False
and record.get("downloaded_code_executed") is False
and record.get("ps5_address_used") is False
and record.get("ps5_connected") is False
)
def sdk_evidence_is_symbol_only(record: dict[str, Any]) -> bool:
return (
record.get("repository") == "https://github.com/ps5-payload-dev/sdk"
and record.get("release") == "v0.41"
and record.get("release_commit") == SDK_COMMIT
and record.get("latest_release_during_audit") is True
and record.get("master_commit_inspected")
== "a0d2bc60bdcc0a5ee9e790fa3b02fe5051a152d0"
and record.get("videoout_stub_size") == 25199
and record.get("videoout_stub_sha256")
== "da6cff9b3255e9ccb0440790f73e0265696ca47724cf8fe5950b579702940016"
and record.get("exports_only") is True
and record.get("public_videoout_header") is False
and record.get("signatures_or_layouts") is False
and record.get("return_semantics") is False
)
def sdl_lineage_is_single(record: dict[str, Any]) -> bool:
return (
record.get("repository") == "https://github.com/ps5-payload-dev/SDL"
and record.get("pinned_commit") == SDL_COMMIT
and record.get("initial_ps5_video_commit")
== "2682a5e31e8aee888538b0fb7253d8cadf2797a1"
and record.get("initial_source_size") == 7873
and record.get("initial_source_sha256")
== "1b9f917cac4e00ba1eccb22093e3ca079238f91c9a44ceefa9e23570ca9abab3"
and record.get("declaration_move_commit")
== "fdfa470a0fa33215c677193982dfe3651ac1321a"
and record.get("uint32_cleanup_commit")
== "14ac2ec2ab5889af47218a957e3456e613b13d3d"
and record.get("pinned_header_size") == 2878
and record.get("pinned_header_sha256")
== "e60766e0b43c2a7fceba2ada0c030e7f7b05e63885590092f2f8f5b9da34ed75"
and record.get("pinned_source_size") == 12162
and record.get("pinned_source_sha256")
== "44124546da132ea6e12b1f06a1808d61690c73460a65c3161e8453e8108684b6"
and record.get("independent_abi_source_cited") is False
and record.get("opaque_buffer_member_name") == "junk0"
and record.get("opaque_attribute_member_name") == "junk0"
and record.get("single_lineage_only") is True
)
def archives_do_not_corroborate(records: Any) -> bool:
expected = {
"ps5-payload-dev/libcross2d": ("829b167262d3567a048b6e69416f8e3be399c098", 1838927, "eb952a041396ba01224a890d14d41662b017488f487ddd4c4018ffddd4a59ae2", "SDL_CONSUMER"),
"ps5-payload-dev/pemu": ("4136088e13e825f33c9d0cc43ff9a8c8f749dcb0", 7540449, "9ed14a1ea432638992b614f9946bcbc9770f70b6f18ded5778fd6809a927eaeb", "SDL_CONSUMER"),
"ps5-payload-dev/FBNeo": ("ca4222ca2cd52215a673c565a5eae3589b352ba2", 15318689, "824d6e5b6b61555f5ecc598204052dcb4b1cf16d28be29b9594a44866e726ef3", "NO_DIRECT_IMPLEMENTATION"),
"ps5-payload-dev/LakeSnes": ("a2db690123649c7ffbc68a663af31efb3a41bf3f", 413067, "253a08957a68461a8535a4727ee1242c21b2dc40c8eb8c99bdb85af799ac3ca6", "SDL_CONSUMER"),
"ps5-payload-dev/yquake2": ("9e233b6a601c393be4ff1dcb1c003750346b8bbb", 2914919, "01ef41608b2be0ace119019901a6ea22f304542972bace714d1177cb7f567978", "SDL_CONSUMER"),
"ps5-payload-dev/pacbrew-repo": ("c2abcfcb60f569128abd0e8e70ad03a67bee5ea7", 143496, "17be50219ce41772cfc50ea9274b0a62a2259162556b6eeecfaed4a691822872", "REFERENCES_SAME_SDL_FORK"),
}
if not isinstance(records, list) or len(records) != 6:
return False
if {item.get("repository") for item in records} != set(expected):
return False
for item in records:
repository = item["repository"]
commit, size, digest, relationship = expected[repository]
if item.get("direct_videoout_hits") != 0:
return False
if item.get("relationship") != relationship:
return False
if item.get("commit") != commit or item.get("size") != size:
return False
if item.get("sha256") != digest:
return False
return True
def ps4_analogue_is_not_promoted(record: dict[str, Any]) -> bool:
return (
record.get("repository")
== "https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain"
and record.get("commit") == "0a1aaf9dd4a92695538bdeb09fb056d06dd11725"
and record.get("four_argument_submit") is True
and record.get("mode_one_documented_as_vsync") is True
and record.get("classification") == "PS4_ANALOG_ONLY"
and record.get("accepted_as_ps5_abi") is False
)
def evidence_matrix_is_fail_closed(record: dict[str, Any]) -> bool:
return record == {
"submit_signature": "PARTIAL_SINGLE_LINEAGE",
"argument_positions": "PARTIAL_SINGLE_LINEAGE",
"mode_one_semantics": "UNPROVEN_ON_PS5",
"frame_zero_validity": "UNPROVEN_ON_PS5",
"video_buffer_layout": "UNPROVEN",
"video_attribute_layout": "UNPROVEN",
"format_constant_semantics": "UNPROVEN",
"register_return_semantics": "PARTIAL_RUNTIME_ONLY",
"submit_error_semantics": "UNPROVEN",
"flip_master_or_active_app_requirement": "UNPROVEN",
"status_query_signatures_and_layouts": "UNPROVEN",
}
def decision_is_blocked(record: dict[str, Any]) -> bool:
return (
record.get("independent_ps5_abi_corroboration_found") is False
and record.get("root_cause_resolved") is False
and record.get("parameter_change_allowed") is False
and record.get("new_videoout_call_allowed") is False
and record.get("phase10r_target_artifact_allowed") is False
and record.get("phase10r_device_action_allowed") is False
and record.get("safe_next_steps") == [
"OFFLINE_LAUNCH_CONTEXT_COMPARISON",
"HOST_OR_SOFTWARE_ONLY_INTEGRATION",
]
)
def git(root: Path, *args: str) -> str:
result = subprocess.run(
["git", *args], cwd=root, capture_output=True, text=True, check=False)
if result.returncode:
raise RuntimeError(result.stderr.strip() or "git failed")
return result.stdout
def validate(root: Path, sdk_root: Path, sdl_root: Path) -> list[str]:
errors: list[str] = []
try:
record = load_json(
root / "manifests/retroarch/phase-1.0q-public-videoout-evidence.json")
except (OSError, ValueError, json.JSONDecodeError) as error:
return [str(error)]
if record.get("phase") != PHASE or record.get("status") != STATUS:
errors.append("phase/status mismatch")
if record.get("start_commit") != "df470c691f375b73768fd0d4a51dc2d35523e71d":
errors.append("start commit mismatch")
if not network_scope_is_bounded(record.get("network_scope", {})):
errors.append("network scope is broadened")
if not all_false(record.get("authorizations", {}), AUTHORIZATION_FIELDS):
errors.append("authorization remains active")
if not sdk_evidence_is_symbol_only(record.get("sdk", {})):
errors.append("SDK evidence was promoted")
if not sdl_lineage_is_single(record.get("sdl_lineage", {})):
errors.append("SDL lineage is incomplete or promoted")
if not archives_do_not_corroborate(record.get("official_project_archives")):
errors.append("official archive inventory mismatch")
storage = record.get("temporary_research_storage", {})
if storage != {
"archive_count": 6,
"downloaded_bytes": 28169547,
"retained_in_git": False,
"cleaned_after_static_scan": False,
"cleanup_status": "RETAINED_TEMP_LOCAL_DELETE_POLICY_BLOCKED",
}:
errors.append("temporary research storage boundary mismatch")
additional = record.get("additional_ps5_source", {})
if not (
additional.get("repository") == "https://github.com/PS5Dev/PS5SDK"
and additional.get("commit") == "a2e03a2a0231a3a3397fa6cd087a01ca6d04f273"
and additional.get("videoout_implementation_found") is False
and additional.get("classification") == "NO_CORROBORATION"
):
errors.append("additional PS5 source was promoted")
if not ps4_analogue_is_not_promoted(record.get("ps4_analogue", {})):
errors.append("PS4 analogue was promoted to PS5 ABI")
if not evidence_matrix_is_fail_closed(record.get("evidence_matrix", {})):
errors.append("evidence matrix mismatch")
if not decision_is_blocked(record.get("decision", {})):
errors.append("parameter or device path is not blocked")
performed = record.get("performed_actions", {})
if not all(value is False for value in performed.values()) or set(performed) != {
"target_source_changed", "target_artifact_created", "ps5_connected",
"device_transfer_performed", "target_execution_performed",
"result_received_from_device",
}:
errors.append("performed-action boundary mismatch")
tests = record.get("tests", {})
if not (
tests.get("chimera_gfx_ctest") == "62_OF_62_PASS"
and tests.get("phase10q_guardrails") == 20
and tests.get("network_required_by_tests") is False
and tests.get("hardware_claim_from_host_test") is False
):
errors.append("test evidence mismatch")
try:
if git(sdk_root, "rev-parse", "HEAD").strip() != SDK_COMMIT:
errors.append("local SDK release commit mismatch")
if git(sdl_root, "rev-parse", "HEAD").strip() != SDL_COMMIT:
errors.append("local SDL commit mismatch")
if git(sdk_root, "status", "--porcelain"):
errors.append("local SDK tree is dirty")
if git(sdl_root, "status", "--porcelain"):
errors.append("local SDL tree is dirty")
stub = sdk_root / "sce_stubs/libSceVideoOut.c"
header = sdl_root / "src/video/ps5/SDL_ps5video.h"
source = sdl_root / "src/video/ps5/SDL_ps5video.c"
if stub.stat().st_size != 25199 or sha256(stub) != record["sdk"]["videoout_stub_sha256"]:
errors.append("local VideoOut stub identity mismatch")
if header.stat().st_size != 2878 or sha256(header) != record["sdl_lineage"]["pinned_header_sha256"]:
errors.append("local SDL header identity mismatch")
if source.stat().st_size != 12162 or sha256(source) != record["sdl_lineage"]["pinned_source_sha256"]:
errors.append("local SDL source identity mismatch")
header_text = header.read_text(encoding="utf-8")
if "uint64_t junk0[3]" not in header_text or "uint8_t junk0[80]" not in header_text:
errors.append("opaque SDL declarations changed")
tracked = git(root, "ls-files").splitlines()
if any(path.lower().endswith((".elf", ".self", ".sprx", ".pkg", ".zip"))
for path in tracked):
errors.append("target or downloaded archive is tracked")
except (OSError, RuntimeError, KeyError) as error:
errors.append(str(error))
return errors
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--root", type=Path, required=True)
parser.add_argument("--sdk-root", type=Path, required=True)
parser.add_argument("--sdl-root", type=Path, required=True)
args = parser.parse_args()
errors = validate(args.root.resolve(), args.sdk_root.resolve(), args.sdl_root.resolve())
if errors:
for error in errors:
print(f"ERROR: {error}")
return 1
print("Phase-1.0Q public VideoOut evidence validation passed")
return 0
if __name__ == "__main__":
raise SystemExit(main())