#!/usr/bin/env python3 """Prove Leo can compose and reason over source-derived KB rows in a disposable clone.""" from __future__ import annotations import argparse import asyncio import hashlib import json import sys import traceback import uuid from pathlib import Path from types import SimpleNamespace from typing import Any HERE = Path(__file__).resolve().parent REPO_ROOT = HERE.parent sys.path.insert(0, str(HERE)) import apply_proposal as ap # noqa: E402 import run_approve_claim_clone_canary as guarded # noqa: E402 import run_leo_clone_bound_handler_checkpoint as bound # noqa: E402 import run_leo_clone_lifecycle_checkpoint as lifecycle # noqa: E402 import stage_normalized_proposal as normalized_stage # noqa: E402 SCHEMA = "livingip.leoCloneCompositionCheckpoint.v1" PACKET_PREFIX = "COMPOSITION_PACKET:" STATE_PREFIX = "COMPOSITION_STATE:" TABLES = lifecycle.LIFECYCLE_TABLES PRODUCTION_TABLES = bound.COUNT_TABLES def _stable_uuid(run_marker: str, label: str) -> str: return str(uuid.uuid5(uuid.NAMESPACE_URL, f"livingip:leo-composition:{run_marker}:{label}")) def build_source_fixture(run_marker: str) -> dict[str, Any]: project = "AURORA-" + hashlib.sha256(run_marker.encode()).hexdigest()[:10].upper() document_text = ( f"{project} operating note. A knowledge change becomes canonical only after operator review and guarded " "apply. Approval alone leaves canonical rows unchanged." ) post_text = ( f"For {project}, reviewer approval is enough: a Leo proposal becomes canonical immediately, and no apply " "step is needed." ) return { "project": project, "document": { "source_key": "operating_document", "source_type": "article", "title": f"{project} operating note", "storage_path": f"/composition/{run_marker}/operating-note.txt", "text": document_text, "content_sha256": hashlib.sha256(document_text.encode()).hexdigest(), }, "post": { "source_key": "contradictory_post", "source_type": "post", "title": f"{project} contradictory post", "url": f"https://x.example.test/{run_marker}", "text": post_text, "content_sha256": hashlib.sha256(post_text.encode()).hexdigest(), }, } def build_prompts(fixture: dict[str, Any], conversation_marker: str) -> dict[str, str]: document = fixture["document"] post = fixture["post"] extraction_schema = { "claim_candidates": [ { "claim_key": "stable_key", "text": "atomic claim", "type": "structural|empirical|normative|meta|concept", "confidence": 0.0, "evidence": [{"source_key": "operating_document", "role": "grounds"}], "edges": [{"edge_type": "contradicts", "target": "other_claim_key"}], } ], "source_candidates": [ { "source_key": "operating_document|contradictory_post", "source_type": "article|post", "storage_path": "document path or null", "url": "post URL or null", "title": "source title", "source_quality": "quality assessment", "key_excerpt": "exact source substring", "content_sha256": "supplied source SHA-256", } ], "dedupe_conflict_assessment": { "database_search_query": "query actually used", "potential_existing_claim_ids": [], "conflicts": [ { "from_claim_key": "claim key", "to_claim_key": "claim key", "relationship": "contradicts", } ], }, } return { "extract": ( f"Cory-style source intake for {fixture['project']}. Remember this conversation-only marker for the " f"later reasoning turn: {conversation_marker}. First search the canonical KB for this project's topic so " "you can report possible duplicates. Then extract atomic claims, exact evidence excerpts, provenance, " "source quality, and explicit conflicts from the two new sources below. Do not stage, approve, apply, or " "claim canonicality. Use source_key operating_document for the document and contradictory_post for the " "post. Preserve the supplied SHA-256 values exactly. Every claim needs evidence; represent the sources' " "conflict with a contradicts edge between claim keys. Return normal prose, then one final compact JSON " f"line beginning {PACKET_PREFIX}. Schema: {json.dumps(extraction_schema, sort_keys=True)}\n\n" f"DOCUMENT locator={document['storage_path']} sha256={document['content_sha256']}\n" f"{document['text']}\n\nPOST locator={post['url']} sha256={post['content_sha256']}\n{post['text']}" ), "reason": ( f"Cory asks about {fixture['project']}: 'approval means it is already in Leo, right?' Answer from the " "canonical KB, explain the source conflict and which evidence is stronger, and distinguish approved from " f"applied. Search without asking me for IDs. Then search proposals using {fixture['project']}, open the " "matching proposal, inspect every relevant claim, run evidence for each claim with --format json so you can " "report canonical source UUIDs rather than source keys, and run edges with --format json for at least one " "claim. Recall the conversation-only marker from the earlier source-intake turn. End with one compact JSON " f"line beginning {STATE_PREFIX}. Set phase exactly to 'final', proposal_id to the full discovered proposal " "UUID, conversation_marker to the exact recalled marker, status exactly to 'applied', claim_ids and " "source_ids to every full canonical UUID discovered from the DB, and conflict_edge to one real canonical " "edge with from_claim, to_claim, edge_type." ), } def parse_prefixed_json(reply: str, prefix: str) -> dict[str, Any]: for line in reversed(reply.splitlines()): stripped = line.strip() if not stripped.startswith(prefix): continue try: value = json.loads(stripped[len(prefix) :].strip()) except json.JSONDecodeError as exc: raise bound.CheckpointError(f"invalid {prefix} JSON: {exc}") from exc if not isinstance(value, dict): raise bound.CheckpointError(f"{prefix} payload must be a JSON object") return value raise bound.CheckpointError(f"reply did not contain a {prefix} line") def validate_composition_packet(packet: dict[str, Any], fixture: dict[str, Any]) -> dict[str, Any]: claims = packet.get("claim_candidates") sources = packet.get("source_candidates") assessment = packet.get("dedupe_conflict_assessment") if not isinstance(claims, list) or len(claims) < 2: raise bound.CheckpointError("composition packet must contain at least two claim candidates") if not isinstance(sources, list) or len(sources) != 2: raise bound.CheckpointError("composition packet must contain exactly the two supplied source candidates") if not isinstance(assessment, dict) or not str(assessment.get("database_search_query") or "").strip(): raise bound.CheckpointError("composition packet must record the canonical dedupe search query") source_by_key = {str(source.get("source_key")): source for source in sources if isinstance(source, dict)} if set(source_by_key) != {"operating_document", "contradictory_post"}: raise bound.CheckpointError("composition source keys do not match the supplied sources") for label, fixture_key, locator_key in ( ("operating_document", "document", "storage_path"), ("contradictory_post", "post", "url"), ): source = source_by_key[label] expected = fixture[fixture_key] excerpt = str(source.get("key_excerpt") or "") if not excerpt or excerpt not in expected["text"]: raise bound.CheckpointError(f"{label} excerpt is not an exact substring of the supplied source") if source.get("content_sha256") != expected["content_sha256"]: raise bound.CheckpointError(f"{label} content SHA-256 does not match the supplied bytes") if source.get(locator_key) != expected[locator_key]: raise bound.CheckpointError(f"{label} locator does not match the supplied source") claim_keys: set[str] = set() evidence_source_keys: set[str] = set() conflict_pairs: set[tuple[str, str]] = set() for claim in claims: if not isinstance(claim, dict): raise bound.CheckpointError("every claim candidate must be an object") claim_key = str(claim.get("claim_key") or "").strip() claim_text = str(claim.get("text") or claim.get("headline") or "").strip() if not claim_key or not claim_text or claim_key in claim_keys: raise bound.CheckpointError("claim candidates need unique keys and nonempty atomic text") claim_keys.add(claim_key) evidence = claim.get("evidence") if not isinstance(evidence, list) or not evidence: raise bound.CheckpointError(f"claim {claim_key} has no evidence") for item in evidence: if isinstance(item, dict) and item.get("source_key"): evidence_source_keys.add(str(item["source_key"])) for edge in claim.get("edges") or []: if isinstance(edge, dict) and edge.get("edge_type") == "contradicts" and edge.get("target"): conflict_pairs.add((claim_key, str(edge["target"]))) if evidence_source_keys != set(source_by_key): raise bound.CheckpointError("both supplied sources must ground at least one extracted claim") if not any(left in claim_keys and right in claim_keys and left != right for left, right in conflict_pairs): raise bound.CheckpointError("composition packet did not encode the source conflict as a claim edge") conflicts = assessment.get("conflicts") if not isinstance(conflicts, list) or not conflicts: raise bound.CheckpointError("dedupe/conflict assessment omitted the observed contradiction") return { "claim_count": len(claims), "source_count": len(sources), "claim_keys": sorted(claim_keys), "evidence_source_keys": sorted(evidence_source_keys), "conflict_pairs": sorted([list(pair) for pair in conflict_pairs]), } def build_parent_packet( packet: dict[str, Any], fixture: dict[str, Any], run_marker: str, agent_id: str ) -> dict[str, Any]: return { "id": _stable_uuid(run_marker, "rich-source-packet"), "proposal_type": "attach_evidence", "status": "pending_review", "proposed_by_handle": "leo", "proposed_by_agent_id": agent_id, "channel": "clone_composition", "source_ref": f"clone-composition:{run_marker}", "rationale": f"Leo source composition packet for {fixture['project']}.", "payload": packet, } def resolve_leo_agent_id(container: str, database: str) -> str: result = bound._psql_json( container, database, """\\set ON_ERROR_STOP on begin transaction read only; select jsonb_build_object( 'agent_id', ( select id::text from public.agents where lower(handle) in ('leo', 'leoclean') order by case lower(handle) when 'leo' then 0 else 1 end, id limit 1 ) )::text; rollback; """, ) try: return str(uuid.UUID(str(result.get("agent_id")))) except ValueError as exc: raise bound.CheckpointError("clone has no canonical leo/leoclean agent row for attribution") from exc def _replace_generic_receipt(skill_text: str) -> str: return skill_text.replace( """End the final answer with one machine-readable line using the full proposal UUID and the row state you observed: `KB_STATE: {"proposal_id":"","status":"pending_review|approved|applied","applied":false}` """, "", ) def patch_composition_bridge( temp_profile: Path, *, container: str, database: str, fixture: dict[str, Any] ) -> dict[str, Any]: bridge = bound.patch_temp_bridge(temp_profile, container, database) skill_path = Path(bridge["bridge_skill_path"]) skill_text = _replace_generic_receipt(skill_path.read_text(encoding="utf-8")) binding = f""" ## Disposable Source Composition Checkpoint This no-send profile is testing source composition for `{fixture["project"]}` against one disposable clone. You may only search and read the clone. You cannot stage, review, approve, apply, send, or access production. The prompt defines either a `COMPOSITION_PACKET:` extraction receipt or a `COMPOSITION_STATE:` canonical reasoning receipt; emit only the receipt requested by that turn. """ skill_text = bound.inject_skill_binding(skill_text, binding.lstrip()) bound._detach_and_write(skill_path, skill_text, mode=0o600) bridge["bridge_skill_sha256"] = bound.sha256_bytes(skill_text.encode()) bridge["composition_project"] = fixture["project"] return bridge def _exclude_rows(rows: list[dict[str, Any]], columns: tuple[str, ...]) -> str: if not rows: return "true" matches = [] for row in rows: matches.append( "(" + " and ".join(f"t.{column}::text = {ap.sql_literal(str(row[column]))}" for column in columns) + ")" ) return "not (" + " or ".join(matches) + ")" def unrelated_guard_snapshot(container: str, database: str, child: dict[str, Any]) -> dict[str, Any]: rows = guarded._expected_bundle_rows(child["payload"]["apply_payload"]) predicates = { "public.claims": _exclude_rows(rows["claims"], ("id",)), "public.sources": _exclude_rows(rows["sources"], ("id",)), "public.claim_evidence": _exclude_rows(rows["claim_evidence"], ("claim_id", "source_id", "role")), "public.claim_edges": _exclude_rows(rows["claim_edges"], ("from_claim", "to_claim", "edge_type")), "public.reasoning_tools": _exclude_rows(rows["reasoning_tools"], ("id",)), "kb_stage.kb_proposals": f"t.id <> {ap.sql_literal(child['id'])}::uuid", lifecycle.APPROVAL_TABLE: f"t.proposal_id <> {ap.sql_literal(child['id'])}::uuid", } pairs = [ f"""'{table}', jsonb_build_object( 'count', (select count(*) from {table} t where {predicates[table]}), 'rowset_md5', (select md5(coalesce(string_agg(to_jsonb(t)::text, E'\\n' order by to_jsonb(t)::text), '')) from {table} t where {predicates[table]}) )""" for table in TABLES ] return bound._psql_json( container, database, """\\set ON_ERROR_STOP on begin transaction read only; select jsonb_build_object( """ + ",\n ".join(pairs) + """ )::text; rollback; """, ) def _turn_args(args: argparse.Namespace, phase: str, prompt: str) -> argparse.Namespace: return SimpleNamespace( chat_id=args.chat_id, user_id=args.user_id, user_name=args.user_name, prompt=prompt, prompt_id=phase, run_id=args.run_marker, turn_timeout=args.turn_timeout, ) async def run_turn( args: argparse.Namespace, temp_profile: Path, *, phase: str, prompt: str, provider_environment: dict[str, str], tool_log: Path, ) -> dict[str, Any]: proof_args = { "run_nonce": args.tool_run_nonce, "database_identity": args.target_database_identity, "require_database_read_only": False, } before = bound.read_tool_proof(tool_log, args.bound_container_id, args.db, **proof_args) gateway = await bound.invoke_gateway_subprocess( _turn_args(args, phase, prompt), temp_profile, provider_environment=provider_environment ) after = bound.read_tool_proof(tool_log, args.bound_container_id, args.db, **proof_args) return { "phase": phase, "prompt_sha256": hashlib.sha256(prompt.encode()).hexdigest(), "prompt": prompt, "gateway": gateway, "tool_invocations": after["invocations"][before["invocation_count"] :], } def _argvs(turn: dict[str, Any]) -> list[list[str]]: return [ [str(value) for value in invocation.get("argv", [])] for invocation in turn.get("tool_invocations", []) if invocation.get("argv") ] def _searched_project(turn: dict[str, Any], project: str) -> bool: return any( len(argv) >= 2 and argv[0] in {"search", "context"} and project.lower() in argv[1].lower() for argv in _argvs(turn) ) def _searched_recorded_dedupe_query(turn: dict[str, Any], packet: dict[str, Any]) -> bool: assessment = packet.get("dedupe_conflict_assessment") or {} query = str(assessment.get("database_search_query") or "") return bool(query) and any( len(argv) >= 2 and argv[0] in {"search", "context"} and argv[1] == query for argv in _argvs(turn) ) def _searched_semantically_without_ids(turn: dict[str, Any], row_ids: list[str]) -> bool: terms = {"approval", "approved", "apply", "applied", "canonical", "review"} return any( len(argv) >= 2 and argv[0] in {"search", "context"} and not any(row_id in argv[1] for row_id in row_ids) and len(terms & set(argv[1].lower().split())) >= 2 for argv in _argvs(turn) ) def _searched_composed_proposal(turn: dict[str, Any], project: str) -> bool: return any( len(argv) >= 2 and argv[0] == "search-proposals" and project.lower() in argv[1].lower() for argv in _argvs(turn) ) def _read_claim(turn: dict[str, Any], claim_id: str) -> bool: return any(argv[:2] == ["show", claim_id] for argv in _argvs(turn)) def _read_claim_edges(turn: dict[str, Any], claim_id: str) -> bool: return any(argv[:2] == ["edges", claim_id] for argv in _argvs(turn)) def _read_claim_evidence(turn: dict[str, Any], claim_id: str) -> bool: return any( argv[:2] == ["evidence", claim_id] and argv[2:] in (["--format", "json"], ["--format=json"]) for argv in _argvs(turn) ) def _read_claim_material(turn: dict[str, Any], claim_id: str) -> bool: return _read_claim(turn, claim_id) or _read_claim_evidence(turn, claim_id) def _read_exact_proposal(turn: dict[str, Any], proposal_id: str) -> bool: return any(argv[:2] == ["show-proposal", proposal_id] for argv in _argvs(turn)) def merge_transcript_events(gateways: list[dict[str, Any]]) -> list[dict[str, Any]]: """Collapse cumulative session traces without hiding events that lack an ID.""" merged: dict[tuple[str, str], dict[str, Any]] = {} order: list[tuple[str, str]] = [] for gateway_index, gateway in enumerate(gateways): events = (gateway.get("transcript_tool_trace") or {}).get("events", []) for event_index, event in enumerate(events): phase = str(event.get("phase") or "") call_id = str(event.get("tool_call_id") or "") if not call_id: call_id = f"missing:{gateway_index}:{event_index}" key = (phase, call_id) if key not in merged: order.append(key) merged[key] = event return [merged[key] for key in order] def terminal_trace_consistency(events: list[dict[str, Any]], tool_proof: dict[str, Any]) -> dict[str, Any]: """Reconcile bounded transcript receipts with nonce-bound wrapper receipts.""" terminal_calls = { str(event.get("tool_call_id")): event for event in events if event.get("phase") == "call" and event.get("tool_name") == "terminal" } results = { str(event.get("tool_call_id")): event for event in events if event.get("phase") == "result" and event.get("tool_call_id") } summary = bound.transcript_terminal_attempt_summary(events) known_exit_codes = summary.get("known_exit_codes") or {} unknown_ids = sorted(set(terminal_calls) - set(known_exit_codes)) unknown_receipted_and_truncated = sorted( call_id for call_id in unknown_ids if call_id in results and results[call_id].get("content_truncated") is True ) every_call_has_result = set(terminal_calls) <= set(results) unknown_results_are_valid = unknown_ids == unknown_receipted_and_truncated count_matches = len(terminal_calls) == int(tool_proof.get("invocation_count") or 0) passes = ( bool(terminal_calls) and every_call_has_result and unknown_results_are_valid and summary.get("rejected_call_count") == 0 and summary.get("nonzero_call_count") == 0 and count_matches and tool_proof.get("all_bound_to_supplied_target") is True and tool_proof.get("all_completed_successfully") is True ) return { **summary, "terminal_call_ids": sorted(terminal_calls), "result_call_ids": sorted(results), "unknown_result_call_ids": unknown_ids, "unknown_receipted_and_truncated_call_ids": unknown_receipted_and_truncated, "every_terminal_call_has_result": every_call_has_result, "unknown_results_are_receipted_and_truncated": unknown_results_are_valid, "nonce_bound_invocation_count": int(tool_proof.get("invocation_count") or 0), "nonce_bound_invocation_count_matches": count_matches, "passes": passes, } def _state_matches(state: dict[str, Any], *, conversation_marker: str, child: dict[str, Any]) -> bool: payload = child["payload"]["apply_payload"] expected_claim_ids = sorted(row["id"] for row in payload["claims"]) expected_source_ids = sorted(row["id"] for row in payload["sources"]) edges = payload["edges"] edge = state.get("conflict_edge") if isinstance(state.get("conflict_edge"), dict) else {} return ( state.get("phase") == "final" and (state.get("conversation_marker") or state.get("marker")) == conversation_marker and state.get("proposal_id") == child["id"] and state.get("status") == "applied" and sorted(state.get("claim_ids") or []) == expected_claim_ids and sorted(state.get("source_ids") or []) == expected_source_ids and bool(edges) and any( edge.get("from_claim") == expected["from_claim"] and edge.get("to_claim") == expected["to_claim"] and edge.get("edge_type") == expected["edge_type"] for expected in edges ) ) def _service_unchanged(before: dict[str, Any] | None, after: dict[str, Any] | None) -> bool: return bool(before and after and before.get("returncode") == 0 and before == after) def expected_table_deltas(child: dict[str, Any]) -> dict[str, int]: rows = guarded._expected_bundle_rows(child["payload"]["apply_payload"]) return { "public.claims": len(rows["claims"]), "public.sources": len(rows["sources"]), "public.claim_evidence": len(rows["claim_evidence"]), "public.claim_edges": len(rows["claim_edges"]), "public.reasoning_tools": len(rows["reasoning_tools"]), "kb_stage.kb_proposals": 1, lifecycle.APPROVAL_TABLE: 1, } def base_snapshot_matches(target: dict[str, Any], production: dict[str, Any]) -> bool: return all( target.get(section, {}).get(table) == production.get(section, {}).get(table) for section in ("counts", "rowset_md5") for table in PRODUCTION_TABLES ) def gate_schema_manifest(container: str, database: str) -> dict[str, Any]: return bound._psql_json( container, database, """\\set ON_ERROR_STOP on begin transaction read only; select jsonb_build_object( 'approval_table', to_regclass('kb_stage.kb_proposal_approvals')::text, 'review_principals_table', to_regclass('kb_stage.kb_review_principals')::text, 'review_role_exists', exists(select 1 from pg_roles where rolname = 'kb_review'), 'apply_role_exists', exists(select 1 from pg_roles where rolname = 'kb_apply'), 'approve_function', to_regprocedure( 'kb_stage.approve_strict_proposal(uuid,text,jsonb,text,text)' )::text, 'assert_function', to_regprocedure( 'kb_stage.assert_approved_proposal(uuid,text,jsonb,text,uuid,timestamptz,text)' )::text, 'finish_function', to_regprocedure( 'kb_stage.finish_approved_proposal(uuid,text,jsonb,text,uuid,timestamptz,text,text)' )::text )::text; rollback; """, ) def clone_gate_schema_ready(manifest: dict[str, Any]) -> bool: return ( manifest.get("approval_table") == lifecycle.APPROVAL_TABLE and manifest.get("review_principals_table") == "kb_stage.kb_review_principals" and manifest.get("review_role_exists") is True and manifest.get("apply_role_exists") is True and bool(manifest.get("approve_function")) and bool(manifest.get("assert_function")) and bool(manifest.get("finish_function")) ) def source_manifest() -> list[dict[str, Any]]: paths = ( Path(__file__).resolve(), (HERE / "bootstrap_clone_kb_gate.py").resolve(), (HERE / "kb_apply_prereqs.sql").resolve(), (HERE / "run_leo_clone_bound_handler_checkpoint.py").resolve(), (HERE / "run_leo_clone_lifecycle_checkpoint.py").resolve(), (HERE / "stage_normalized_proposal.py").resolve(), (HERE / "kb_proposal_normalize.py").resolve(), (HERE / "kb_proposal_review_packet.py").resolve(), (HERE / "kb_rich_proposal_creation_plan.py").resolve(), (HERE / "apply_worker.py").resolve(), (HERE / "run_approve_claim_clone_canary.py").resolve(), (HERE / "approve_proposal.py").resolve(), (HERE / "apply_proposal.py").resolve(), ) return [ { "repo_relative_path": path.relative_to(REPO_ROOT.resolve()).as_posix(), "sha256": hashlib.sha256(path.read_bytes()).hexdigest(), "size_bytes": path.stat().st_size, } for path in paths ] def validate_args(args: argparse.Namespace) -> None: lifecycle._validate_marker(args.run_marker, "--run-marker") lifecycle._validate_marker(args.conversation_marker, "--conversation-marker") if args.run_marker == args.conversation_marker: raise bound.CheckpointError("run and conversation markers must be distinct") if args.container == bound.PRODUCTION_CONTAINER: raise bound.CheckpointError("--container must be a disposable non-production container") if not bound.SAFE_DOCKER_NAME_RE.fullmatch(args.container): raise bound.CheckpointError("--container must be an explicit Docker name") if not bound.SAFE_DB_NAME_RE.fullmatch(args.db): raise bound.CheckpointError("--db must be an explicit database name") if not args.copy_model_auth or not args.operator_review or not args.guarded_apply: raise bound.CheckpointError("--copy-model-auth, --operator-review, and --guarded-apply are required") if args.turn_timeout <= 0: raise bound.CheckpointError("--turn-timeout must be positive") args.output = bound.validate_private_output_path(args.output) async def run_checkpoint(args: argparse.Namespace) -> dict[str, Any]: validate_args(args) fixture = build_source_fixture(args.run_marker) prompts = build_prompts(fixture, args.conversation_marker) report: dict[str, Any] = { "schema": SCHEMA, "generated_at_utc": bound.utc_now(), "current_canary": "source bytes -> Leo extraction -> strict staged child -> review/apply -> restarted reasoning", "required_tier": "live_vps_no_send_disposable_full_data_clone", "posted_to_telegram": False, "production_writes_attempted": False, "production_service_restart_attempted": False, "fixture": { "project": fixture["project"], "document_sha256": fixture["document"]["content_sha256"], "post_sha256": fixture["post"]["content_sha256"], }, "errors": [], "turns": {}, "source_manifest_before": source_manifest(), "output": str(args.output), } temp_profile: Path | None = None tool_log: Path | None = None bridge: dict[str, Any] = {} provider_environment: dict[str, str] = {} provider_secret_values: tuple[str, ...] = () target_container_id: str | None = None target_identity_before: dict[str, Any] | None = None target_guard_before: dict[str, Any] | None = None target_unrelated_before: dict[str, Any] | None = None production_guard_before: dict[str, Any] | None = None production_gate_schema_before: dict[str, Any] | None = None production_service_before: dict[str, Any] | None = None live_bridge_before: dict[str, str | None] | None = None packet: dict[str, Any] | None = None child: dict[str, Any] | None = None try: target_identity_before, production_identity = lifecycle.assert_disposable_target(args.container, args.db) target_container_id = str(target_identity_before["id"]) args.bound_container_id = target_container_id report["target"] = { "requested_container": args.container, "bound_container_id": target_container_id, "container_identity_before": target_identity_before, "isolation_checks": bound.validate_disposable_target_identity(target_identity_before, production_identity), } production_guard_before = bound.database_guard_snapshot( bound.PRODUCTION_CONTAINER, bound.PRODUCTION_DB, tables=PRODUCTION_TABLES ) target_base_guard = bound.database_guard_snapshot(target_container_id, args.db, tables=PRODUCTION_TABLES) if not base_snapshot_matches(target_base_guard, production_guard_before): raise bound.CheckpointError( "target base rows are not an exact production clone before clone-only gate additions" ) target_guard_before = bound.database_guard_snapshot(target_container_id, args.db, tables=TABLES) target_gate_schema = gate_schema_manifest(target_container_id, args.db) if not clone_gate_schema_ready(target_gate_schema): raise bound.CheckpointError( "clone-only guarded review/apply prerequisites are incomplete: " + json.dumps(target_gate_schema, sort_keys=True) ) production_gate_schema_before = gate_schema_manifest(bound.PRODUCTION_CONTAINER, bound.PRODUCTION_DB) if ( target_guard_before["database_identity"]["system_identifier"] == production_guard_before["database_identity"]["system_identifier"] ): raise bound.CheckpointError("target and production share a PostgreSQL system identifier") args.target_database_identity = target_guard_before["database_identity"] production_service_before = bound.service_state() live_bridge_before = bound.bridge_hashes() report["production_invariants"] = { "container_identity": production_identity, "guard_snapshot_before": production_guard_before, "gate_schema_before": production_gate_schema_before, "service_before": production_service_before, "live_bridge_hashes_before": live_bridge_before, } report["target_base_guard_snapshot"] = target_base_guard report["target_gate_schema"] = target_gate_schema report["target_guard_snapshot_before"] = target_guard_before missing_secrets = [ label for label, path in ( ("review", Path(args.review_secrets_file)), ("apply", Path(args.apply_secrets_file)), ) if not path.is_file() ] if missing_secrets: raise bound.CheckpointError( "required separated clone credential file(s) are absent: " + ", ".join(missing_secrets) ) temp_profile, copy_audit = bound.copy_profile(run_id=args.run_marker, prompt_id="composition") report["temporary_profile_copy_audit"] = copy_audit report["model_auth_binding"] = bound.copy_ephemeral_model_auth(temp_profile) provider_environment, environment_audit = bound.load_ephemeral_provider_environment(temp_profile) provider_secret_values = tuple(provider_environment.values()) report["model_auth_binding"]["environment_binding"] = environment_audit bridge = patch_composition_bridge( temp_profile, container=target_container_id, database=args.db, fixture=fixture ) report["temporary_bridge"] = bridge tool_log = Path(bridge["tool_log_path"]) args.tool_run_nonce = bridge["run_nonce"] extract_turn = await run_turn( args, temp_profile, phase="T1_extract_sources", prompt=prompts["extract"], provider_environment=provider_environment, tool_log=tool_log, ) lifecycle._require_gateway_turn(extract_turn) report["turns"]["T1_extract_sources"] = extract_turn packet = parse_prefixed_json(str(extract_turn["gateway"].get("reply") or ""), PACKET_PREFIX) report["packet_validation"] = validate_composition_packet(packet, fixture) guard_after_extraction = bound.database_guard_snapshot(target_container_id, args.db, tables=TABLES) report["target_guard_snapshot_after_extraction"] = guard_after_extraction if guard_after_extraction != target_guard_before: raise bound.CheckpointError("source extraction changed the clone before staging") agent_id = resolve_leo_agent_id(target_container_id, args.db) parent = build_parent_packet(packet, fixture, args.run_marker, agent_id) stage_result = normalized_stage.stage_normalized_child(args.container, args.db, parent) if stage_result["bound_container_id"] != target_container_id: raise bound.CheckpointError("normalized staging rebound to a different container identity") child = stage_result["child"] report["normalized_child"] = { "id": child["id"], "proposal_type": child["proposal_type"], "status": child["status"], "source_ref": child["source_ref"], "parent_packet_sha256": child["parent_packet_sha256"], "payload_sha256": child["payload_sha256"], "planned_row_ids": { "claims": [row["id"] for row in child["payload"]["apply_payload"]["claims"]], "sources": [row["id"] for row in child["payload"]["apply_payload"]["sources"]], }, } report["stage_receipt"] = stage_result["database_receipt"] expected_rows = guarded._expected_bundle_rows(child["payload"]["apply_payload"]) empty_rows = {key: [] for key in expected_rows} if ( guarded._exact_bundle_readback(target_container_id, args.db, child["payload"]["apply_payload"]) != empty_rows ): raise bound.CheckpointError("canonical rows appeared before review/apply") pending = guarded._proposal_readback(target_container_id, args.db, child["id"]) report["pending_readback"] = pending if not pending or not bound._state_semantics(pending, "pending_review")["all"]: raise bound.CheckpointError("normalized child was not exactly pending and unapplied") target_unrelated_before = unrelated_guard_snapshot(target_container_id, args.db, child) review_dry, review_apply = lifecycle.run_operator_review(args, child["id"]) approved = guarded._proposal_readback(target_container_id, args.db, child["id"]) approval_snapshot = guarded._approval_snapshot_readback(target_container_id, args.db, child["id"]) report["operator_review"] = { "dry_run": lifecycle._command_receipt(review_dry), "apply": lifecycle._command_receipt(review_apply), "approved_readback": approved, "approval_snapshot": approval_snapshot, } apply_dry, apply_execute = lifecycle.run_guarded_apply(args, child["id"]) applied = guarded._proposal_readback(target_container_id, args.db, child["id"]) approval_after = guarded._approval_snapshot_readback(target_container_id, args.db, child["id"]) final_rows = guarded._exact_bundle_readback(target_container_id, args.db, child["payload"]["apply_payload"]) report["guarded_apply"] = { "dry_run": lifecycle._command_receipt(apply_dry), "apply": lifecycle._command_receipt(apply_execute), "applied_readback": applied, "approval_snapshot_after_apply": approval_after, } report["final_canonical_rows"] = final_rows if not guarded._approval_transition_valid(pending, approved): raise bound.CheckpointError("operator review did not produce the exact approved transition") if not guarded._apply_transition_valid(approved, applied): raise bound.CheckpointError("guarded apply transition is invalid") if approval_snapshot != approval_after: raise bound.CheckpointError("apply changed the immutable approval snapshot") if final_rows != expected_rows: raise bound.CheckpointError("canonical source-derived rows differ from the reviewed payload") reason_turn = await run_turn( args, temp_profile, phase="T5_reason_after_restart", prompt=prompts["reason"], provider_environment=provider_environment, tool_log=tool_log, ) lifecycle._require_gateway_turn(reason_turn) report["turns"]["T5_reason_after_restart"] = reason_turn state = parse_prefixed_json(str(reason_turn["gateway"].get("reply") or ""), STATE_PREFIX) report["final_state_receipt"] = state report["final_state_matches_rows"] = _state_matches( state, conversation_marker=args.conversation_marker, child=child ) t1_child = extract_turn["gateway"].get("child_process") or {} t5_child = reason_turn["gateway"].get("child_process") or {} report["isolated_restart"] = { "prior_child_absent": t1_child.get("alive_after_readback") is False and t1_child.get("process_group_alive_after_readback") is False, "child_pid_changed": t1_child.get("pid") != t5_child.get("pid"), "same_session_key": bool(extract_turn["gateway"].get("session_key")) and extract_turn["gateway"].get("session_key") == reason_turn["gateway"].get("session_key"), "same_persisted_session_id": ( bool((extract_turn["gateway"].get("transcript_tool_trace") or {}).get("session_id")) and (extract_turn["gateway"].get("transcript_tool_trace") or {}).get("session_id") == (reason_turn["gateway"].get("transcript_tool_trace") or {}).get("session_id") ), } except Exception as exc: report["errors"].append({"type": type(exc).__name__, "message": str(exc)}) report["traceback_tail"] = traceback.format_exc().splitlines()[-16:] finally: provider_environment.clear() child_cleanup = bound.cleanup_active_gateway_children() try: if not tool_log or not bridge or not target_container_id or not target_guard_before: raise bound.CheckpointError("tool proof prerequisites were not established") tool_proof = bound.read_tool_proof( tool_log, target_container_id, args.db, run_nonce=bridge["run_nonce"], database_identity=target_guard_before["database_identity"], require_database_read_only=False, ) except Exception as exc: report["errors"].append({"type": type(exc).__name__, "message": f"tool proof: {exc}"}) tool_proof = { "invocations": [], "invocation_count": 0, "all_bound_to_supplied_target": False, "all_completed_successfully": False, } report["tool_proof"] = tool_proof temp_root = temp_profile.parent if temp_profile else None cleanup_clear = not bound._ACTIVE_GATEWAY_CHILDREN and all( not item.get("alive_after_cleanup") and not item.get("process_group_alive_after_cleanup") for item in child_cleanup.values() ) temp_removed = bound.remove_tree(temp_root) if cleanup_clear else False report["cleanup"] = { "active_gateway_child_cleanup": child_cleanup, "active_gateway_registry_clear": not bound._ACTIVE_GATEWAY_CHILDREN, "temp_profile_removed": temp_removed, "absence_verified_independently": bound.temp_path_absent(temp_root), "active_temp_root_registry_clear": (temp_root not in bound._ACTIVE_TEMP_ROOTS if temp_root else True), } target_guard_after = None target_identity_after = None target_unrelated_after = None if target_container_id: try: target_identity_after = bound.container_identity(args.container) if target_identity_after.get("id") != target_container_id: raise bound.CheckpointError("target name no longer resolves to the pinned identity") report.setdefault("target", {})["container_identity_after"] = target_identity_after target_guard_after = bound.database_guard_snapshot(target_container_id, args.db, tables=TABLES) report["target_guard_snapshot_after"] = target_guard_after if child and target_unrelated_before is not None: target_unrelated_after = unrelated_guard_snapshot(target_container_id, args.db, child) except Exception as exc: report["errors"].append({"type": type(exc).__name__, "message": f"target postflight: {exc}"}) production_guard_after = None production_gate_schema_after = None try: production_guard_after = bound.database_guard_snapshot( bound.PRODUCTION_CONTAINER, bound.PRODUCTION_DB, tables=PRODUCTION_TABLES ) production_gate_schema_after = gate_schema_manifest(bound.PRODUCTION_CONTAINER, bound.PRODUCTION_DB) except Exception as exc: report["errors"].append({"type": type(exc).__name__, "message": f"production postflight: {exc}"}) production_service_after = bound.service_state() live_bridge_after = bound.bridge_hashes() production = report.setdefault("production_invariants", {}) production.update( { "guard_snapshot_after": production_guard_after, "guard_snapshot_unchanged": production_guard_before is not None and production_guard_before == production_guard_after, "gate_schema_after": production_gate_schema_after, "gate_schema_unchanged": production_gate_schema_before is not None and production_gate_schema_before == production_gate_schema_after, "service_after": production_service_after, "service_unchanged": _service_unchanged(production_service_before, production_service_after), "live_bridge_hashes_after": live_bridge_after, "live_bridge_unchanged": live_bridge_before is not None and live_bridge_before == live_bridge_after, } ) turns = report.get("turns") or {} extraction = turns.get("T1_extract_sources") or {} reasoning = turns.get("T5_reason_after_restart") or {} gateways = [turn.get("gateway") or {} for turn in (extraction, reasoning)] merged_events = merge_transcript_events(gateways) terminal_consistency = terminal_trace_consistency(merged_events, tool_proof) report["merged_transcript_event_count"] = len(merged_events) report["terminal_trace_consistency"] = terminal_consistency expected_claim_ids = [row["id"] for row in child["payload"]["apply_payload"]["claims"]] if child else [] expected_source_ids = [row["id"] for row in child["payload"]["apply_payload"]["sources"]] if child else [] generated_row_ids = [ *expected_claim_ids, *expected_source_ids, *([child["id"]] if child else []), ] reply = str((reasoning.get("gateway") or {}).get("reply") or "").lower() transcript_calls = [ event.get("tool_name") for event in merged_events if event.get("phase") == "call" ] source_manifest_after = source_manifest() report["source_manifest_after"] = source_manifest_after checks = { "clone_base_rows_match_production_before_gate_use": base_snapshot_matches( report.get("target_base_guard_snapshot") or {}, production.get("guard_snapshot_before") or {}, ), "clone_only_gate_schema_ready": clone_gate_schema_ready(report.get("target_gate_schema") or {}), "source_packet_validated": bool(report.get("packet_validation")), "extraction_searched_existing_kb": _searched_recorded_dedupe_query(extraction, packet or {}), "extraction_changed_no_database_rows": report.get("target_guard_snapshot_after_extraction") == report.get("target_guard_snapshot_before"), "normalized_child_staged": child is not None and report.get("stage_receipt", {}).get("status") == "pending_review", "source_hashes_preserved": bool(child) and {fixture["document"]["content_sha256"], fixture["post"]["content_sha256"]} <= {row["hash"] for row in child["payload"]["apply_payload"]["sources"]}, "canonical_rows_match_reviewed_payload": bool(child) and report.get("final_canonical_rows") == guarded._expected_bundle_rows(child["payload"]["apply_payload"]), "immutable_approval_survived_apply": report.get("operator_review", {}).get("approval_snapshot") == report.get("guarded_apply", {}).get("approval_snapshot_after_apply"), "target_table_deltas_exact": bool(child and target_guard_before and target_guard_after) and lifecycle._table_deltas(target_guard_before["counts"], target_guard_after["counts"]) == expected_table_deltas(child), "target_database_identity_stable": bool(target_guard_before and target_guard_after) and target_guard_before.get("database_identity") == target_guard_after.get("database_identity"), "reasoning_searched_without_ids": _searched_semantically_without_ids(reasoning, generated_row_ids), "reasoning_searched_composed_proposal": _searched_composed_proposal(reasoning, fixture["project"]), "reasoning_read_exact_proposal": bool(child) and _read_exact_proposal(reasoning, child["id"]), "reasoning_read_every_composed_claim": bool(expected_claim_ids) and all(_read_claim_material(reasoning, claim_id) for claim_id in expected_claim_ids), "reasoning_read_every_claim_evidence": bool(expected_claim_ids) and all(_read_claim_evidence(reasoning, claim_id) for claim_id in expected_claim_ids), "reasoning_read_conflict_edges": bool(expected_claim_ids) and any(_read_claim_edges(reasoning, claim_id) for claim_id in expected_claim_ids), "reasoning_answered_cory_state_and_conflict": ("approved" in reply or "approval" in reply) and "applied" in reply and "canonical" in reply and "conflict" in reply, "final_state_receipt_matches_rows": report.get("final_state_matches_rows") is True, "isolated_restart_and_memory_survived": bool(report.get("isolated_restart")) and all(report.get("isolated_restart", {}).values()), "all_tool_calls_bound_and_successful": tool_proof.get("all_bound_to_supplied_target") is True and tool_proof.get("all_completed_successfully") is True, "terminal_results_complete_and_first_try": terminal_consistency.get("passes") is True, "all_gateway_children_clean": bool(gateways) and all( (gateway.get("child_process") or {}).get("readiness_verified") is True and (gateway.get("child_process") or {}).get("timed_out") is False and (gateway.get("child_process") or {}).get("exitcode") == 0 and (gateway.get("child_process") or {}).get("result_transport") == "private_temp_file" and ((gateway.get("child_process") or {}).get("termination") or {}).get("attempted") is False and (gateway.get("child_process") or {}).get("alive_after_readback") is False and (gateway.get("child_process") or {}).get("process_group_alive_after_readback") is False for gateway in gateways ), "gateway_tool_surfaces_are_read_only_and_no_send": bool(gateways) and all( set((gateway.get("tool_surface") or {}).get("actual_registry_tools") or []) == {"skills_list", "skill_view", "terminal"} and set((gateway.get("tool_surface") or {}).get("allowed_tools") or []) == {"skills_list", "skill_view", "terminal"} and (gateway.get("tool_surface") or {}).get("gateway_adapters_verified_mapping") is True and (gateway.get("tool_surface") or {}).get("gateway_adapter_count") == 0 and (gateway.get("tool_surface") or {}).get("send_message_tool_enabled") is False and (gateway.get("tool_surface") or {}).get("terminal_restricted_to_clone_wrapper") is True and (gateway.get("tool_surface") or {}).get("terminal_subprocess_inherits_provider_credentials") is False and gateway.get("model_free_fallback_used") is False for gateway in gateways ), "all_transcript_tool_calls_allowlisted": bool(transcript_calls) and all(name in {"skills_list", "skill_view", "terminal"} for name in transcript_calls), "target_name_still_pinned": bool(target_identity_before and target_identity_after) and target_identity_before == target_identity_after, "unrelated_clone_rows_unchanged": target_unrelated_before is not None and target_unrelated_before == target_unrelated_after, "production_database_unchanged": production.get("guard_snapshot_unchanged") is True, "production_gate_schema_unchanged": production.get("gate_schema_unchanged") is True, "production_service_unchanged": production.get("service_unchanged") is True, "live_bridge_unchanged": production.get("live_bridge_unchanged") is True, "checkpoint_source_files_unchanged": report.get("source_manifest_before") == source_manifest_after, "no_telegram_send": report.get("posted_to_telegram") is False and all(gateway.get("posted_to_telegram") is False for gateway in gateways), "temporary_profile_removed": report.get("cleanup", {}).get("temp_profile_removed") is True and report.get("cleanup", {}).get("absence_verified_independently") is True and report.get("cleanup", {}).get("active_gateway_registry_clear") is True and report.get("cleanup", {}).get("active_temp_root_registry_clear") is True, } report["checks"] = checks report["status"] = "pass" if not report["errors"] and all(checks.values()) else "fail" report["claim_ceiling"] = ( "A pass proves no-send source extraction, deterministic hash-bound normalization, clone-only guarded " "canonical apply, and restarted open-ended reasoning over the composed rows. It does not prove Telegram " "delivery, production mutation, scheduled identity recomposition, or semantic behavior beyond this case." ) report["completed_at_utc"] = bound.utc_now() report = bound.redact_value(report, secret_values=provider_secret_values) bound.write_report(args.output, report, secret_values=provider_secret_values) return report def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--container", required=True) parser.add_argument("--db", required=True) parser.add_argument("--output", required=True, type=Path) parser.add_argument("--run-marker", default=None) parser.add_argument("--conversation-marker", default=None) parser.add_argument("--chat-id", default=bound.DEFAULT_CHAT_ID) parser.add_argument("--user-id", default=bound.DEFAULT_USER_ID) parser.add_argument("--user-name", default="codex clone composition checkpoint") parser.add_argument("--turn-timeout", type=int, default=300) parser.add_argument("--review-secrets-file", default=lifecycle.DEFAULT_REVIEW_SECRETS_FILE) parser.add_argument("--apply-secrets-file", default=lifecycle.DEFAULT_APPLY_SECRETS_FILE) parser.add_argument("--copy-model-auth", action="store_true") parser.add_argument("--operator-review", action="store_true") parser.add_argument("--guarded-apply", action="store_true") args = parser.parse_args(argv) args.run_marker = args.run_marker or lifecycle.new_marker("leo-composition") args.conversation_marker = args.conversation_marker or lifecycle.new_marker("composition-memory") return args def main(argv: list[str] | None = None) -> int: args = parse_args(argv) try: with bound.termination_cleanup_handlers(): report = asyncio.run(run_checkpoint(args)) except bound.CheckpointError as exc: print(json.dumps({"status": "rejected", "error": str(exc)}, sort_keys=True)) return 2 print( json.dumps( { "status": report.get("status"), "output": str(args.output), "checks_passed": sum(bool(value) for value in report.get("checks", {}).values()), "checks_total": len(report.get("checks", {})), "error_count": len(report.get("errors", [])), }, sort_keys=True, ) ) return 0 if report.get("status") == "pass" else 1 if __name__ == "__main__": raise SystemExit(main())