teleo-infrastructure/tests/test_run_leo_clone_composition_checkpoint.py

738 lines
30 KiB
Python

from __future__ import annotations
import argparse
import asyncio
import copy
import json
import os
import subprocess
import sys
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_composition_checkpoint as composition # noqa: E402
RUN_MARKER = "composition-unit-20260711"
CONVERSATION_MARKER = "composition-memory-unit-20260711"
AGENT_ID = "11111111-1111-4111-8111-111111111111"
def _packet(fixture: dict[str, Any]) -> dict[str, Any]:
return {
"claim_candidates": [
{
"claim_key": "guarded_apply_required",
"text": "Approval leaves canonical rows unchanged until guarded apply succeeds.",
"type": "structural",
"confidence": 0.98,
"evidence": [{"source_key": "operating_document", "role": "grounds"}],
"edges": [
{
"edge_type": "contradicts",
"target": "approval_is_canonical",
}
],
},
{
"claim_key": "approval_is_canonical",
"text": "Reviewer approval immediately makes a Leo proposal canonical.",
"type": "empirical",
"confidence": 0.4,
"evidence": [{"source_key": "contradictory_post", "role": "grounds"}],
},
],
"source_candidates": [
{
"source_key": "operating_document",
"source_type": "article",
"storage_path": fixture["document"]["storage_path"],
"url": None,
"title": fixture["document"]["title"],
"source_quality": "internal_operating_document",
"key_excerpt": fixture["document"]["text"],
"content_sha256": fixture["document"]["content_sha256"],
},
{
"source_key": "contradictory_post",
"source_type": "post",
"storage_path": None,
"url": fixture["post"]["url"],
"title": fixture["post"]["title"],
"source_quality": "unverified_social_post",
"key_excerpt": fixture["post"]["text"],
"content_sha256": fixture["post"]["content_sha256"],
},
],
"dedupe_conflict_assessment": {
"database_search_query": fixture["project"],
"potential_existing_claim_ids": [],
"conflicts": [
{
"from_claim_key": "guarded_apply_required",
"to_claim_key": "approval_is_canonical",
"relationship": "contradicts",
}
],
},
}
def test_fixture_and_prompts_keep_source_bytes_and_memory_boundaries_explicit() -> None:
fixture = composition.build_source_fixture(RUN_MARKER)
prompts = composition.build_prompts(fixture, CONVERSATION_MARKER)
assert fixture["project"] in fixture["document"]["text"]
assert fixture["project"] in fixture["post"]["text"]
assert fixture["document"]["content_sha256"] in prompts["extract"]
assert fixture["post"]["content_sha256"] in prompts["extract"]
assert CONVERSATION_MARKER in prompts["extract"]
assert CONVERSATION_MARKER not in prompts["reason"]
assert fixture["document"]["text"] not in prompts["reason"]
assert fixture["post"]["text"] not in prompts["reason"]
child = composition.normalized_stage.prepare_normalized_child(
composition.build_parent_packet(_packet(fixture), fixture, RUN_MARKER, AGENT_ID)
)
assert child["id"] not in prompts["reason"]
assert all(
row["id"] not in prompts["reason"]
for collection in ("claims", "sources")
for row in child["payload"]["apply_payload"][collection]
)
def test_valid_packet_is_hash_bound_evidenced_and_conflict_aware() -> None:
fixture = composition.build_source_fixture(RUN_MARKER)
validation = composition.validate_composition_packet(_packet(fixture), fixture)
assert validation["claim_count"] == 2
assert validation["source_count"] == 2
assert validation["evidence_source_keys"] == ["contradictory_post", "operating_document"]
assert validation["conflict_pairs"] == [["guarded_apply_required", "approval_is_canonical"]]
@pytest.mark.parametrize("mutation", ["hash", "excerpt", "evidence", "conflict"])
def test_packet_validation_fails_closed_on_provenance_or_reasoning_loss(mutation: str) -> None:
fixture = composition.build_source_fixture(RUN_MARKER)
packet = _packet(fixture)
if mutation == "hash":
packet["source_candidates"][0]["content_sha256"] = "0" * 64
elif mutation == "excerpt":
packet["source_candidates"][0]["key_excerpt"] = "hallucinated excerpt"
elif mutation == "evidence":
packet["claim_candidates"][0]["evidence"] = []
else:
packet["claim_candidates"][0]["edges"] = []
with pytest.raises(composition.bound.CheckpointError):
composition.validate_composition_packet(packet, fixture)
def test_packet_normalizes_to_deterministic_hash_bound_claim_graph() -> None:
fixture = composition.build_source_fixture(RUN_MARKER)
packet = _packet(fixture)
parent = composition.build_parent_packet(packet, fixture, RUN_MARKER, AGENT_ID)
child = composition.normalized_stage.prepare_normalized_child(parent)
payload = child["payload"]["apply_payload"]
assert parent["id"] == composition._stable_uuid(RUN_MARKER, "rich-source-packet")
assert len(payload["claims"]) == 2
assert len(payload["sources"]) == 4
assert len(payload["evidence"]) == 4
assert len(payload["edges"]) == 1
assert payload["edges"][0]["edge_type"] == "contradicts"
assert {fixture["document"]["content_sha256"], fixture["post"]["content_sha256"]} <= {
row["hash"] for row in payload["sources"]
}
assert composition.expected_table_deltas(child) == {
"public.claims": 2,
"public.sources": 4,
"public.claim_evidence": 4,
"public.claim_edges": 1,
"public.reasoning_tools": 0,
"kb_stage.kb_proposals": 1,
composition.lifecycle.APPROVAL_TABLE: 1,
}
def test_final_state_receipt_must_match_every_generated_row_id() -> None:
fixture = composition.build_source_fixture(RUN_MARKER)
child = composition.normalized_stage.prepare_normalized_child(
composition.build_parent_packet(_packet(fixture), fixture, RUN_MARKER, AGENT_ID)
)
payload = child["payload"]["apply_payload"]
edge = payload["edges"][0]
state = {
"phase": "final",
"conversation_marker": CONVERSATION_MARKER,
"proposal_id": child["id"],
"status": "applied",
"claim_ids": [row["id"] for row in payload["claims"]],
"source_ids": [row["id"] for row in payload["sources"]],
"conflict_edge": {
"from_claim": edge["from_claim"],
"to_claim": edge["to_claim"],
"edge_type": edge["edge_type"],
},
}
assert composition._state_matches(state, conversation_marker=CONVERSATION_MARKER, child=child) is True
marker_alias = copy.deepcopy(state)
marker_alias["marker"] = marker_alias.pop("conversation_marker")
assert composition._state_matches(marker_alias, conversation_marker=CONVERSATION_MARKER, child=child) is True
wrong = copy.deepcopy(state)
wrong["source_ids"] = wrong["source_ids"][:-1]
assert composition._state_matches(wrong, conversation_marker=CONVERSATION_MARKER, child=child) is False
def test_unrelated_guard_excludes_every_planned_row_and_is_read_only(
monkeypatch: pytest.MonkeyPatch,
) -> None:
fixture = composition.build_source_fixture(RUN_MARKER)
child = composition.normalized_stage.prepare_normalized_child(
composition.build_parent_packet(_packet(fixture), fixture, RUN_MARKER, AGENT_ID)
)
observed: dict[str, str] = {}
def fake_psql(_container: str, _database: str, sql: str) -> dict[str, Any]:
observed["sql"] = sql
return {table: {"count": 1, "rowset_md5": "same"} for table in composition.TABLES}
monkeypatch.setattr(composition.bound, "_psql_json", fake_psql)
snapshot = composition.unrelated_guard_snapshot("clone-id", "teleo", child)
lowered = observed["sql"].lower()
assert set(snapshot) == set(composition.TABLES)
assert "begin transaction read only" in lowered
assert child["id"] in observed["sql"]
for collection in ("claims", "sources"):
for row in child["payload"]["apply_payload"][collection]:
assert row["id"] in observed["sql"]
assert "insert into" not in lowered
assert "update " not in lowered
assert "delete from" not in lowered
def test_prefixed_receipts_are_exact_json_objects() -> None:
payload = {"claim_candidates": [], "source_candidates": []}
reply = "analysis\nCOMPOSITION_PACKET: " + json.dumps(payload, sort_keys=True)
assert composition.parse_prefixed_json(reply, composition.PACKET_PREFIX) == payload
with pytest.raises(composition.bound.CheckpointError, match="invalid"):
composition.parse_prefixed_json("COMPOSITION_PACKET: nope", composition.PACKET_PREFIX)
with pytest.raises(composition.bound.CheckpointError, match="did not contain"):
composition.parse_prefixed_json("no receipt", composition.PACKET_PREFIX)
def test_semantic_search_and_exact_read_helpers_require_database_commands_without_generated_ids() -> None:
claim_id = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"
proposal_id = "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
project = "AURORA-TEST"
turn = {
"tool_invocations": [
{"argv": ["search", "approval apply canonical guarded operator review"]},
{"argv": ["search-proposals", project, "--status", "all", "--limit", "20"]},
{"argv": ["show-proposal", proposal_id]},
{"argv": ["show", claim_id]},
{"argv": ["evidence", claim_id, "--format", "json"]},
{"argv": ["edges", claim_id, "--format", "json"]},
]
}
assert composition._searched_semantically_without_ids(turn, [claim_id, proposal_id]) is True
assert composition._searched_composed_proposal(turn, project) is True
assert composition._read_exact_proposal(turn, proposal_id) is True
assert composition._read_claim(turn, claim_id) is True
assert composition._read_claim_evidence(turn, claim_id) is True
assert composition._read_claim_edges(turn, claim_id) is True
evidence_only = {"tool_invocations": [{"argv": ["evidence", claim_id, "--format", "json"]}]}
assert composition._read_claim_material(evidence_only, claim_id) is True
turn["tool_invocations"][0]["argv"][1] = f"show {claim_id}"
assert composition._searched_semantically_without_ids(turn, [claim_id, proposal_id]) is False
def test_cumulative_transcript_merge_accepts_only_receipted_truncated_unknown_results() -> None:
first = [
{"phase": "call", "tool_call_id": "call-1", "tool_name": "terminal"},
{
"phase": "result",
"tool_call_id": "call-1",
"tool_name": "terminal",
"content": '{"exit_code":0}',
"content_truncated": False,
},
]
second = [
*first,
{"phase": "call", "tool_call_id": "call-2", "tool_name": "terminal"},
{
"phase": "result",
"tool_call_id": "call-2",
"tool_name": "terminal",
"content": '{"output":"large',
"content_truncated": True,
},
]
gateways = [
{"transcript_tool_trace": {"events": first}},
{"transcript_tool_trace": {"events": second}},
]
merged = composition.merge_transcript_events(gateways)
consistency = composition.terminal_trace_consistency(
merged,
{
"invocation_count": 2,
"all_bound_to_supplied_target": True,
"all_completed_successfully": True,
},
)
assert len(merged) == 4
assert consistency["passes"] is True
assert consistency["unknown_result_call_ids"] == ["call-2"]
missing_receipt = [event for event in merged if event.get("tool_call_id") != "call-2" or event["phase"] != "result"]
assert composition.terminal_trace_consistency(
missing_receipt,
{
"invocation_count": 2,
"all_bound_to_supplied_target": True,
"all_completed_successfully": True,
},
)["passes"] is False
def test_source_contains_no_production_write_restart_or_delivery_adapter() -> None:
source = (REPO_ROOT / "scripts" / "run_leo_clone_composition_checkpoint.py").read_text(encoding="utf-8").lower()
assert "insert into public." not in source
assert "update public." not in source
assert "delete from public." not in source
assert "systemctl restart" not in source
assert "send_message(" not in source
def test_source_manifest_covers_the_full_composition_and_gate_dependency_closure() -> None:
paths = {item["repo_relative_path"] for item in composition.source_manifest()}
assert paths == {
"scripts/apply_proposal.py",
"scripts/apply_worker.py",
"scripts/approve_proposal.py",
"scripts/bootstrap_clone_kb_gate.py",
"scripts/kb_apply_prereqs.sql",
"scripts/kb_proposal_normalize.py",
"scripts/kb_proposal_review_packet.py",
"scripts/kb_rich_proposal_creation_plan.py",
"scripts/run_approve_claim_clone_canary.py",
"scripts/run_leo_clone_bound_handler_checkpoint.py",
"scripts/run_leo_clone_composition_checkpoint.py",
"scripts/run_leo_clone_lifecycle_checkpoint.py",
"scripts/stage_normalized_proposal.py",
}
def _args(tmp_path: Path) -> argparse.Namespace:
return argparse.Namespace(
container="composition-clone",
db="teleo",
output=tmp_path / "composition-report.json",
run_marker=RUN_MARKER,
conversation_marker=CONVERSATION_MARKER,
chat_id=composition.bound.DEFAULT_CHAT_ID,
user_id=composition.bound.DEFAULT_USER_ID,
user_name="composition unit",
turn_timeout=30,
review_secrets_file=str(tmp_path / "kb-review.env"),
apply_secrets_file=str(tmp_path / "kb-apply.env"),
copy_model_auth=True,
operator_review=True,
guarded_apply=True,
)
def _proposal(child: dict[str, Any], state: str) -> dict[str, Any]:
reviewed = state in {"approved", "applied"}
applied = state == "applied"
return {
"id": child["id"],
"proposal_type": child["proposal_type"],
"status": state,
"channel": child["channel"],
"source_ref": child["source_ref"],
"rationale": child["rationale"],
"payload": child["payload"],
"reviewed_by_handle": composition.lifecycle.REVIEWER_HANDLE if reviewed else None,
"reviewed_by_agent_id": AGENT_ID if reviewed else None,
"reviewed_at": "2026-07-11T10:00:00+00:00" if reviewed else None,
"review_note": composition.lifecycle.REVIEW_NOTE if reviewed else None,
"applied_by_handle": composition.lifecycle.APPLIED_BY_HANDLE if applied else None,
"applied_by_agent_id": AGENT_ID if applied else None,
"applied_at": "2026-07-11T10:01:00+00:00" if applied else None,
}
def _approval_snapshot(proposal: dict[str, Any]) -> dict[str, Any]:
return {
"proposal_id": proposal["id"],
"proposal_type": proposal["proposal_type"],
"payload": proposal["payload"],
"reviewed_by_handle": proposal["reviewed_by_handle"],
"reviewed_by_agent_id": proposal["reviewed_by_agent_id"],
"reviewed_at": proposal["reviewed_at"],
"review_note": proposal["review_note"],
}
def test_mocked_full_composition_checkpoint_passes_with_exact_rows_and_cleanup(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
args = _args(tmp_path)
Path(args.review_secrets_file).write_text("KB_REVIEW_PASSWORD=test\n", encoding="utf-8")
Path(args.apply_secrets_file).write_text("KB_APPLY_PASSWORD=test\n", encoding="utf-8")
fixture = composition.build_source_fixture(args.run_marker)
packet = _packet(fixture)
parent = composition.build_parent_packet(packet, fixture, args.run_marker, AGENT_ID)
child = composition.normalized_stage.prepare_normalized_child(parent)
expected_rows = composition.guarded._expected_bundle_rows(child["payload"]["apply_payload"])
empty_rows = {key: [] for key in expected_rows}
base_counts = {table: 10 for table in composition.TABLES}
final_counts = {
table: base_counts[table] + composition.expected_table_deltas(child)[table] for table in composition.TABLES
}
base_snapshot = {
"counts": base_counts,
"rowset_md5": {table: f"base-{table}" for table in composition.TABLES},
}
state: dict[str, Any] = {"phase": "initial", "invocations": [], "transcript_events": []}
target_identity = {
"id": "composition-clone-id",
"name": args.container,
"image": "postgres",
"labels": {
composition.bound.DISPOSABLE_LABEL_KEY: composition.bound.DISPOSABLE_LABEL_VALUE,
},
"network_mode": "none",
"ports": {},
"mount_sources": ["/composition-clone-data"],
"started_at": "clone-start",
}
production_identity = {
"id": "production-id",
"name": composition.bound.PRODUCTION_CONTAINER,
"image": "postgres",
"labels": {},
"network_mode": "bridge",
"ports": {},
"mount_sources": ["/production-data"],
"started_at": "production-start",
}
monkeypatch.setattr(
composition.lifecycle,
"assert_disposable_target",
lambda _container, _database: (dict(target_identity), dict(production_identity)),
)
monkeypatch.setattr(
composition.bound,
"container_identity",
lambda name: dict(production_identity if name == composition.bound.PRODUCTION_CONTAINER else target_identity),
)
def guard_snapshot(container: str, _database: str, **_kwargs: Any) -> dict[str, Any]:
snapshot = json.loads(json.dumps(base_snapshot))
production = container == composition.bound.PRODUCTION_CONTAINER
snapshot["database_identity"] = {
"current_database": args.db,
"system_identifier": "production-system" if production else "clone-system",
"transaction_read_only": "off",
}
if not production and state["phase"] == "applied":
snapshot["counts"] = dict(final_counts)
for table, delta in composition.expected_table_deltas(child).items():
if delta:
snapshot["rowset_md5"][table] = "changed"
return snapshot
monkeypatch.setattr(composition.bound, "database_guard_snapshot", guard_snapshot)
clone_gate = {
"approval_table": composition.lifecycle.APPROVAL_TABLE,
"review_principals_table": "kb_stage.kb_review_principals",
"review_role_exists": True,
"apply_role_exists": True,
"approve_function": "kb_stage.approve_strict_proposal",
"assert_function": "kb_stage.assert_approved_proposal",
"finish_function": "kb_stage.finish_approved_proposal",
}
production_gate = {
"approval_table": None,
"review_principals_table": None,
"review_role_exists": False,
"apply_role_exists": True,
"approve_function": None,
"assert_function": None,
"finish_function": None,
}
monkeypatch.setattr(
composition,
"gate_schema_manifest",
lambda container, _database: (
dict(production_gate) if container == composition.bound.PRODUCTION_CONTAINER else dict(clone_gate)
),
)
monkeypatch.setattr(
composition.bound,
"service_state",
lambda: {"returncode": 0, "ActiveState": "active", "MainPID": "123", "NRestarts": "0"},
)
monkeypatch.setattr(
composition.bound,
"bridge_hashes",
lambda: {"wrapper": "live-wrapper", "bridge_skill": "live-skill"},
)
runtime_root = tmp_path / "composition-runtime"
runtime_profile = runtime_root / "profile"
def copy_profile(**_kwargs: Any) -> tuple[Path, dict[str, Any]]:
runtime_profile.mkdir(parents=True)
composition.bound.register_temp_root(runtime_root)
return runtime_profile, {"passes": True, "secret_contents_read_or_recorded": False}
monkeypatch.setattr(composition.bound, "copy_profile", copy_profile)
monkeypatch.setattr(
composition.bound,
"copy_ephemeral_model_auth",
lambda _profile: {"mode": "ephemeral_file_copy", "source_contents_recorded": False},
)
monkeypatch.setattr(
composition.bound,
"load_ephemeral_provider_environment",
lambda _profile: ({}, {"bound_credential_count": 0, "credential_contents_recorded": False}),
)
tool_log = runtime_profile / "tool-log.jsonl"
monkeypatch.setattr(
composition,
"patch_composition_bridge",
lambda _profile, **_kwargs: {
"tool_log_path": str(tool_log),
"run_nonce": "composition-run-nonce",
"wrapper_path": str(runtime_profile / "bin" / "teleo-kb"),
"bridge_skill_path": str(runtime_profile / "skills" / "teleo-kb-bridge" / "SKILL.md"),
},
)
monkeypatch.setattr(composition, "resolve_leo_agent_id", lambda _container, _database: AGENT_ID)
monkeypatch.setattr(
composition.normalized_stage,
"stage_normalized_child",
lambda _container, _database, _parent: (
state.update(phase="pending_review")
or {
"child": child,
"bound_container_id": target_identity["id"],
"database_receipt": {
"created": True,
"proposal_id": child["id"],
"proposal_type": child["proposal_type"],
"status": "pending_review",
"source_ref": child["source_ref"],
"payload_sha256": child["payload_sha256"],
},
}
),
)
monkeypatch.setattr(
composition.guarded,
"_exact_bundle_readback",
lambda _container, _database, _payload: expected_rows if state["phase"] == "applied" else empty_rows,
)
monkeypatch.setattr(
composition.guarded,
"_proposal_readback",
lambda _container, _database, _proposal_id: (
None if state["phase"] == "initial" else _proposal(child, state["phase"])
),
)
monkeypatch.setattr(
composition.guarded,
"_approval_snapshot_readback",
lambda _container, _database, _proposal_id: _approval_snapshot(_proposal(child, "approved")),
)
unrelated = {table: {"count": 10, "rowset_md5": f"unrelated-{table}"} for table in composition.TABLES}
monkeypatch.setattr(
composition,
"unrelated_guard_snapshot",
lambda _container, _database, _child: json.loads(json.dumps(unrelated)),
)
def review(
_args: argparse.Namespace, _proposal_id: str
) -> tuple[subprocess.CompletedProcess[str], subprocess.CompletedProcess[str]]:
state["phase"] = "approved"
return (
subprocess.CompletedProcess([], 0, "select kb_stage.approve_strict_proposal(...);", ""),
subprocess.CompletedProcess([], 0, "approved", ""),
)
def apply(
_args: argparse.Namespace, _proposal_id: str
) -> tuple[subprocess.CompletedProcess[str], subprocess.CompletedProcess[str]]:
state["phase"] = "applied"
return (
subprocess.CompletedProcess(
[],
0,
"select kb_stage.assert_approved_proposal(...); select kb_stage.finish_approved_proposal(...);",
"",
),
subprocess.CompletedProcess([], 0, "applied", ""),
)
monkeypatch.setattr(composition.lifecycle, "run_operator_review", review)
monkeypatch.setattr(composition.lifecycle, "run_guarded_apply", apply)
async def run_turn(
_args: argparse.Namespace,
_profile: Path,
*,
phase: str,
prompt: str,
provider_environment: dict[str, str],
tool_log: Path,
) -> dict[str, Any]:
assert provider_environment == {}
assert tool_log == runtime_profile / "tool-log.jsonl"
if phase == "T1_extract_sources":
reply = "Extracted two conflicting claims.\nCOMPOSITION_PACKET: " + json.dumps(
packet, sort_keys=True, separators=(",", ":")
)
argvs = [["context", packet["dedupe_conflict_assessment"]["database_search_query"]]]
pid = 101
else:
payload = child["payload"]["apply_payload"]
edge = payload["edges"][0]
receipt = {
"phase": "final",
"conversation_marker": args.conversation_marker,
"proposal_id": child["id"],
"status": "applied",
"claim_ids": [row["id"] for row in payload["claims"]],
"source_ids": [row["id"] for row in payload["sources"]],
"conflict_edge": {
"from_claim": edge["from_claim"],
"to_claim": edge["to_claim"],
"edge_type": edge["edge_type"],
},
}
reply = (
"Approval was not canonical; guarded apply made it applied and canonical. The sources conflict. "
f"I recall {args.conversation_marker}.\nCOMPOSITION_STATE: "
+ json.dumps(receipt, sort_keys=True, separators=(",", ":"))
)
argvs = [
["search", "approval apply canonical guarded operator review"],
["search-proposals", fixture["project"], "--status", "all", "--limit", "20"],
["show-proposal", child["id"]],
*[["show", row["id"]] for row in payload["claims"]],
*[["evidence", row["id"], "--format", "json"] for row in payload["claims"]],
["edges", payload["claims"][0]["id"], "--format", "json"],
]
pid = 202
invocations = [
{
"invocation_id": f"{phase}-{index}",
"container": target_identity["id"],
"database": args.db,
"argv": argv,
"returncode": 0,
}
for index, argv in enumerate(argvs)
]
state["invocations"].extend(invocations)
current_events = [
event
for invocation in invocations
for event in (
{
"phase": "call",
"tool_name": "terminal",
"tool_call_id": invocation["invocation_id"],
},
{
"phase": "result",
"tool_name": "terminal",
"tool_call_id": invocation["invocation_id"],
"content": '{"exit_code":0}',
"content_truncated": False,
},
)
]
state["transcript_events"].extend(current_events)
events = copy.deepcopy(state["transcript_events"])
return {
"phase": phase,
"prompt": prompt,
"prompt_sha256": "prompt-hash",
"tool_invocations": invocations,
"gateway": {
"authorized": True,
"handler_invoked": True,
"posted_to_telegram": False,
"model_free_fallback_used": False,
"reply": reply,
"session_key": "telegram:composition",
"transcript_tool_trace": {
"session_id": "persisted-composition-session",
"events": events,
},
"tool_surface": {
"allowed_tools": ["skills_list", "skill_view", "terminal"],
"actual_registry_tools": ["skills_list", "skill_view", "terminal"],
"gateway_adapters_verified_mapping": True,
"gateway_adapter_count": 0,
"send_message_tool_enabled": False,
"terminal_restricted_to_clone_wrapper": True,
"terminal_subprocess_inherits_provider_credentials": False,
},
"child_process": {
"pid": pid,
"readiness_verified": True,
"timed_out": False,
"exitcode": 0,
"result_transport": "private_temp_file",
"termination": {"attempted": False},
"alive_after_readback": False,
"process_group_alive_after_readback": False,
},
},
}
monkeypatch.setattr(composition, "run_turn", run_turn)
monkeypatch.setattr(
composition.bound,
"read_tool_proof",
lambda _path, _container, _database, **_kwargs: {
"invocations": list(state["invocations"]),
"invocation_count": len(state["invocations"]),
"all_bound_to_supplied_target": bool(state["invocations"]),
"all_completed_successfully": bool(state["invocations"]),
},
)
report = asyncio.run(composition.run_checkpoint(args))
assert report["status"] == "pass", {
"errors": report["errors"],
"failed_checks": [name for name, passed in report["checks"].items() if not passed],
}
assert all(report["checks"].values())
assert report["final_canonical_rows"] == expected_rows
assert report["checks"]["target_table_deltas_exact"] is True
assert report["cleanup"]["active_gateway_registry_clear"] is True
assert not os.path.lexists(runtime_root)
retained = json.loads(args.output.read_text(encoding="utf-8"))
assert retained["status"] == "pass"
assert args.output.stat().st_mode & 0o777 == 0o600