1174 lines
45 KiB
Python
1174 lines
45 KiB
Python
"""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:
|
|
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_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_cory_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
|