#!/usr/bin/env python3 """Collect read-only preflight for the Telegram-visible DC benchmark. This is a pre-send proof collector. It verifies the exact authorization packet, then reads the VPS deploy stamp, Leo gateway service state, and current KB row counts. It never sends Telegram messages and never mutates the database. """ from __future__ import annotations import argparse import base64 import json import subprocess from dataclasses import dataclass from datetime import datetime, timezone from pathlib import Path from typing import Any, Callable REPORT_DIR = Path("docs/reports/leo-working-state-20260709") DEFAULT_PACKET = REPORT_DIR / "telegram-visible-direct-claim-authorization-packet-current.json" DEFAULT_OUT = REPORT_DIR / "telegram-visible-direct-claim-preflight-current.json" DEFAULT_MARKDOWN_OUT = REPORT_DIR / "telegram-visible-direct-claim-preflight-current.md" DEFAULT_SSH_TARGET = "root@77.42.65.182" DEFAULT_SSH_KEY = Path.home() / ".ssh/livingip_hetzner_20260604_ed25519" REMOTE_REPO = "/opt/teleo-eval/workspaces/deploy-infra" REMOTE_PACKET = ( f"{REMOTE_REPO}/docs/reports/leo-working-state-20260709/" "telegram-visible-direct-claim-authorization-packet-current.json" ) EXPECTED_PROMPT_IDS = ["DC-01", "DC-02", "DC-03", "DC-04", "DC-05", "DC-06"] @dataclass(frozen=True) class CommandResult: returncode: int stdout: str stderr: str Runner = Callable[[list[str], str, int], CommandResult] REMOTE_SCRIPT = r''' import json import subprocess from pathlib import Path repo = Path("__REMOTE_REPO__") packet_path = Path("__REMOTE_PACKET__") def run(command, **kwargs): return subprocess.run(command, text=True, capture_output=True, check=False, **kwargs) def service_state(): proc = run([ "systemctl", "show", "leoclean-gateway.service", "-p", "ActiveState", "-p", "SubState", "-p", "MainPID", "-p", "NRestarts", "-p", "ExecMainStartTimestamp", "--no-pager", ]) state = {} for line in proc.stdout.splitlines(): if "=" in line: key, value = line.split("=", 1) state[key] = value return {"returncode": proc.returncode, "stderr": proc.stderr, "state": state} def db_counts(): sql = """ select jsonb_build_object( 'public.claims', (select count(*) from public.claims), 'public.sources', (select count(*) from public.sources), 'public.claim_evidence', (select count(*) from public.claim_evidence), 'public.claim_edges', (select count(*) from public.claim_edges), 'kb_stage.kb_proposals', (select count(*) from kb_stage.kb_proposals) )::text; """ proc = run( ["docker", "exec", "-i", "teleo-pg", "psql", "-U", "postgres", "-d", "teleo", "-At", "-q"], input=sql, ) parsed = None if proc.returncode == 0 and proc.stdout.strip(): parsed = json.loads(proc.stdout.strip()) return {"returncode": proc.returncode, "stderr": proc.stderr, "counts": parsed} def git_value(args): proc = run(["git", "-C", str(repo), *args]) return {"returncode": proc.returncode, "stdout": proc.stdout.strip(), "stderr": proc.stderr.strip()} payload = { "deploy_head": git_value(["rev-parse", "HEAD"]), "last_deploy_sha": { "returncode": 0, "stdout": Path("/opt/teleo-eval/.last-deploy-sha").read_text(encoding="utf-8").strip(), "stderr": "", }, "packet_present": packet_path.exists(), "packet_bytes": packet_path.stat().st_size if packet_path.exists() else 0, "service": service_state(), "db_counts": db_counts(), } print(json.dumps(payload, sort_keys=True)) ''' def subprocess_runner(command: list[str], input_text: str, timeout: int) -> CommandResult: proc = subprocess.run(command, input=input_text, text=True, capture_output=True, timeout=timeout, check=False) return CommandResult(proc.returncode, proc.stdout, proc.stderr) def _load_json(path: Path) -> dict[str, Any]: return json.loads(path.read_text(encoding="utf-8")) def packet_checks(packet: dict[str, Any]) -> dict[str, bool]: target = packet.get("target", {}) return { "packet_ready_to_request_authorization": packet.get("ready_to_request_authorization") is True, "packet_not_sent": packet.get("telegram_visible_messages_sent") is False, "packet_has_no_authorization_recorded": packet.get("telegram_visible_message_authorization_present") is False, "packet_does_not_mutate_db": packet.get("mutates_db") is False, "packet_does_not_execute_production_apply": packet.get("production_apply_executed") is False, "packet_targets_leo_group": target.get("chat_label") == "Leo" and target.get("chat_id") == "-5146042086", "packet_prompt_ids_exact": target.get("expected_prompt_ids") == EXPECTED_PROMPT_IDS, "packet_message_count_exact": target.get("message_count") == len(EXPECTED_PROMPT_IDS), } def ssh_command(args: argparse.Namespace) -> list[str]: return [ "ssh", "-i", str(args.ssh_key), "-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=accept-new", "-o", f"ConnectTimeout={args.connect_timeout}", args.ssh_target, "python3 -", ] def parse_remote(stdout: str) -> dict[str, Any] | None: for line in reversed(stdout.splitlines()): line = line.strip() if not line.startswith("{"): continue try: return json.loads(line) except json.JSONDecodeError: continue return None def remote_payload_from_args(args: argparse.Namespace) -> tuple[dict[str, Any] | None, int, str]: if args.remote_json_base64: try: decoded = base64.b64decode(args.remote_json_base64, validate=True).decode("utf-8") return json.loads(decoded), 0, "" except Exception as exc: # noqa: BLE001 - retained in artifact as a parse gate return None, 2, f"failed to parse --remote-json-base64: {exc}" return None, -1, "" def collect_preflight(args: argparse.Namespace, *, runner: Runner = subprocess_runner) -> dict[str, Any]: packet = _load_json(args.packet) local_packet_checks = packet_checks(packet) supplied_payload, supplied_returncode, supplied_stderr = remote_payload_from_args(args) if supplied_returncode >= 0: remote_payload = supplied_payload remote_returncode = supplied_returncode remote_stderr = supplied_stderr remote_source = "supplied_remote_json_base64" else: remote_script = REMOTE_SCRIPT.replace("__REMOTE_REPO__", REMOTE_REPO).replace("__REMOTE_PACKET__", REMOTE_PACKET) command = ssh_command(args) remote_proc = runner(command, remote_script, args.timeout) remote_payload = parse_remote(remote_proc.stdout) if remote_proc.returncode == 0 else None remote_returncode = remote_proc.returncode remote_stderr = remote_proc.stderr remote_source = "ssh_subprocess" remote_checks = { "ssh_readback_ok": remote_returncode == 0 and remote_payload is not None, "remote_packet_present": bool((remote_payload or {}).get("packet_present")), "remote_packet_nonempty": int((remote_payload or {}).get("packet_bytes") or 0) > 0, "deploy_head_matches_last_deploy": False, "service_active_running": False, "db_counts_read": False, } if remote_payload: deploy_head = remote_payload.get("deploy_head", {}).get("stdout") last_deploy = remote_payload.get("last_deploy_sha", {}).get("stdout") service_state = remote_payload.get("service", {}).get("state", {}) counts = remote_payload.get("db_counts", {}).get("counts") remote_checks.update( { "deploy_head_matches_last_deploy": bool(deploy_head and deploy_head == last_deploy), "service_active_running": service_state.get("ActiveState") == "active" and service_state.get("SubState") == "running", "db_counts_read": isinstance(counts, dict) and all(key in counts for key in EXPECTED_DB_COUNT_KEYS), } ) status = "pass" if all(local_packet_checks.values()) and all(remote_checks.values()) else "fail" blocker_readback = { "current_canary": ( "Pre-send Telegram-visible direct-claim benchmark readiness for DC-01 through DC-06 in the " "Leo group, expecting packet verification plus VPS deploy/service/DB count readback before " "any authorized send." ), "attempted_routes": [ "local authorization packet validation", f"{remote_source} remote VPS readback for deploy stamp, service state, packet presence, and DB counts", ], "exact_gate": "" if status == "pass" else (remote_stderr.strip() or "remote readback checks did not pass"), "clear_CTA": ( "Run the remote readback from a full-access shell, base64-encode its JSON output, then rerun " "`scripts/collect_telegram_visible_direct_claim_preflight.py --remote-json-base64 `. " "Only after this report passes should the exact DC-01 through DC-06 Telegram group messages be " "sent under explicit action-time authorization." ), "next_non_user_action": ( "Rerun this preflight with supplied VPS remote readback JSON, then run the Telegram-visible " "DC scorer and service/DB after-readbacks if the user explicitly authorizes the group send." ), } return { "generated_at_utc": datetime.now(timezone.utc).isoformat(), "mode": "telegram_visible_direct_claim_preflight_readonly", "status": status, "ready_for_authorized_telegram_visible_dc_run": status == "pass", "telegram_visible_messages_sent": False, "production_apply_executed": False, "mutates_db": False, "packet_path": str(args.packet), "packet_checks": local_packet_checks, "remote_checks": remote_checks, "remote_source": remote_source, "remote": remote_payload, "remote_returncode": remote_returncode, "remote_stderr": remote_stderr, "blocker_readback": blocker_readback, "claim_ceiling": ( "This is a read-only preflight for an explicitly authorized Telegram-visible DC benchmark. It does " "not send Telegram messages, does not run production apply, and does not prove Telegram-visible DC " "behavior until the six-message run is authorized, sent, captured, and scored." ), } EXPECTED_DB_COUNT_KEYS = [ "public.claims", "public.sources", "public.claim_evidence", "public.claim_edges", "kb_stage.kb_proposals", ] def write_json(path: Path, data: dict[str, Any]) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8") def write_markdown(path: Path, data: dict[str, Any]) -> None: remote = data.get("remote") or {} service = remote.get("service", {}).get("state", {}) counts = remote.get("db_counts", {}).get("counts") or {} lines = [ "# Telegram-Visible Direct-Claim Preflight", "", f"Generated UTC: `{data['generated_at_utc']}`", f"Mode: `{data['mode']}`", f"Status: `{data['status']}`", f"Ready for authorized Telegram-visible DC run: `{data['ready_for_authorized_telegram_visible_dc_run']}`", f"Telegram-visible messages sent: `{data['telegram_visible_messages_sent']}`", f"Production apply executed: `{data['production_apply_executed']}`", f"Mutates DB: `{data['mutates_db']}`", f"Remote source: `{data['remote_source']}`", "", "## Packet Checks", "", ] lines.extend(f"- `{key}`: `{value}`" for key, value in sorted(data["packet_checks"].items())) lines.extend(["", "## Remote Checks", ""]) lines.extend(f"- `{key}`: `{value}`" for key, value in sorted(data["remote_checks"].items())) lines.extend( [ "", "## Deploy And Service", "", f"- Deploy head: `{remote.get('deploy_head', {}).get('stdout', '')}`", f"- Last deploy SHA: `{remote.get('last_deploy_sha', {}).get('stdout', '')}`", f"- ActiveState: `{service.get('ActiveState', '')}`", f"- SubState: `{service.get('SubState', '')}`", f"- MainPID: `{service.get('MainPID', '')}`", f"- NRestarts: `{service.get('NRestarts', '')}`", f"- ExecMainStartTimestamp: `{service.get('ExecMainStartTimestamp', '')}`", "", "## DB Counts Before Send", "", ] ) lines.extend(f"- `{key}`: `{counts.get(key, '')}`" for key in EXPECTED_DB_COUNT_KEYS) if data["status"] != "pass": blocker = data.get("blocker_readback", {}) lines.extend( [ "", "## Blocker Readback", "", f"- Current canary: {blocker.get('current_canary', '')}", f"- Exact gate: `{blocker.get('exact_gate', '')}`", f"- Clear CTA: {blocker.get('clear_CTA', '')}", f"- Next non-user action: {blocker.get('next_non_user_action', '')}", ] ) lines.extend(["", "## Claim Ceiling", "", data["claim_ceiling"], ""]) path.parent.mkdir(parents=True, exist_ok=True) path.write_text("\n".join(lines), encoding="utf-8") def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--packet", type=Path, default=DEFAULT_PACKET) parser.add_argument("--ssh-target", default=DEFAULT_SSH_TARGET) parser.add_argument("--ssh-key", type=Path, default=DEFAULT_SSH_KEY) parser.add_argument("--connect-timeout", type=int, default=10) parser.add_argument("--timeout", type=int, default=60) parser.add_argument( "--remote-json-base64", help="Base64-encoded remote readback JSON from an approved top-level SSH command; skips subprocess SSH.", ) parser.add_argument("--out", type=Path, default=DEFAULT_OUT) parser.add_argument("--markdown-out", type=Path, default=DEFAULT_MARKDOWN_OUT) return parser.parse_args(argv) def main(argv: list[str] | None = None) -> int: args = parse_args(argv) data = collect_preflight(args) write_json(args.out, data) write_markdown(args.markdown_out, data) print( json.dumps( { "out": str(args.out), "markdown_out": str(args.markdown_out), "status": data["status"], "ready_for_authorized_telegram_visible_dc_run": data[ "ready_for_authorized_telegram_visible_dc_run" ], }, indent=2, sort_keys=True, ) ) return 0 if data["status"] == "pass" else 2 if __name__ == "__main__": raise SystemExit(main())