"""Tests for the disposable-DB no-send GatewayRunner checkpoint."""

from __future__ import annotations

import argparse
import asyncio
import json
import os
import re
import signal
import subprocess
import sys
import time
from pathlib import Path
from typing import Any

import pytest

REPO_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO_ROOT / "scripts"))

import run_leo_clone_bound_handler_checkpoint as checkpoint  # noqa: E402

PROPOSAL_ID = "11111111-1111-4111-8111-111111111111"
CLAIM_ID = "22222222-2222-4222-8222-222222222222"
SOURCE_ID = "33333333-3333-4333-8333-333333333333"
COUNTS = {
    "public.claims": 1837,
    "public.sources": 4145,
    "public.claim_evidence": 4670,
    "public.claim_edges": 4916,
    "public.reasoning_tools": 17,
    "kb_stage.kb_proposals": 27,
}
SERVICE = """ActiveState=active
SubState=running
MainPID=2999690
NRestarts=0
ExecMainStartTimestamp=Fri 2026-07-10 03:47:11 UTC
User=teleo
WorkingDirectory=/home/teleo
"""


@pytest.fixture(autouse=True)
def _clear_temp_registry() -> None:
    checkpoint.cleanup_active_gateway_children()
    checkpoint._ACTIVE_GATEWAY_CHILDREN.clear()
    checkpoint.cleanup_active_temp_roots()
    checkpoint._ACTIVE_TEMP_ROOTS.clear()
    yield
    checkpoint.cleanup_active_gateway_children()
    checkpoint._ACTIVE_GATEWAY_CHILDREN.clear()
    checkpoint.cleanup_active_temp_roots()
    checkpoint._ACTIVE_TEMP_ROOTS.clear()


def _write(path: Path, value: str = "fixture") -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(value, encoding="utf-8")


