#!/usr/bin/env python3 """Project a fresh protected native-relay receipt through one pinned SSH route.""" from __future__ import annotations import argparse import os import pathlib import subprocess import time def parse_receipt(path: pathlib.Path) -> tuple[dict[str, str], float]: if path.is_symlink(): raise ValueError("relay receipt cannot be a symlink") stat = path.stat() values: dict[str, str] = {} for line in path.read_text(encoding="utf-8").splitlines(): if not line or line[:1].isspace() or ": " not in line: continue key, value = line.split(": ", 1) if key in values: raise ValueError(f"duplicate relay receipt key: {key}") values[key] = value return values, time.time() - stat.st_mtime def projection_action( values: dict[str, str], age: float, max_age: float, expected_source: str ) -> str: ready = ( age >= -5 and age <= max_age and values.get("schema") == "guanghu.physical-native-final-resident-relay/v1" and values.get("status") == "READY_NATIVE_RESIDENT" and values.get("recovery_capability_sent") == "false" and values.get("acknowledged_sequences") == "1,2,3,4,5,6" and values.get("observed_nat_sources") == expected_source ) return "ready" if ready else "dormant" def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--relay-receipt", required=True) parser.add_argument("--max-receipt-age-seconds", type=float, default=15.0) parser.add_argument("--expected-nat-source", required=True) parser.add_argument("--node", required=True) parser.add_argument("--relay", required=True) parser.add_argument("--candidate-sha256", required=True) parser.add_argument("--source-commit", required=True) parser.add_argument("--ssh-bin", default="/usr/bin/ssh") parser.add_argument("--ssh-config", required=True) parser.add_argument("--ssh-target", required=True) args = parser.parse_args() if args.max_receipt_age_seconds <= 0: raise SystemExit("max receipt age must be greater than zero") ssh_bin = pathlib.Path(args.ssh_bin) ssh_config = pathlib.Path(args.ssh_config) if not ssh_bin.is_absolute() or not os.access(ssh_bin, os.X_OK): raise SystemExit("SSH binary must be an executable absolute path") if not ssh_config.is_absolute() or not ssh_config.is_file(): raise SystemExit("SSH config must be an existing absolute file") try: values, age = parse_receipt(pathlib.Path(args.relay_receipt)) action = projection_action( values, age, args.max_receipt_age_seconds, args.expected_nat_source, ) except (OSError, UnicodeError, ValueError): action = "dormant" command = [ str(ssh_bin), "-F", str(ssh_config), "-o", "BatchMode=yes", "-o", "ConnectTimeout=5", args.ssh_target, action, args.node, args.candidate_sha256, args.source_commit, args.relay, ] completed = subprocess.run(command, check=False, timeout=10) if completed.returncode != 0: raise SystemExit("native projection transport failed closed") print(f"NATIVE_PUBLIC_PROJECTION_RELAY_OK action={action}") return 0 if __name__ == "__main__": raise SystemExit(main())