@pytest.fixture
def live_profile(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
    profile = tmp_path / "live-profile"
    _write(profile / "bin" / "teleo-kb", "#!/usr/bin/env bash\nexit 99\n")
    _write(profile / "bin" / "kb_tool.py", "raise SystemExit('fixture only')\n")
    _write(
        profile / "skills" / "teleo-kb-bridge" / "SKILL.md",
        "---\nname: teleo-kb-bridge\ndescription: fixture\n---\n\n"
        "Run /home/teleo/.hermes/profiles/leoclean/bin/teleo-kb show-proposal ID\n",
    )
    _write(profile / "SOUL.md", "Leo fixture\n")
    _write(profile / ".env", "DO_NOT_COPY_ENV=fixture-secret\n")
    _write(profile / "auth.json", '{"token":"do-not-copy"}\n')
    _write(profile / "secrets" / "telegram-token", "do-not-copy\n")
    _write(profile / "sessions" / "session.sqlite3", "do-not-copy\n")
    _write(profile / "state" / "gateway.db", "do-not-copy\n")
    _write(profile / "backups" / "profile.tar", "do-not-copy\n")
    _write(profile / "memory_backups" / "old.json", "do-not-copy\n")
    _write(profile / "bin" / "kb_tool.py.bak", "do-not-copy\n")
    symlink = profile / "linked-secret"
    try:
        symlink.symlink_to(profile / ".env")
    except OSError:
        pass

    temp_parent = tmp_path / "temp-roots"
    temp_parent.mkdir()

    def fake_mkdtemp(*, prefix: str) -> str:
        root = temp_parent / f"{prefix}pytest"
        root.mkdir()
        return str(root)

    monkeypatch.setattr(checkpoint, "LIVE_PROFILE", profile)
    monkeypatch.setattr(checkpoint, "AGENT_ROOT", tmp_path / "hermes-agent")
    monkeypatch.setattr(checkpoint.tempfile, "mkdtemp", fake_mkdtemp)
    return profile


def _proposal(status: str = "approved") -> dict[str, Any]:
    return {
        "id": PROPOSAL_ID,
        "proposal_type": "approve_claim",
        "status": status,
        "payload": {
            "claims": [{"id": CLAIM_ID, "body": "fixture claim"}],
            "sources": [{"id": SOURCE_ID, "title": "fixture source"}],
        },
        "reviewed_by_handle": "m3ta" if status in {"approved", "applied"} else None,
        "reviewed_at": "2026-07-10 16:00:00+00" if status in {"approved", "applied"} else None,
        "applied_by_handle": "kb-apply" if status == "applied" else None,
        "applied_at": "2026-07-10 16:05:00+00" if status == "applied" else None,
    }


def _target_checkpoint(database: str, status: str = "approved") -> dict[str, Any]:
    return {
        "database_identity": {
            "current_database": database,
            "database_oid": "24680",
            "system_identifier": "clone-system-id",
            "server_address": "local_socket",
            "server_port": None,
            "postmaster_started_at": "2026-07-10 15:00:00+00",
            "transaction_read_only": "on",
            "transaction_snapshot": "1:1:",
        },
        "counts": COUNTS,
        "proposals": [_proposal(status)],
    }


class FakeSubprocess:
    def __init__(
        self,
        *,
        database: str = "clone_db",
        status: str = "approved",
        mutate_target: bool = False,
        fail_read_only_verification_once: bool = False,
    ) -> None:
        self.database = database
        self.status = status
        self.calls: list[dict[str, Any]] = []
        self.target_read_only = False
        self.mutate_target = mutate_target
        self.fail_read_only_verification_once = fail_read_only_verification_once
        self.read_only_verification_failed = False
        self.target_guard_reads = 0

    def __call__(
        self,
        command: list[str],
        *,
        input: str | None,
        text: bool,
        capture_output: bool,
        check: bool,
    ) -> subprocess.CompletedProcess[str]:
        self.calls.append({"command": command, "input": input})
        assert text is True
        assert capture_output is True
        assert check is False

        if command[:2] == ["systemctl", "show"]:
            return subprocess.CompletedProcess(command, 0, SERVICE, "")
        if command[:2] == ["docker", "inspect"]:
            container = command[-1]
            is_clone = container in {"clone-pg", "clone-container-id"}
            identity = "clone-container-id" if is_clone else "production-container-id"
            payload = [
                {
                    "Id": identity,
                    "Name": "/clone-pg" if is_clone else f"/{checkpoint.PRODUCTION_CONTAINER}",
                    "Config": {
                        "Image": "postgres:16",
                        "Labels": (
                            {checkpoint.DISPOSABLE_LABEL_KEY: checkpoint.DISPOSABLE_LABEL_VALUE} if is_clone else {}
                        ),
                    },
                    "HostConfig": {"NetworkMode": "none" if is_clone else "bridge"},
                    "NetworkSettings": {"Ports": {}},
                    "Mounts": [{"Source": "clone-volume" if is_clone else "production-volume"}],
                    "State": {"StartedAt": "2026-07-10T15:00:00Z"},
                }
            ]
            return subprocess.CompletedProcess(command, 0, json.dumps(payload) + "\n", "")
        if command[:3] == ["docker", "exec", "-i"]:
            container = command[3]
            database = command[command.index("-d") + 1]
            sql = input or ""
            if "alter role postgres" in sql.lower():
                self.target_read_only = " reset " not in f" {sql.lower()} "
                return subprocess.CompletedProcess(command, 0, "", "")
            if "already_forced_read_only" in sql:
                return subprocess.CompletedProcess(
                    command,
                    0,
                    json.dumps({"already_forced_read_only": False}) + "\n",
                    "",
                )
            if "jsonb_build_object('transaction_read_only'" in sql:
                if (
                    self.fail_read_only_verification_once
                    and self.target_read_only
                    and not self.read_only_verification_failed
                ):
                    self.read_only_verification_failed = True
                    return subprocess.CompletedProcess(
                        command,
                        0,
                        json.dumps({"transaction_read_only": "off"}) + "\n",
                        "",
                    )
                return subprocess.CompletedProcess(
                    command,
                    0,
                    json.dumps({"transaction_read_only": "on" if self.target_read_only else "off"}) + "\n",
                    "",
                )
            if container == checkpoint.PRODUCTION_CONTAINER:
                assert database == checkpoint.PRODUCTION_DB
                assert "begin transaction read only" in sql.lower()
                if "'rowset_md5'" in sql:
                    snapshot = {
                        "database_identity": {
                            "current_database": checkpoint.PRODUCTION_DB,
                            "system_identifier": "production-system-id",
                            "postmaster_started_at": "2026-07-10 03:47:11+00",
                            "transaction_read_only": "off",
                        },
                        "counts": COUNTS,
                        "rowset_md5": {table: f"md5-{index}" for index, table in enumerate(COUNTS)},
                    }
                    return subprocess.CompletedProcess(command, 0, json.dumps(snapshot) + "\n", "")
                return subprocess.CompletedProcess(command, 0, json.dumps(COUNTS) + "\n", "")
            assert container == "clone-container-id"
            assert database == self.database
            assert "begin transaction read only" in sql.lower()
            if "jsonb_each_text" in sql:
                related = {
                    "public.claims": [{"id": CLAIM_ID, "body": "fixture claim"}],
                    "public.sources": [{"id": SOURCE_ID, "title": "fixture source"}],
                    "public.claim_evidence": [],
                    "public.claim_edges": [],
                    "public.reasoning_tools": [],
                }
                return subprocess.CompletedProcess(command, 0, json.dumps(related) + "\n", "")
            if "'rowset_md5'" in sql:
                self.target_guard_reads += 1
                suffix = "-mutated" if self.mutate_target and self.target_guard_reads >= 2 else ""
                snapshot = {
                    "database_identity": {
                        "current_database": self.database,
                        "system_identifier": "clone-system-id",
                        "postmaster_started_at": "2026-07-10 15:00:00+00",
                        "transaction_read_only": "on" if self.target_read_only else "off",
                    },
                    "counts": COUNTS,
                    "rowset_md5": {table: f"clone-md5-{index}{suffix}" for index, table in enumerate(COUNTS)},
                }
                return subprocess.CompletedProcess(command, 0, json.dumps(snapshot) + "\n", "")
            return subprocess.CompletedProcess(
                command,
                0,
                json.dumps(_target_checkpoint(self.database, self.status)) + "\n",
                "",
            )
        raise AssertionError(f"unexpected subprocess command: {command}")


def _args(tmp_path: Path, **overrides: Any) -> argparse.Namespace:
    values = {
        "container": "clone-pg",
        "db": "clone_db",
        "prompt_id": "CB-APPROVED",
        "prompt": f"What is the exact state of proposal {PROPOSAL_ID}?",
        "expected_state": "approved",
        "output": tmp_path / "checkpoint.json",
        "proposal_id": PROPOSAL_ID,
        "chat_id": checkpoint.DEFAULT_CHAT_ID,
        "user_id": checkpoint.DEFAULT_USER_ID,
        "user_name": checkpoint.DEFAULT_USER_NAME,
        "run_id": "pytest-run",
        "turn_timeout": 10,
        "copy_model_auth": False,
    }
    values.update(overrides)
    return argparse.Namespace(**values)


def _record_successful_tool_call(temp_profile: Path, proposal_id: str = PROPOSAL_ID) -> None:
    wrapper = (temp_profile / "bin" / "teleo-kb").read_text(encoding="utf-8")
    run_nonce = re.search(r"^RUN_NONCE=(.+)$", wrapper, re.MULTILINE).group(1)
    container = re.search(r"^TARGET_CONTAINER=(.+)$", wrapper, re.MULTILINE).group(1)
    events = [
        {
            "phase": "start",
            "at_utc": "2026-07-10T16:10:00+00:00",
            "invocation_id": "tool-1",
            "run_nonce": run_nonce,
            "container": container,
            "database": "clone_db",
            "database_identity": {
                "current_database": "clone_db",
                "system_identifier": "clone-system-id",
                "transaction_read_only": "on",
            },
            "argv": ["show-proposal", proposal_id],
        },
        {
            "phase": "end",
            "at_utc": "2026-07-10T16:10:01+00:00",
            "invocation_id": "tool-1",
            "run_nonce": run_nonce,
            "container": container,
            "database": "clone_db",
            "returncode": 0,
        },
    ]
    (temp_profile / "checkpoint-tool-calls.jsonl").write_text(
        "".join(json.dumps(event) + "\n" for event in events),
        encoding="utf-8",
    )


def _successful_gateway_result() -> dict[str, Any]:
    return {
        "runner_class": "gateway.run.GatewayRunner",
        "session_key": "telegram:-5146042086:9070919",
        "authorized": True,
        "handler_invoked": True,
        "posted_to_telegram": False,
        "model_free_fallback_used": False,
        "reply": (
            f"Proposal {PROPOSAL_ID} is approved and applied_at is NULL.\n"
            f'KB_STATE: {{"proposal_id":"{PROPOSAL_ID}","status":"approved","applied":false}}'
        ),
        "runner_cleanup": {"attempted": False, "ok": True},
        "tool_surface": {
            "allowed_tools": ["skills_list", "skill_view", "terminal"],
            "actual_registry_tools": ["skills_list", "skill_view", "terminal"],
            "send_message_tool_enabled": False,
            "gateway_adapters_verified_mapping": True,
            "gateway_adapter_count": 0,
            "terminal_restricted_to_clone_wrapper": True,
            "terminal_subprocess_inherits_provider_credentials": False,
        },
        "transcript_tool_trace": {
            "events": [
                {"phase": "call", "tool_call_id": "terminal-1", "tool_name": "terminal"},
                {
                    "phase": "result",
                    "tool_call_id": "terminal-1",
                    "content": '{"output":"ok","exit_code":0,"error":null}',
                },
            ],
            "event_count": 2,
        },
        "child_process": {
            "alive_after_readback": False,
            "process_group_alive_after_readback": False,
            "result_transport": "private_temp_file",
            "timed_out": False,
            "exitcode": 0,
            "readiness_verified": True,
            "termination": {"attempted": False},
        },
    }


def test_checkpoint_forces_clone_target_and_returns_bound_proof(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
    live_profile: Path,
) -> None:
    fake_subprocess = FakeSubprocess()
    observed: dict[str, Any] = {}

    async def fake_gateway(
        args: argparse.Namespace,
        temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {}
        observed["temp_root"] = temp_profile.parent
        observed["wrapper"] = (temp_profile / "bin" / "teleo-kb").read_text(encoding="utf-8")
        observed["skill"] = (temp_profile / "skills" / "teleo-kb-bridge" / "SKILL.md").read_text(encoding="utf-8")
        observed["copied_paths"] = [str(path.relative_to(temp_profile)) for path in temp_profile.rglob("*")]
        _record_successful_tool_call(temp_profile)
        return _successful_gateway_result()

    monkeypatch.setattr(checkpoint.subprocess, "run", fake_subprocess)
    monkeypatch.setattr(checkpoint, "invoke_gateway_subprocess", fake_gateway)

    args = _args(tmp_path)
    report = asyncio.run(checkpoint.run_checkpoint(args))

    assert report["status"] == "pass"
    assert report["gateway"]["reply"].startswith(f"Proposal {PROPOSAL_ID}")
    assert report["proposal_checkpoint"]["selected_proposal"]["id"] == PROPOSAL_ID
    assert report["proposal_checkpoint"]["state_semantics"]["all"] is True
    assert report["proposal_checkpoint"]["related_canonical_rows"]["public.claims"][0]["id"] == CLAIM_ID
    assert report["tool_proof"]["all_bound_to_supplied_target"] is True
    assert report["production_invariants"]["counts_unchanged"] is True
    assert report["production_invariants"]["service_unchanged"] is True
    assert report["cleanup"]["absence_verified_independently"] is True
    assert not os.path.lexists(observed["temp_root"])
    assert observed["temp_root"].name.startswith("leo-clone-checkpoint-pytest-run-CB-APPROVED-")

    wrapper = observed["wrapper"]
    assert wrapper.startswith("#!/bin/bash\n")
    assert f"DOCKER={checkpoint.SYSTEM_DOCKER}" in wrapper
    assert f"export PATH={checkpoint.SYSTEM_EXEC_PATH}" in wrapper
    assert "/usr/bin/env bash" not in wrapper
    assert "$(python3 " not in wrapper
    assert "$(docker " not in wrapper
    assert "TARGET_CONTAINER=clone-container-id" in wrapper
    assert "TARGET_DATABASE=clone_db" in wrapper
    assert '--local --container "$TARGET_CONTAINER" --db "$TARGET_DATABASE"' in wrapper
    assert checkpoint.PRODUCTION_CONTAINER not in wrapper
    assert "cloudsql" not in wrapper.lower()
    assert observed["skill"].startswith("---\nname: teleo-kb-bridge\n")
    assert observed["skill"].index("Disposable Checkpoint Binding") > observed["skill"].index("\n---\n")
    assert str(observed["temp_root"] / "profile" / "bin" / "teleo-kb") in observed["skill"]
    assert "start a terminal call directly with `teleo-kb`" in observed["skill"]
    assert "/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb" not in observed["skill"]

    copied = "\n".join(observed["copied_paths"])
    for forbidden in (".env", "auth.json", "secrets", "sessions", "state", "backups", "memory_backups", ".bak"):
        assert forbidden not in copied
    assert report["temporary_profile_copy_audit"]["passes"] is True
    assert report["temporary_profile_copy_audit"]["secret_contents_read_or_recorded"] is False
    retained_text = args.output.read_text(encoding="utf-8")
    assert json.loads(retained_text)["status"] == "pass"
    assert report["proposal_checkpoint"]["selected_proposal"]["payload_sha256"]
    assert "fixture claim" not in retained_text
    assert "fixture-secret" not in retained_text
    assert "do-not-copy" not in retained_text

    target_execs = [
        call["command"]
        for call in fake_subprocess.calls
        if call["command"][:3] == ["docker", "exec", "-i"] and call["command"][3] != checkpoint.PRODUCTION_CONTAINER
    ]
    assert target_execs
    assert all(
        command[3] == "clone-container-id" and command[command.index("-d") + 1] == "clone_db"
        for command in target_execs
    )


def test_checkpoint_fails_when_target_row_content_changes(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
    live_profile: Path,
) -> None:
    fake_subprocess = FakeSubprocess(mutate_target=True)

    async def fake_gateway(
        _args: argparse.Namespace,
        temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {}
        _record_successful_tool_call(temp_profile)
        return _successful_gateway_result()

    monkeypatch.setattr(checkpoint.subprocess, "run", fake_subprocess)
    monkeypatch.setattr(checkpoint, "invoke_gateway_subprocess", fake_gateway)

    report = asyncio.run(checkpoint.run_checkpoint(_args(tmp_path)))

    assert report["status"] == "fail"
    assert report["checks"]["target_row_content_unchanged"] is False
    assert report["checks"]["production_guard_snapshot_unchanged"] is True


def test_checkpoint_fails_when_tool_receipt_reads_a_different_proposal(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
    live_profile: Path,
) -> None:
    fake_subprocess = FakeSubprocess()

    async def fake_gateway(
        _args: argparse.Namespace,
        temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {}
        _record_successful_tool_call(temp_profile, "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa")
        return _successful_gateway_result()

    monkeypatch.setattr(checkpoint.subprocess, "run", fake_subprocess)
    monkeypatch.setattr(checkpoint, "invoke_gateway_subprocess", fake_gateway)

    report = asyncio.run(checkpoint.run_checkpoint(_args(tmp_path)))

    assert report["status"] == "fail"
    assert report["checks"]["tool_receipt_read_exact_selected_proposal"] is False


def test_checkpoint_fails_when_terminal_result_is_missing(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
    live_profile: Path,
) -> None:
    fake_subprocess = FakeSubprocess()

    async def fake_gateway(
        _args: argparse.Namespace,
        temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {}
        _record_successful_tool_call(temp_profile)
        result = _successful_gateway_result()
        result["transcript_tool_trace"]["events"] = [
            {"phase": "call", "tool_call_id": "terminal-1", "tool_name": "terminal"}
        ]
        return result

    monkeypatch.setattr(checkpoint.subprocess, "run", fake_subprocess)
    monkeypatch.setattr(checkpoint, "invoke_gateway_subprocess", fake_gateway)

    report = asyncio.run(checkpoint.run_checkpoint(_args(tmp_path)))

    assert report["status"] == "fail"
    assert report["checks"]["terminal_call_results_complete_and_receipted"] is False


def test_read_only_restore_obligation_survives_enable_verification_failure(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
    live_profile: Path,
) -> None:
    fake_subprocess = FakeSubprocess(fail_read_only_verification_once=True)
    monkeypatch.setattr(checkpoint.subprocess, "run", fake_subprocess)

    report = asyncio.run(checkpoint.run_checkpoint(_args(tmp_path)))

    assert report["status"] == "fail"
    assert fake_subprocess.read_only_verification_failed is True
    assert fake_subprocess.target_read_only is False
    assert report["target"]["read_only_role_restore_obligation_installed"] is True
    assert report["target"]["read_only_role_restored"] is True
    assert any("read-only verification" in item["message"] for item in report["errors"])


def test_production_container_is_rejected_without_gateway_fallback(tmp_path: Path) -> None:
    args = _args(tmp_path, container=checkpoint.PRODUCTION_CONTAINER)

    with pytest.raises(checkpoint.CheckpointError, match="must not target the production"):
        checkpoint.validate_args(args)


def test_disposable_target_identity_requires_label_network_and_storage_isolation() -> None:
    production = {
        "id": "production",
        "labels": {},
        "network_mode": "bridge",
        "ports": {},
        "mount_sources": ["production-volume"],
    }
    target = {
        "id": "clone",
        "labels": {checkpoint.DISPOSABLE_LABEL_KEY: checkpoint.DISPOSABLE_LABEL_VALUE},
        "network_mode": "none",
        "ports": {},
        "mount_sources": ["clone-volume"],
    }

    assert all(checkpoint.validate_disposable_target_identity(target, production).values())
    with pytest.raises(checkpoint.CheckpointError, match="proven disposable"):
        checkpoint.validate_disposable_target_identity(target | {"labels": {}}, production)
    with pytest.raises(checkpoint.CheckpointError, match="proven disposable"):
        checkpoint.validate_disposable_target_identity(target | {"mount_sources": ["production-volume"]}, production)


def test_output_inside_live_profile_is_rejected(tmp_path: Path, live_profile: Path) -> None:
    args = _args(tmp_path, output=live_profile / "checkpoint.json")

    with pytest.raises(checkpoint.CheckpointError, match="outside the live leoclean profile"):
        checkpoint.validate_args(args)


def test_output_parent_must_be_private_and_owned(tmp_path: Path) -> None:
    shared = tmp_path / "shared"
    shared.mkdir(mode=0o777)
    shared.chmod(0o777)
    args = _args(tmp_path, output=shared / "checkpoint.json")

    with pytest.raises(checkpoint.CheckpointError, match="private directory"):
        checkpoint.validate_args(args)


def test_rejected_output_path_is_never_overwritten_by_run_checkpoint(
    tmp_path: Path,
    live_profile: Path,
) -> None:
    protected = live_profile / "auth.json"
    before = protected.read_bytes()
    args = _args(tmp_path, output=protected)

    with pytest.raises(checkpoint.CheckpointError, match="outside the live leoclean profile"):
        asyncio.run(checkpoint.run_checkpoint(args))

    assert protected.read_bytes() == before


def test_handler_exception_still_removes_and_independently_verifies_temp_root(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
    live_profile: Path,
) -> None:
    fake_subprocess = FakeSubprocess()
    observed: dict[str, Path] = {}

    async def failing_gateway(
        _args: argparse.Namespace,
        temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {}
        observed["temp_root"] = temp_profile.parent
        (temp_profile / "transient-session.json").write_text("temporary", encoding="utf-8")
        raise RuntimeError("injected handler failure")

    monkeypatch.setattr(checkpoint.subprocess, "run", fake_subprocess)
    monkeypatch.setattr(checkpoint, "invoke_gateway_subprocess", failing_gateway)

    args = _args(tmp_path)
    report = asyncio.run(checkpoint.run_checkpoint(args))

    assert report["status"] == "fail"
    assert any(item["message"] == "injected handler failure" for item in report["errors"])
    assert report["cleanup"]["temp_profile_removed"] is True
    assert report["cleanup"]["temp_session_removed_with_profile"] is True
    assert report["cleanup"]["absence_verified_independently"] is True
    assert report["cleanup"]["active_temp_root_registry_clear"] is True
    assert not os.path.lexists(observed["temp_root"])
    assert observed["temp_root"] not in checkpoint._ACTIVE_TEMP_ROOTS
    assert json.loads(args.output.read_text(encoding="utf-8"))["cleanup"]["absence_verified_independently"] is True


def test_termination_signal_cleans_root_before_interruption_propagates(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
    live_profile: Path,
) -> None:
    fake_subprocess = FakeSubprocess()
    observed: dict[str, Path] = {}

    async def interrupted_gateway(
        _args: argparse.Namespace,
        temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {}
        observed["temp_root"] = temp_profile.parent
        (temp_profile / "transient-session.db").write_text("temporary", encoding="utf-8")
        checkpoint._termination_handler(signal.SIGTERM, None)
        raise AssertionError("termination handler must raise")

    monkeypatch.setattr(checkpoint.subprocess, "run", fake_subprocess)
    monkeypatch.setattr(checkpoint, "invoke_gateway_subprocess", interrupted_gateway)

    args = _args(tmp_path)
    with pytest.raises(checkpoint.TerminationRequested) as raised:
        asyncio.run(checkpoint.run_checkpoint(args))

    assert raised.value.signum == signal.SIGTERM
    assert not os.path.lexists(observed["temp_root"])
    assert observed["temp_root"] not in checkpoint._ACTIVE_TEMP_ROOTS
    retained = json.loads(args.output.read_text(encoding="utf-8"))
    assert retained["cleanup"]["termination_signal"] == signal.SIGTERM
    assert retained["cleanup"]["absence_verified_independently"] is True
    assert retained["cleanup"]["active_temp_root_registry_clear"] is True


def test_temp_copy_excludes_sensitive_and_state_artifacts_without_readback(live_profile: Path) -> None:
    temp_profile, audit = checkpoint.copy_profile(
        run_id="copy-test",
        prompt_id="CB-COPY",
        live_profile=live_profile,
    )
    root = temp_profile.parent
    try:
        owner_marker = root / ".teleo-temp-owner"
        assert owner_marker.read_text(encoding="utf-8") == "copy-test\nCB-COPY\n"
        assert owner_marker.stat().st_mode & 0o777 == 0o600
        assert audit["passes"] is True
        assert audit["secret_contents_read_or_recorded"] is False
        assert audit["omitted_counts_by_category"]
        assert not (temp_profile / ".env").exists()
        assert not (temp_profile / "auth.json").exists()
        assert not (temp_profile / "secrets").exists()
        assert not (temp_profile / "sessions").exists()
        assert not (temp_profile / "state").exists()
        assert not any(path.is_symlink() for path in temp_profile.rglob("*"))
    finally:
        assert checkpoint.remove_tree(root) is True
    assert checkpoint.temp_path_absent(root) is True


def test_temp_owner_marker_failure_removes_registered_root(
    live_profile: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    original_write_text = Path.write_text

    def fail_owner_marker(path: Path, *args: Any, **kwargs: Any) -> int:
        if path.name == ".teleo-temp-owner":
            raise OSError("marker write failed")
        return original_write_text(path, *args, **kwargs)

    monkeypatch.setattr(Path, "write_text", fail_owner_marker)

    with pytest.raises(OSError, match="marker write failed"):
        checkpoint.copy_profile(run_id="copy-fail", prompt_id="CB-COPY", live_profile=live_profile)

    assert not list((live_profile.parent / "temp-roots").iterdir())
    assert not checkpoint._ACTIVE_TEMP_ROOTS


def test_patch_temp_bridge_rejects_preexisting_tool_log(live_profile: Path) -> None:
    temp_profile, _audit = checkpoint.copy_profile(
        run_id="stale-log-test",
        prompt_id="CB-STALE-LOG",
        live_profile=live_profile,
    )
    root = temp_profile.parent
    try:
        (temp_profile / "checkpoint-tool-calls.jsonl").write_text("stale\n", encoding="utf-8")
        with pytest.raises(checkpoint.CheckpointError, match="must not pre-exist"):
            checkpoint.patch_temp_bridge(temp_profile, "clone-container-id", "clone_db")
    finally:
        assert checkpoint.remove_tree(root) is True


def test_explicit_model_auth_copy_is_minimal_private_and_removed(live_profile: Path) -> None:
    temp_profile, _audit = checkpoint.copy_profile(
        run_id="auth-copy-test",
        prompt_id="CB-AUTH",
        live_profile=live_profile,
    )
    root = temp_profile.parent
    try:
        binding = checkpoint.copy_ephemeral_model_auth(
            temp_profile,
            live_profile=live_profile,
        )
        copied = temp_profile / "auth.json"
        assert copied.read_text(encoding="utf-8") == '{"token":"do-not-copy"}\n'
        assert copied.stat().st_mode & 0o777 == 0o600
        assert binding["mode"] == "ephemeral_file_copy"
        assert binding["source_contents_recorded"] is False
        assert binding["source_fingerprint_recorded"] is False
    finally:
        assert checkpoint.remove_tree(root) is True
    assert checkpoint.temp_path_absent(root) is True


def test_provider_environment_binding_is_scoped_to_configured_provider(tmp_path: Path) -> None:
    profile = tmp_path / "profile"
    _write(profile / "config.yaml", "model:\n  provider: openrouter\n")
    _write(
        profile / "auth.json",
        json.dumps(
            {
                "active_provider": "openai-codex",
                "credential_pool": {
                    "openrouter": [
                        {
                            "source": "env:OPENROUTER_API_KEY",
                            "access_token": "private-openrouter-value",
                            "priority": 0,
                        }
                    ],
                    "copilot": [
                        {
                            "source": "env:GITHUB_TOKEN",
                            "access_token": "private-github-value",
                            "priority": 0,
                        }
                    ],
                },
            }
        ),
    )

    environment, audit = checkpoint.load_ephemeral_provider_environment(profile)

    assert environment == {"OPENROUTER_API_KEY": "private-openrouter-value"}
    assert audit["configured_provider"] == "openrouter"
    assert audit["environment_names"] == ["OPENROUTER_API_KEY"]
    assert audit["bound_credential_count"] == 1
    assert "private-openrouter-value" not in json.dumps(audit)
    assert "private-github-value" not in json.dumps(audit)


def test_report_redaction_does_not_emit_token_shaped_errors() -> None:
    value = checkpoint.redact_value(
        {
            "error": "token=123456789:abcdefghijklmnopqrstuvwxyzABCDE password=hunter2",
            "safe": "proposal state",
        }
    )

    assert value["error"] == "token=[REDACTED] password=[REDACTED]"
    assert value["safe"] == "proposal state"

    structured = checkpoint.redact_value(
        {
            "access_token": "structured-test-token-value",
            "nested": {"refresh_token": "eyJabcdefghijklmnopqrstuvwxyz.abcdefghijk.lmnopqrstuv"},
            "token": "opaque-value",
            "private_key": "opaque-private-key",
            "api_key_present": True,
        }
    )
    assert structured["access_token"] == "[REDACTED]"
    assert structured["nested"]["refresh_token"] == "[REDACTED]"
    assert structured["token"] == "[REDACTED]"
    assert structured["private_key"] == "[REDACTED]"
    assert structured["api_key_present"] is True


def test_write_report_forces_private_mode(tmp_path: Path) -> None:
    path = tmp_path / "receipt.json"

    checkpoint.write_report(path, {"status": "pass", "access_token": "private"})

    assert path.stat().st_mode & 0o777 == 0o600
    assert json.loads(path.read_text(encoding="utf-8"))["access_token"] == "[REDACTED]"


def test_write_report_replaces_destination_symlink_without_touching_target(tmp_path: Path) -> None:
    victim = tmp_path / "victim.txt"
    victim.write_text("unchanged", encoding="utf-8")
    path = tmp_path / "receipt.json"
    path.symlink_to(victim)

    checkpoint.write_report(path, {"status": "pass"})

    assert victim.read_text(encoding="utf-8") == "unchanged"
    assert not path.is_symlink()
    assert json.loads(path.read_text(encoding="utf-8"))["status"] == "pass"


def test_transcript_tool_trace_keeps_only_bounded_redacted_tool_events() -> None:
    trace = checkpoint.transcript_tool_trace(
        [
            {"role": "user", "content": "do not retain me"},
            {
                "role": "assistant",
                "content": "reasoning not retained",
                "tool_calls": [
                    {
                        "id": "call-1",
                        "function": {
                            "name": "terminal",
                            "arguments": '{"command":"teleo-kb search helmer"}',
                        },
                    }
                ],
            },
            {
                "role": "tool",
                "tool_call_id": "call-1",
                "tool_name": "terminal",
                "content": "token=123456789:abcdefghijklmnopqrstuvwxyzABCDE" + ("x" * 50),
            },
            {"role": "assistant", "content": "final answer not retained"},
        ],
        content_limit=32,
    )

    assert trace[0] == {
        "phase": "call",
        "tool_call_id": "call-1",
        "tool_name": "terminal",
        "arguments": '{"command":"teleo-kb search helmer"}',
        "arguments_truncated": False,
    }
    assert trace[1]["phase"] == "result"
    assert trace[1]["content"] == "token=[REDACTED]"
    assert trace[1]["content_truncated"] is True
    assert len(trace) == 2


def test_terminal_attempt_summary_counts_rejections_and_nonzero_results() -> None:
    summary = checkpoint.transcript_terminal_attempt_summary(
        [
            {"phase": "call", "tool_call_id": "accepted", "tool_name": "terminal"},
            {"phase": "result", "tool_call_id": "accepted", "content": '{"exit_code": 0}'},
            {"phase": "call", "tool_call_id": "rejected", "tool_name": "terminal"},
            {"phase": "result", "tool_call_id": "rejected", "content": '{"exit_code": 126}'},
            {"phase": "call", "tool_call_id": "failed", "tool_name": "terminal"},
            {"phase": "result", "tool_call_id": "failed", "content": '{"exit_code": 2}'},
            {"phase": "call", "tool_call_id": "truncated", "tool_name": "terminal"},
            {"phase": "result", "tool_call_id": "truncated", "content": '{"output":"large'},
        ]
    )

    assert summary["call_count"] == 4
    assert summary["rejected_call_ids"] == ["rejected"]
    assert summary["nonzero_call_ids"] == ["failed", "rejected"]
    assert summary["result_code_unknown_call_count"] == 1


@pytest.mark.parametrize(
    "argv",
    [
        ["show-proposal", "--help"],
        ["show-proposal", PROPOSAL_ID[:8]],
        ["search", "helmer", "--limit", "101"],
        ["search", "helmer", "--container", checkpoint.PRODUCTION_CONTAINER],
        ["propose-edge", PROPOSAL_ID, "relates", CLAIM_ID],
    ],
)
def test_read_only_bridge_argument_parser_rejects_nonquery_or_ambiguous_forms(argv: list[str]) -> None:
    with pytest.raises(checkpoint.CheckpointError):
        checkpoint.validate_read_only_bridge_argv(argv)


def test_read_only_bridge_argument_parser_accepts_bounded_query() -> None:
    checkpoint.validate_read_only_bridge_argv(["search-proposals", "7 powers", "--status", "all", "--limit", "20"])


def test_restricted_terminal_executes_only_read_only_clone_wrapper(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    wrapper = tmp_path / "bin" / "teleo-kb"
    _write(
        wrapper,
        '#!/usr/bin/env bash\nprintf \'%s|%s\' "$1" "${OPENROUTER_API_KEY-unset}"\n',
    )
    wrapper.chmod(0o700)
    monkeypatch.setenv("OPENROUTER_API_KEY", "must-not-reach-terminal-child")

    allowed = json.loads(
        checkpoint.restricted_bridge_terminal_handler(
            wrapper,
            tmp_path,
            {"command": f"{wrapper} search Helmer"},
        )
    )
    harmless_redirect = json.loads(
        checkpoint.restricted_bridge_terminal_handler(
            wrapper,
            tmp_path,
            {"command": f"{wrapper} search Helmer 2>&1"},
        )
    )
    bare_command = json.loads(
        checkpoint.restricted_bridge_terminal_handler(
            wrapper,
            tmp_path,
            {"command": "teleo-kb search Helmer"},
        )
    )
    wrong_binary = json.loads(
        checkpoint.restricted_bridge_terminal_handler(
            wrapper,
            tmp_path,
            {"command": "docker ps"},
        )
    )
    write_verb = json.loads(
        checkpoint.restricted_bridge_terminal_handler(
            wrapper,
            tmp_path,
            {"command": f"{wrapper} propose-claim anything"},
        )
    )
    background = json.loads(
        checkpoint.restricted_bridge_terminal_handler(
            wrapper,
            tmp_path,
            {"command": f"{wrapper} search Helmer", "background": True},
        )
    )

    assert allowed == {"output": "search|unset", "exit_code": 0, "error": None}
    assert harmless_redirect == allowed
    assert bare_command == allowed
    assert wrong_binary["exit_code"] == 126
    assert write_verb["exit_code"] == 126
    assert background["exit_code"] == 126


def test_gateway_environment_authorizes_only_the_exact_synthetic_source(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    monkeypatch.setenv("TELEGRAM_ALLOWED_CHATS", "live-chat")
    monkeypatch.setenv("TELEGRAM_ALLOWED_USERS", "live-user")
    monkeypatch.setenv("TELEGRAM_ALLOW_ALL_USERS", "true")
    monkeypatch.setenv("GATEWAY_ALLOW_ALL_USERS", "true")

    with checkpoint.gateway_environment(
        tmp_path,
        chat_id="clone-chat",
        user_id="clone-user",
        provider_environment={"OPENROUTER_API_KEY": "temporary-provider-key"},
    ):
        assert os.environ["TELEGRAM_ALLOWED_CHATS"] == "clone-chat"
        assert os.environ["TELEGRAM_ALLOWED_USERS"] == "clone-user"
        assert os.environ["TELEGRAM_ALLOW_ALL_USERS"] == "false"
        assert os.environ["GATEWAY_ALLOW_ALL_USERS"] == "false"
        assert os.environ["OPENROUTER_API_KEY"] == "temporary-provider-key"

    assert os.environ["TELEGRAM_ALLOWED_CHATS"] == "live-chat"
    assert os.environ["TELEGRAM_ALLOWED_USERS"] == "live-user"
    assert os.environ["TELEGRAM_ALLOW_ALL_USERS"] == "true"
    assert os.environ["GATEWAY_ALLOW_ALL_USERS"] == "true"
    assert "OPENROUTER_API_KEY" not in os.environ


def test_gateway_subprocess_timeout_kills_child_before_return(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    if "fork" not in checkpoint.multiprocessing.get_all_start_methods():
        pytest.skip("fork is required by the live VPS checkpoint")

    descendant_pid_path = tmp_path / "descendant.pid"

    async def hanging_gateway(
        _args: argparse.Namespace,
        _temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {"OPENROUTER_API_KEY": "temporary"}
        descendant = subprocess.Popen(["sleep", "60"])
        descendant_pid_path.write_text(str(descendant.pid), encoding="utf-8")
        await asyncio.sleep(60)
        raise AssertionError("the parent must terminate this child")

    monkeypatch.setattr(checkpoint, "invoke_gateway", hanging_gateway)
    profile = tmp_path / "profile"
    profile.mkdir()
    args = _args(tmp_path, turn_timeout=1.0)

    result = asyncio.run(
        checkpoint.invoke_gateway_subprocess(
            args,
            profile,
            provider_environment={"OPENROUTER_API_KEY": "temporary"},
        )
    )

    assert result["handler_error"]["type"] == "TimeoutError"
    assert result["child_process"]["timed_out"] is True
    assert result["child_process"]["alive_after_readback"] is False
    assert result["child_process"]["process_group_alive_after_readback"] is False
    assert result["child_process"]["readiness_verified"] is True
    assert result["child_process"]["termination"]["alive_after_cleanup"] is False
    assert result["child_process"]["termination"]["process_group_alive_after_cleanup"] is False
    assert not checkpoint._ACTIVE_GATEWAY_CHILDREN
    descendant_pid = int(descendant_pid_path.read_text(encoding="utf-8"))
    deadline = time.monotonic() + 2
    while time.monotonic() < deadline:
        try:
            os.kill(descendant_pid, 0)
        except ProcessLookupError:
            break
        time.sleep(0.05)
    else:
        pytest.fail(f"descendant process {descendant_pid} survived checkpoint timeout")


def test_gateway_subprocess_timeout_cannot_hide_behind_early_result_file(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    if "fork" not in checkpoint.multiprocessing.get_all_start_methods():
        pytest.skip("fork is required by the live VPS checkpoint")

    def early_result_child(
        _args: argparse.Namespace,
        _temp_profile: Path,
        _provider_environment: dict[str, str],
        result_path: Path,
        readiness_path: Path,
    ) -> None:
        os.setsid()
        checkpoint.write_report(
            readiness_path,
            {"pid": os.getpid(), "process_group_id": os.getpgrp(), "ready_at_utc": checkpoint.utc_now()},
        )
        checkpoint.write_report(
            result_path,
            {
                "authorized": True,
                "handler_invoked": True,
                "posted_to_telegram": False,
                "model_free_fallback_used": False,
                "reply": "premature",
            },
        )
        time.sleep(60)

    monkeypatch.setattr(checkpoint, "_gateway_child_entry", early_result_child)
    profile = tmp_path / "early-result-profile"
    profile.mkdir()
    result = asyncio.run(checkpoint.invoke_gateway_subprocess(_args(tmp_path, turn_timeout=0.2), profile))

    assert result["authorized"] is True
    assert result["child_process"]["timed_out"] is True
    assert result["child_process"]["exitcode"] != 0
    assert result["child_process"]["termination"]["attempted"] is True
    assert result["child_process"]["process_group_alive_after_readback"] is False


def test_gateway_subprocess_returns_large_result_without_pipe_deadlock(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    if "fork" not in checkpoint.multiprocessing.get_all_start_methods():
        pytest.skip("fork is required by the live VPS checkpoint")

    async def large_gateway(
        _args: argparse.Namespace,
        _temp_profile: Path,
        *,
        provider_environment: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        assert provider_environment == {}
        return {
            "authorized": True,
            "handler_invoked": True,
            "posted_to_telegram": False,
            "model_free_fallback_used": False,
            "reply": "x" * 1_000_000,
        }

    monkeypatch.setattr(checkpoint, "invoke_gateway", large_gateway)
    profile = tmp_path / "large-profile"
    profile.mkdir()
    args = _args(tmp_path, turn_timeout=30)

    result = asyncio.run(checkpoint.invoke_gateway_subprocess(args, profile))

    assert "reply" in result, result
    assert len(result["reply"]) == 1_000_000
    assert result["child_process"]["result_transport"] == "private_temp_file"
    assert result["child_process"]["timed_out"] is False
    assert result["child_process"]["exitcode"] == 0
    assert result["child_process"]["readiness_verified"] is True


@pytest.mark.parametrize("state", ["pending_review", "approved", "applied"])
def test_checkpoint_state_semantics_cover_each_composable_lifecycle_state(state: str) -> None:
    proposal = _proposal(state)

    assert checkpoint._state_semantics(proposal, state)["all"] is True


def test_reply_state_receipt_rejects_contradictory_state() -> None:
    receipt = checkpoint.parse_reply_state_receipt(
        f'KB_STATE: {{"proposal_id":"{PROPOSAL_ID}","status":"pending_review","applied":false}}'
    )

    assert receipt["valid"] is True
    assert checkpoint.reply_state_receipt_matches(receipt, _proposal("approved")) is False


def test_selector_resolves_one_unique_proposal_prefix_from_m3taversal_style_reply() -> None:
    other = _proposal("approved") | {"id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"}
    before = {"proposals": [_proposal("approved"), other]}
    after = {"proposals": [_proposal("approved"), other]}

    selection = checkpoint.select_expected_proposal(
        before=before,
        after=after,
        expected_state="approved",
        prompt="Is Helmer actually in Leo now?",
        reply=f"Proposal `{PROPOSAL_ID[:8]}` is approved but not applied.",
        explicit_proposal_id=None,
    )

    assert selection["selection_method"] == "unique_prompt_or_reply_uuid_prefix"
    assert selection["selected_proposal"]["id"] == PROPOSAL_ID
    assert selection["selected_exactly_one"] is True
