Prove Leo KB composition and approved apply lifecycle

This commit is contained in:
twentyOne2x 2026-07-12 21:17:17 +02:00
parent bd5f1e5bc4
commit 3d5b0b75ef
9 changed files with 1752 additions and 455 deletions

View file

@ -0,0 +1,39 @@
{
"schema": "livingip.workingLeoDocumentIngestionFixture.v1",
"source": {
"identity": "document:working-leo-review-gated-composition-v1",
"source_key": "operating_document",
"source_type": "article",
"title": "Working Leo review-gated composition note",
"locator": "fixture://working-leo/document-ingestion-v1",
"body": "Working Leo composition note. A newly captured document may produce claim and evidence candidates, but those candidates are not canonical knowledge.\n\nA staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds. The proposal must retain the source content hash, exact evidence excerpt, and source identity so reviewers can trace every planned row back to the captured artifact.\n\nFor a staging-only rehearsal, pending_review is the terminal state. No public knowledge-base row should be written.",
"metadata": {
"author": "Working Leo canary fixture",
"captured_at": "2026-07-12T00:00:00Z",
"document_kind": "operating_note",
"language": "en"
}
},
"extraction": {
"claim": {
"claim_key": "staged_proposal_remains_noncanonical",
"type": "structural",
"confidence": 0.99,
"text": "A staged knowledge proposal remains non-canonical until review and guarded apply succeed.",
"body": "A staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds.",
"metadata": {
"extractor": "deterministic_fixture_replay",
"extraction_version": 1,
"needs_research": false
}
},
"evidence": {
"role": "grounds",
"body": "A staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds.",
"metadata": {
"evidence_kind": "exact_quote",
"section": "paragraph_2"
}
}
}
}

View file

@ -85,6 +85,7 @@ from __future__ import annotations
import argparse
import json
import shutil
import subprocess
import sys
import uuid
@ -857,8 +858,9 @@ def load_password(secrets_file: str) -> str:
def run_psql(args: argparse.Namespace, sql: str, password: str) -> str:
docker_binary = shutil.which("docker") or "docker"
command = [
"docker", "exec", "-e", "PGPASSWORD", "-i", args.container,
docker_binary, "exec", "-e", "PGPASSWORD", "-i", args.container,
"psql", "-U", args.role, "-h", args.host, "-d", args.db,
"-v", "ON_ERROR_STOP=1", "-At", "-q",
]

View file

@ -15,6 +15,7 @@ import argparse
import hashlib
import json
import re
import shutil
import subprocess
import sys
import uuid
@ -135,7 +136,7 @@ def _role_psql(
password: str,
) -> subprocess.CompletedProcess[str]:
command = [
"docker",
shutil.which("docker") or "docker",
"exec",
"-e",
"PGPASSWORD",
@ -213,26 +214,34 @@ def _schema_copy(container: str, source_db: str, clone_db: str) -> None:
def _service_state(service: str) -> dict[str, Any]:
result = _run(
[
"systemctl",
"show",
service,
"--no-pager",
"-p",
"ActiveState",
"-p",
"SubState",
"-p",
"MainPID",
"-p",
"NRestarts",
"-p",
"ExecMainStartTimestamp",
],
check=False,
)
state: dict[str, Any] = {"returncode": result.returncode}
command = [
"systemctl",
"show",
service,
"--no-pager",
"-p",
"ActiveState",
"-p",
"SubState",
"-p",
"MainPID",
"-p",
"NRestarts",
"-p",
"ExecMainStartTimestamp",
]
try:
result = _run(command, check=False)
except FileNotFoundError:
return {
"available": False,
"returncode": 127,
"reason": "systemctl_unavailable",
}
state: dict[str, Any] = {
"available": result.returncode == 0,
"returncode": result.returncode,
}
for line in result.stdout.splitlines():
key, separator, value = line.partition("=")
if separator:
@ -826,6 +835,108 @@ def _table_deltas(before: dict[str, int], after: dict[str, int]) -> dict[str, in
return {key: after[key] - before[key] for key in sorted(before)}
def _canonical_row_keys(rows: dict[str, list[dict[str, Any]]]) -> dict[str, Any]:
"""Return stable primary/composite keys for every canonical row in a bundle."""
return {
"public.claims": sorted(row["id"] for row in rows.get("claims", [])),
"public.sources": sorted(row["id"] for row in rows.get("sources", [])),
"public.claim_evidence": sorted(
[
{
"claim_id": row["claim_id"],
"source_id": row["source_id"],
"role": row["role"],
}
for row in rows.get("claim_evidence", [])
],
key=lambda row: (row["claim_id"], row["source_id"], row["role"]),
),
"public.claim_edges": sorted(
[
{
"from_claim": row["from_claim"],
"to_claim": row["to_claim"],
"edge_type": row["edge_type"],
}
for row in rows.get("claim_edges", [])
],
key=lambda row: (row["from_claim"], row["to_claim"], row["edge_type"]),
),
"public.reasoning_tools": sorted(
row["id"] for row in rows.get("reasoning_tools", [])
),
}
def _strict_receipt(
result: dict[str, Any],
expected_rows: dict[str, list[dict[str, Any]]],
expected_table_deltas: dict[str, int],
) -> dict[str, Any]:
"""Build the compact pass/fail surface from actual database readbacks."""
applied = result.get("apply_transition", {}).get("applied_readback") or {}
actual_rows = result.get("row_readback") or {}
expected_keys = _canonical_row_keys(expected_rows)
actual_keys = _canonical_row_keys(actual_rows)
checks = {
"proposal_id_exact": applied.get("id")
== result.get("fixture_ids", {}).get("proposal_id"),
"proposal_status_applied": applied.get("status") == "applied",
"proposal_applied_at_present": bool(applied.get("applied_at")),
"canonical_rows_exact": actual_rows == expected_rows,
"canonical_row_keys_exact": actual_keys == expected_keys,
"before_after_counts_present": (
isinstance(result.get("clone_counts_before_apply"), dict)
and isinstance(result.get("clone_counts_after_apply"), dict)
),
"table_deltas_exact": result.get("clone_apply_table_deltas")
== expected_table_deltas,
"conflict_transaction_rolled_back": result.get("checks", {}).get(
"conflict_transaction_rolled_back_exactly"
)
is True,
"clone_database_removed": (
result.get("clone_dropped") is True
and result.get("cleanup_readback", {}).get(
"leftover_clone_database_count"
)
== 0
),
"source_database_unchanged": result.get("source_database_mutated") is False,
}
return {
"schema": "working-leo.approved-change-strict-receipt.v1",
"pass": result.get("status") == "pass" and all(checks.values()),
"checks": checks,
"proposal": {
"id": applied.get("id"),
"status": applied.get("status"),
"applied_at": applied.get("applied_at"),
"applied_by_handle": applied.get("applied_by_handle"),
},
"canonical_row_keys": {
"expected": expected_keys,
"actual": actual_keys,
},
"row_counts": {
"before_apply": result.get("clone_counts_before_apply"),
"after_apply": result.get("clone_counts_after_apply"),
"expected_deltas": expected_table_deltas,
"actual_deltas": result.get("clone_apply_table_deltas"),
},
"rollback_cleanup": {
"conflict_transaction_rolled_back": checks[
"conflict_transaction_rolled_back"
],
"clone_database_removed": checks["clone_database_removed"],
"leftover_clone_database_count": result.get("cleanup_readback", {}).get(
"leftover_clone_database_count"
),
"source_database_unchanged": checks["source_database_unchanged"],
},
}
def _exact_bundle_readback(
container: str, database: str, payload: dict[str, Any]
) -> dict[str, list[dict[str, Any]]]:
@ -1905,6 +2016,18 @@ drop database if exists {clone_db};
f"{type(exc).__name__}: {exc}"
)
gateway_process_observable = (
result.get("service_before", {}).get("available") is True
and result.get("service_after", {}).get("available") is True
)
gateway_process_unchanged = (
result.get("service_before", {}).get("MainPID")
== result.get("service_after", {}).get("MainPID")
and result.get("service_before", {}).get("NRestarts")
== result.get("service_after", {}).get("NRestarts")
if gateway_process_observable
else None
)
result["checks"] = {
"security_definer_dependencies_ready": _security_dependencies_ready(
result.get("security_definer_readback") or {}
@ -2058,12 +2181,7 @@ drop database if exists {clone_db};
"source_files_unchanged_during_run": (
result.get("source_binding", {}).get("unchanged_during_run") is True
),
"gateway_process_unchanged": (
result.get("service_before", {}).get("MainPID")
== result.get("service_after", {}).get("MainPID")
and result.get("service_before", {}).get("NRestarts")
== result.get("service_after", {}).get("NRestarts")
),
"gateway_process_unchanged": gateway_process_unchanged,
"clone_cleanup_complete": (
result.get("clone_dropped") is True
and result.get("leftover_clone_count") == 0
@ -2072,9 +2190,11 @@ drop database if exists {clone_db};
result["source_counts_observed_unchanged"] = (
result.get("source_counts_before") == result.get("source_counts_after")
)
result["gateway_process_observable"] = gateway_process_observable
result["status"] = (
"pass"
if all(result["checks"].values()) and "error" not in result
if all(value is True for value in result["checks"].values() if value is not None)
and "error" not in result
else "fail"
)
result["source_database_mutated"] = not all(
@ -2085,16 +2205,24 @@ drop database if exists {clone_db};
"source_table_deltas_exactly_zero",
)
)
result["service_restarted"] = not result["checks"][
"gateway_process_unchanged"
]
result["service_restarted"] = (
None
if gateway_process_unchanged is None
else not gateway_process_unchanged
)
result["post_run_cleanup"] = {
"leftover_clone_database_count": result.get("leftover_clone_count"),
"gateway_process_observable": gateway_process_observable,
"gateway_active_state": result.get("service_after", {}).get("ActiveState"),
"gateway_sub_state": result.get("service_after", {}).get("SubState"),
"gateway_main_pid": result.get("service_after", {}).get("MainPID"),
"gateway_restart_count": result.get("service_after", {}).get("NRestarts"),
}
result["strict_receipt"] = _strict_receipt(
result, expected_rows, expected_table_deltas
)
if not result["strict_receipt"]["pass"]:
result["status"] = "fail"
return result

View file

@ -6,6 +6,7 @@ source_container="${SOURCE_CONTAINER:-teleo-pg}"
source_db="${SOURCE_DB:-teleo}"
service="${LEO_SERVICE:-leoclean-gateway.service}"
image="${POSTGRES_CANARY_IMAGE:-postgres:16}"
source_tier="${SOURCE_TIER:-live-readonly}"
normalization_json=""
output="${repo_root}/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json"
@ -31,6 +32,10 @@ while [[ $# -gt 0 ]]; do
service="$2"
shift 2
;;
--source-tier)
source_tier="$2"
shift 2
;;
*)
echo "unknown argument: $1" >&2
exit 2
@ -38,6 +43,22 @@ while [[ $# -gt 0 ]]; do
esac
done
if [[ "$source_tier" != "isolated-local" && "$source_tier" != "live-readonly" ]]; then
echo "--source-tier must be isolated-local or live-readonly" >&2
exit 2
fi
source_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$source_container")"
source_canary_label="$(
docker inspect -f '{{index .Config.Labels "livingip.canary"}}' "$source_container"
)"
if [[ "$source_tier" == "isolated-local" ]]; then
if [[ "$source_network_mode" != "none" || "$source_canary_label" != "working-leo-approved-source" ]]; then
echo "isolated-local source must be networkless and labeled livingip.canary=working-leo-approved-source" >&2
exit 2
fi
fi
container="working-leo-approve-claim-$RANDOM-$$"
workdir="/tmp/${container}"
apply_password="isolated-apply-${RANDOM}-${RANDOM}"
@ -64,8 +85,17 @@ source_counts() {
}
service_state() {
systemctl show "$service" --no-pager \
-p ActiveState -p SubState -p MainPID -p NRestarts -p ExecMainStartTimestamp
if ! command -v systemctl >/dev/null 2>&1; then
printf 'Available=false\nReason=systemctl_unavailable\n'
return 0
fi
local output
if output="$(systemctl show "$service" --no-pager \
-p ActiveState -p SubState -p MainPID -p NRestarts -p ExecMainStartTimestamp 2>&1)"; then
printf 'Available=true\n%s\n' "$output"
else
printf 'Available=false\nReason=service_readback_failed\n'
fi
}
mkdir -p "$workdir" "$(dirname "$output")"
@ -73,17 +103,30 @@ source_counts_before="$(source_counts)"
service_before="$(service_state)"
docker run -d --name "$container" \
--network none \
--tmpfs /var/lib/postgresql/data:rw,nosuid,size=512m \
-e POSTGRES_PASSWORD="isolated-postgres-${RANDOM}-${RANDOM}" \
-e POSTGRES_DB=teleo \
"$image" >/dev/null
for _ in $(seq 1 40); do
ready_streak=0
for _ in $(seq 1 80); do
if docker exec "$container" pg_isready -U postgres -d teleo >/dev/null 2>&1; then
break
ready_streak=$((ready_streak + 1))
if [[ "$ready_streak" -ge 2 ]]; then
break
fi
else
ready_streak=0
fi
sleep 0.25
done
docker exec "$container" pg_isready -U postgres -d teleo >/dev/null
if [[ "$ready_streak" -lt 2 ]]; then
echo "disposable Postgres did not become stably ready" >&2
exit 1
fi
container_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$container")"
container_mounts_json="$(docker inspect -f '{{json .Mounts}}' "$container")"
docker exec "$source_container" pg_dump -U postgres -d "$source_db" \
--schema-only --no-owner --no-privileges >"$workdir/schema.sql"
@ -173,6 +216,11 @@ CONTAINER_NAME_READBACK="$container_name_readback" \
CONTAINER_NAME_READBACK_RC="$container_name_readback_rc" \
OUTER_WORKDIR_LEXISTS="$outer_workdir_lexists" \
CANARY_RC="$canary_rc" \
SOURCE_TIER="$source_tier" \
SOURCE_NETWORK_MODE="$source_network_mode" \
SOURCE_CANARY_LABEL="$source_canary_label" \
CANARY_NETWORK_MODE="$container_network_mode" \
CANARY_MOUNTS_JSON="$container_mounts_json" \
python3 - "$output" <<'PY'
import hashlib
import json
@ -254,9 +302,40 @@ after_counts = json.loads(os.environ["SOURCE_COUNTS_AFTER"])
live_table_deltas = table_deltas(before_counts, after_counts)
before_service = service(os.environ["SERVICE_BEFORE"])
after_service = service(os.environ["SERVICE_AFTER"])
service_stable = all(
before_service.get(key) == after_service.get(key)
for key in ("ActiveState", "SubState", "MainPID", "NRestarts")
source_tier = os.environ["SOURCE_TIER"]
source_network_mode = os.environ["SOURCE_NETWORK_MODE"]
source_canary_label = os.environ["SOURCE_CANARY_LABEL"]
container_network_mode = os.environ["CANARY_NETWORK_MODE"]
container_mounts = json.loads(os.environ["CANARY_MOUNTS_JSON"])
container_volume_mounts = [
mount for mount in container_mounts if mount.get("Type") == "volume"
]
container_isolated = (
container_network_mode == "none" and not container_volume_mounts
)
source_tier_enforced = (
source_tier != "isolated-local"
or (
source_network_mode == "none"
and source_canary_label == "working-leo-approved-source"
)
)
service_observable = (
before_service.get("Available") == "true"
and after_service.get("Available") == "true"
)
service_stable = (
all(
before_service.get(key) == after_service.get(key)
for key in ("ActiveState", "SubState", "MainPID", "NRestarts")
)
if service_observable
else None
)
service_gate_passes = (
service_stable is True
if source_tier == "live-readonly"
else service_stable is not False
)
container_absent = (
int(os.environ["CONTAINER_NAME_READBACK_RC"]) == 0
@ -277,15 +356,22 @@ inner_runtime_pass = data.get("status") == "pass" and int(os.environ["CANARY_RC"
outer_ok = (
before_counts == after_counts
and all(delta == 0 for delta in live_table_deltas.values())
and service_stable
and service_gate_passes
and container_absent
and workdir_absent
and source_binding_ok
and stale_ephemeral_paths_absent
and container_isolated
and source_tier_enforced
)
data["required_tier"] = "T3_live_readonly"
data["required_tiers"] = ["T2_runtime", "T3_live_readonly"]
data["runtime_scope"] = "isolated_postgres_container_from_readonly_live_schema"
if source_tier == "isolated-local":
data["required_tier"] = "T2_runtime"
data["required_tiers"] = ["T2_runtime"]
data["runtime_scope"] = "isolated_postgres_container_from_readonly_local_fixture"
else:
data["required_tier"] = "T3_live_readonly"
data["required_tiers"] = ["T2_runtime", "T3_live_readonly"]
data["runtime_scope"] = "isolated_postgres_container_from_readonly_live_schema"
data["outer_isolation"] = {
"source_container": os.environ.get("SOURCE_CONTAINER", "teleo-pg"),
"source_database": os.environ.get("SOURCE_DB", "teleo"),
@ -295,7 +381,22 @@ data["outer_isolation"] = {
"source_counts_unchanged": before_counts == after_counts,
"service_before": before_service,
"service_after": after_service,
"service_required": source_tier == "live-readonly",
"service_observable": service_observable,
"service_stable": service_stable,
"service_gate_passes": service_gate_passes,
"source_boundary": {
"source_tier": source_tier,
"network_mode": source_network_mode,
"canary_label": source_canary_label,
"tier_enforced": source_tier_enforced,
},
"container_isolation": {
"network_mode": container_network_mode,
"volume_mounts": container_volume_mounts,
"network_disabled": container_network_mode == "none",
"no_docker_volumes": not container_volume_mounts,
},
"cleanup_readback": {
"container_remove_returncode": int(os.environ["OUTER_CONTAINER_REMOVE_RC"]),
"container_name_query_returncode": int(
@ -312,14 +413,24 @@ data["checks"]["outer_live_counts_exactly_unchanged"] = before_counts == after_c
data["checks"]["outer_live_table_deltas_exactly_zero"] = all(
delta == 0 for delta in live_table_deltas.values()
)
data["checks"]["outer_service_stable"] = service_stable
data["checks"]["outer_service_observed_if_required"] = (
source_tier != "live-readonly" or service_observable
)
data["checks"]["outer_service_stable_if_observed"] = service_gate_passes
data["checks"]["outer_container_absent_independent_readback"] = container_absent
data["checks"]["outer_workdir_absent_independent_readback"] = workdir_absent
data["checks"]["source_binding_independently_verified"] = source_binding_ok
data["checks"]["stale_ephemeral_paths_absent"] = stale_ephemeral_paths_absent
data["checks"]["outer_source_tier_enforced"] = source_tier_enforced
data["checks"]["outer_container_network_disabled"] = (
container_network_mode == "none"
)
data["checks"]["outer_container_has_no_docker_volumes"] = not container_volume_mounts
data["checks"]["outer_isolation_complete"] = outer_ok
if outer_ok and inner_runtime_pass:
data["current_tier"] = "T3_live_readonly"
data["current_tier"] = (
"T2_runtime" if source_tier == "isolated-local" else "T3_live_readonly"
)
else:
data["status"] = "fail"
data["current_tier"] = "T2_runtime" if inner_runtime_pass else "T1_model"

View file

@ -0,0 +1,519 @@
#!/usr/bin/env python3
"""Run a document-ingestion-to-staged-proposal canary in disposable local Postgres."""
from __future__ import annotations
import argparse
import hashlib
import json
import shutil
import subprocess
import sys
import time
import uuid
from pathlib import Path
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 stage_normalized_proposal as normalized_stage # noqa: E402
SCHEMA = "livingip.workingLeoLocalIngestionProposalCanary.v1"
FIXTURE_SCHEMA = "livingip.workingLeoDocumentIngestionFixture.v1"
DEFAULT_FIXTURE = REPO_ROOT / "fixtures" / "working-leo" / "document-ingestion-v1.json"
CONTAINER_LABEL = "livingip.canary=working-leo-local-ingestion"
class CanaryError(RuntimeError):
pass
def sha256_bytes(value: bytes) -> str:
return hashlib.sha256(value).hexdigest()
def canonical_sha256(value: Any) -> str:
return sha256_bytes(json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=True).encode())
def stable_uuid(artifact_sha256: str, label: str) -> str:
return str(uuid.uuid5(uuid.NAMESPACE_URL, f"livingip:working-leo-ingestion:{artifact_sha256}:{label}"))
def load_fixture(path: Path) -> tuple[dict[str, Any], dict[str, Any]]:
raw = path.read_bytes()
try:
fixture = json.loads(raw)
except json.JSONDecodeError as exc:
raise CanaryError(f"fixture is not valid JSON: {exc}") from exc
if not isinstance(fixture, dict) or fixture.get("schema") != FIXTURE_SCHEMA:
raise CanaryError(f"fixture schema must be {FIXTURE_SCHEMA}")
source = fixture.get("source")
extraction = fixture.get("extraction")
claim = extraction.get("claim") if isinstance(extraction, dict) else None
evidence = extraction.get("evidence") if isinstance(extraction, dict) else None
if not all(isinstance(item, dict) for item in (source, claim, evidence)):
raise CanaryError("fixture requires source, extraction.claim, and extraction.evidence objects")
required_source = ("identity", "source_key", "source_type", "title", "locator", "body", "metadata")
required_claim = ("claim_key", "type", "confidence", "text", "body", "metadata")
required_evidence = ("role", "body", "metadata")
for label, value, required in (
("source", source, required_source),
("claim", claim, required_claim),
("evidence", evidence, required_evidence),
):
missing = [key for key in required if value.get(key) in (None, "")]
if missing:
raise CanaryError(f"fixture {label} is missing: {', '.join(missing)}")
if not isinstance(value.get("metadata"), dict):
raise CanaryError(f"fixture {label}.metadata must be an object")
if claim["body"] not in source["body"]:
raise CanaryError("extracted claim body must be an exact substring of source.body")
if evidence["body"] not in source["body"]:
raise CanaryError("extracted evidence body must be an exact substring of source.body")
artifact_sha256 = sha256_bytes(raw)
source_content_sha256 = sha256_bytes(source["body"].encode())
return fixture, {
"path": str(path.resolve()),
"artifact_sha256": artifact_sha256,
"source_content_sha256": source_content_sha256,
"source_identity": source["identity"],
}
def build_row_ids(artifact_sha256: str) -> dict[str, str]:
return {
"source_capture_id": stable_uuid(artifact_sha256, "source-capture"),
"claim_extraction_id": stable_uuid(artifact_sha256, "claim-extraction"),
"evidence_extraction_id": stable_uuid(artifact_sha256, "evidence-extraction"),
"parent_proposal_id": stable_uuid(artifact_sha256, "rich-parent-proposal"),
}
def build_parent_packet(
fixture: dict[str, Any], input_receipt: dict[str, Any], row_ids: dict[str, str]
) -> dict[str, Any]:
source = fixture["source"]
claim = fixture["extraction"]["claim"]
evidence = fixture["extraction"]["evidence"]
parent_source_ref = (
f"local-ingestion:{input_receipt['artifact_sha256']}:"
f"source={row_ids['source_capture_id']}:claim={row_ids['claim_extraction_id']}:"
f"evidence={row_ids['evidence_extraction_id']}"
)
return {
"id": row_ids["parent_proposal_id"],
"proposal_type": "attach_evidence",
"status": "pending_review",
"proposed_by_handle": "leo",
"proposed_by_agent_id": None,
"channel": "local_ingestion_canary",
"source_ref": parent_source_ref,
"rationale": "Stage one hash-bound claim/evidence extraction from a captured local document fixture.",
"payload": {
"claim_candidates": [
{
"claim_key": claim["claim_key"],
"type": claim["type"],
"confidence": claim["confidence"],
"text": claim["text"],
"body": claim["body"],
"evidence_tier": "isolated_fixture",
"needs_research": claim["metadata"].get("needs_research", False),
"evidence": [{"source_key": source["source_key"], "role": evidence["role"]}],
"edges": [],
}
],
"source_candidates": [
{
"source_key": source["source_key"],
"source_type": source["source_type"],
"title": source["title"],
"storage_path": input_receipt["path"],
"url": None,
"source_quality": "local realistic ingestion fixture",
"key_excerpt": evidence["body"],
"content_sha256": input_receipt["source_content_sha256"],
}
],
"dedupe_conflict_assessment": {
"database_search_query": claim["claim_key"].replace("_", " "),
"potential_existing_claim_ids": [],
"conflicts": [],
},
},
}
def build_schema_sql() -> str:
return r"""\set ON_ERROR_STOP on
create schema kb_canary;
create schema kb_stage;
create table kb_canary.source_captures (
id uuid primary key,
source_identity text not null unique,
source_type text not null,
title text not null,
locator text not null,
artifact_path text not null,
artifact_sha256 text not null check (artifact_sha256 ~ '^[0-9a-f]{64}$'),
content_sha256 text not null check (content_sha256 ~ '^[0-9a-f]{64}$'),
body text not null,
metadata jsonb not null
);
create table kb_canary.claim_extractions (
id uuid primary key,
source_capture_id uuid not null references kb_canary.source_captures(id),
claim_key text not null,
body text not null,
metadata jsonb not null
);
create table kb_canary.evidence_extractions (
id uuid primary key,
claim_extraction_id uuid not null references kb_canary.claim_extractions(id),
source_capture_id uuid not null references kb_canary.source_captures(id),
role text not null,
body text not null,
metadata jsonb not null
);
create table kb_stage.kb_proposals (
id uuid primary key,
proposal_type text not null,
status text not null,
proposed_by_handle text,
proposed_by_agent_id uuid,
channel text not null,
source_ref text not null,
rationale text not null,
payload jsonb not null,
reviewed_by_handle text,
reviewed_by_agent_id uuid,
reviewed_at timestamptz,
review_note text,
applied_by_handle text,
applied_by_agent_id uuid,
applied_at timestamptz
);
"""
def build_capture_sql(fixture: dict[str, Any], input_receipt: dict[str, Any], row_ids: dict[str, str]) -> str:
source = fixture["source"]
claim = fixture["extraction"]["claim"]
evidence = fixture["extraction"]["evidence"]
q = ap.sql_literal
claim_metadata = {
**claim["metadata"],
"claim_type": claim["type"],
"confidence": claim["confidence"],
"text": claim["text"],
}
return rf"""\set ON_ERROR_STOP on
begin;
insert into kb_canary.source_captures
(id, source_identity, source_type, title, locator, artifact_path,
artifact_sha256, content_sha256, body, metadata)
values
({q(row_ids["source_capture_id"])}::uuid, {q(source["identity"])}, {q(source["source_type"])},
{q(source["title"])}, {q(source["locator"])}, {q(input_receipt["path"])},
{q(input_receipt["artifact_sha256"])}, {q(input_receipt["source_content_sha256"])},
{q(source["body"])}, {q(json.dumps(source["metadata"], sort_keys=True))}::jsonb);
insert into kb_canary.claim_extractions
(id, source_capture_id, claim_key, body, metadata)
values
({q(row_ids["claim_extraction_id"])}::uuid, {q(row_ids["source_capture_id"])}::uuid,
{q(claim["claim_key"])}, {q(claim["body"])}, {q(json.dumps(claim_metadata, sort_keys=True))}::jsonb);
insert into kb_canary.evidence_extractions
(id, claim_extraction_id, source_capture_id, role, body, metadata)
values
({q(row_ids["evidence_extraction_id"])}::uuid, {q(row_ids["claim_extraction_id"])}::uuid,
{q(row_ids["source_capture_id"])}::uuid, {q(evidence["role"])}, {q(evidence["body"])},
{q(json.dumps(evidence["metadata"], sort_keys=True))}::jsonb);
commit;
"""
def build_readback_sql(row_ids: dict[str, str], proposal_id: str) -> str:
q = ap.sql_literal
return rf"""\set ON_ERROR_STOP on
begin transaction read only;
select jsonb_build_object(
'source_capture', (select to_jsonb(s) from kb_canary.source_captures s
where id = {q(row_ids["source_capture_id"])}::uuid),
'claim_extraction', (select to_jsonb(c) from kb_canary.claim_extractions c
where id = {q(row_ids["claim_extraction_id"])}::uuid),
'evidence_extraction', (select to_jsonb(e) from kb_canary.evidence_extractions e
where id = {q(row_ids["evidence_extraction_id"])}::uuid),
'staged_proposal', (select to_jsonb(p) from kb_stage.kb_proposals p
where id = {q(proposal_id)}::uuid),
'counts', jsonb_build_object(
'source_captures', (select count(*) from kb_canary.source_captures),
'claim_extractions', (select count(*) from kb_canary.claim_extractions),
'evidence_extractions', (select count(*) from kb_canary.evidence_extractions),
'staged_proposals', (select count(*) from kb_stage.kb_proposals)
)
)::text;
rollback;
"""
class DockerPostgres:
def __init__(self, name: str) -> None:
self.name = name
self.docker = shutil.which("docker")
if not self.docker:
raise CanaryError("docker executable is unavailable")
self.started = False
self.volume_mounts: list[dict[str, Any]] = []
def _run(
self, args: list[str], *, input_text: str | None = None, check: bool = True
) -> subprocess.CompletedProcess[str]:
result = subprocess.run([self.docker, *args], input=input_text, text=True, capture_output=True, check=False)
if check and result.returncode != 0:
detail = (result.stderr or result.stdout).strip()
raise CanaryError(f"docker {' '.join(args[:3])} failed ({result.returncode}): {detail}")
return result
def start(self) -> dict[str, Any]:
result = self._run(
[
"run",
"--rm",
"-d",
"--name",
self.name,
"--network",
"none",
"--label",
CONTAINER_LABEL,
"--tmpfs",
"/var/lib/postgresql/data:rw,nosuid,size=256m",
"-e",
"POSTGRES_HOST_AUTH_METHOD=trust",
"-e",
"POSTGRES_DB=teleo",
"postgres:16-alpine",
]
)
self.started = True
container_id = result.stdout.strip()
deadline = time.monotonic() + 30
ready_streak = 0
while time.monotonic() < deadline:
ready = self._run(["exec", self.name, "pg_isready", "-U", "postgres", "-d", "teleo"], check=False)
if ready.returncode == 0:
ready_streak += 1
if ready_streak >= 2:
break
else:
ready_streak = 0
time.sleep(0.25)
else:
raise CanaryError("disposable Postgres did not become ready within 30 seconds")
inspect = json.loads(self._run(["inspect", self.name]).stdout)[0]
if inspect["HostConfig"]["NetworkMode"] != "none":
raise CanaryError("disposable Postgres must use network mode none")
if inspect["Config"]["Labels"].get("livingip.canary") != "working-leo-local-ingestion":
raise CanaryError("disposable Postgres is missing its canary label")
self.volume_mounts = [
{
"type": mount.get("Type"),
"name": mount.get("Name"),
"destination": mount.get("Destination"),
}
for mount in inspect.get("Mounts", [])
if mount.get("Type") == "volume"
]
if self.volume_mounts:
raise CanaryError("disposable Postgres unexpectedly created a Docker volume")
return {
"container_id": container_id,
"name": self.name,
"image": inspect["Config"]["Image"],
"network_mode": inspect["HostConfig"]["NetworkMode"],
"tmpfs_data_dir": "/var/lib/postgresql/data" in inspect["HostConfig"].get("Tmpfs", {}),
"docker_volume_mounts": self.volume_mounts,
"canary_label": inspect["Config"]["Labels"].get("livingip.canary"),
}
def psql(self, sql: str) -> str:
result = self._run(
["exec", "-i", self.name, "psql", "-U", "postgres", "-d", "teleo", "-Atq"],
input_text=sql,
)
return result.stdout.strip()
def psql_json(self, sql: str) -> dict[str, Any]:
output = self.psql(sql)
lines = [line for line in output.splitlines() if line.strip()]
if not lines:
raise CanaryError("Postgres readback returned no JSON")
try:
value = json.loads(lines[-1])
except json.JSONDecodeError as exc:
raise CanaryError(f"Postgres readback was not JSON: {lines[-1]}") from exc
if not isinstance(value, dict):
raise CanaryError("Postgres readback must be a JSON object")
return value
def cleanup(self) -> dict[str, Any]:
remove = self._run(["rm", "-f", self.name], check=False) if self.started else None
inspect = self._run(["inspect", self.name], check=False)
return {
"remove_attempted": self.started,
"remove_returncode": remove.returncode if remove else None,
"container_absent": inspect.returncode != 0,
"docker_volume_mounts_observed": self.volume_mounts,
"anonymous_or_named_volume_created": bool(self.volume_mounts),
}
def proposal_links(readback: dict[str, Any], input_receipt: dict[str, Any]) -> dict[str, Any]:
proposal = readback["staged_proposal"]
apply_payload = proposal["payload"]["apply_payload"]
source_rows = apply_payload["sources"]
evidence_rows = apply_payload["evidence"]
return {
"proposal_id": proposal["id"],
"proposal_status": proposal["status"],
"proposal_source_ref": proposal["source_ref"],
"planned_claim_ids": [row["id"] for row in apply_payload["claims"]],
"planned_source_ids": [row["id"] for row in source_rows],
"planned_evidence_keys": [
{"claim_id": row["claim_id"], "source_id": row["source_id"], "role": row["role"]} for row in evidence_rows
],
"source_content_hash_matches": any(
row.get("hash") == input_receipt["source_content_sha256"] for row in source_rows
),
"parent_source_ref_embedded": any(
readback["source_capture"]["artifact_sha256"] in str(row.get("excerpt"))
and readback["source_capture"]["id"] in str(row.get("excerpt"))
and readback["claim_extraction"]["id"] in str(row.get("excerpt"))
and readback["evidence_extraction"]["id"] in str(row.get("excerpt"))
for row in source_rows
),
}
def evaluate_checks(
fixture: dict[str, Any], input_receipt: dict[str, Any], row_ids: dict[str, str], readback: dict[str, Any]
) -> dict[str, bool]:
source = readback.get("source_capture") or {}
claim = readback.get("claim_extraction") or {}
evidence = readback.get("evidence_extraction") or {}
proposal = readback.get("staged_proposal") or {}
links = proposal_links(readback, input_receipt)
return {
"input_artifact_hash_persisted": source.get("artifact_sha256") == input_receipt["artifact_sha256"],
"source_content_hash_persisted": source.get("content_sha256") == input_receipt["source_content_sha256"],
"source_identity_persisted": source.get("source_identity") == input_receipt["source_identity"],
"claim_links_to_source_capture": claim.get("source_capture_id") == row_ids["source_capture_id"],
"claim_body_and_metadata_persisted": (
claim.get("body") == fixture["extraction"]["claim"]["body"]
and claim.get("metadata", {}).get("text") == fixture["extraction"]["claim"]["text"]
),
"evidence_links_to_claim_and_source": (
evidence.get("claim_extraction_id") == row_ids["claim_extraction_id"]
and evidence.get("source_capture_id") == row_ids["source_capture_id"]
),
"evidence_body_and_metadata_persisted": (
evidence.get("body") == fixture["extraction"]["evidence"]["body"]
and evidence.get("metadata") == fixture["extraction"]["evidence"]["metadata"]
),
"one_row_per_ingestion_stage": readback.get("counts")
== {"source_captures": 1, "claim_extractions": 1, "evidence_extractions": 1, "staged_proposals": 1},
"proposal_is_pending_review": proposal.get("status") == "pending_review",
"proposal_has_source_ref": bool(proposal.get("source_ref")),
"proposal_payload_contains_input_hash": links["source_content_hash_matches"],
"proposal_payload_contains_capture_row_linkage": links["parent_source_ref_embedded"],
"no_review_or_apply_metadata": all(
proposal.get(key) is None
for key in ("reviewed_by_handle", "reviewed_at", "applied_by_handle", "applied_at")
),
}
def run_canary(fixture_path: Path, output: Path | None = None) -> dict[str, Any]:
fixture, input_receipt = load_fixture(fixture_path)
row_ids = build_row_ids(input_receipt["artifact_sha256"])
parent = build_parent_packet(fixture, input_receipt, row_ids)
child = normalized_stage.prepare_normalized_child(parent)
container_name = f"working-leo-ingest-{uuid.uuid4().hex[:12]}"
postgres = DockerPostgres(container_name)
receipt: dict[str, Any] = {
"schema": SCHEMA,
"status": "fail",
"required_tier": "isolated_realistic_ingestion_to_proposal",
"input": input_receipt,
"row_ids": row_ids,
"production_mutation_attempted": False,
"canonical_apply_attempted": False,
}
try:
receipt["environment"] = postgres.start()
postgres.psql(build_schema_sql())
postgres.psql(build_capture_sql(fixture, input_receipt, row_ids))
stage_result = postgres.psql_json(normalized_stage.build_stage_sql(child))
readback = postgres.psql_json(build_readback_sql(row_ids, child["id"]))
checks = evaluate_checks(fixture, input_receipt, row_ids, readback)
receipt.update(
{
"stage_command_result": stage_result,
"rows": readback,
"row_link_fields_proven": proposal_links(readback, input_receipt),
"checks": checks,
"status": "pass" if all(checks.values()) else "fail",
}
)
except (CanaryError, OSError, ValueError, KeyError) as exc:
receipt["error"] = {"type": type(exc).__name__, "message": str(exc)}
finally:
receipt["cleanup"] = postgres.cleanup()
receipt["cleanup"]["network_mode_none"] = (
receipt.get("environment", {}).get("network_mode") == "none"
)
receipt["cleanup"]["no_production_target_referenced"] = receipt[
"cleanup"
]["network_mode_none"]
if not all(
(
receipt["cleanup"]["container_absent"],
receipt["cleanup"]["network_mode_none"],
)
):
receipt["status"] = "fail"
receipt["strongest_claim"] = (
"A realistic local document fixture was hash-captured, replayed through deterministic claim/evidence "
"extraction, normalized by the existing rich-proposal normalizer, and staged/read back as one "
"pending_review proposal in disposable networkless Postgres."
)
receipt["residual_gap"] = (
"This does not prove live generative extraction, arbitrary document coverage, canonical apply, or any "
"hosted/production runtime."
)
if output:
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8")
return receipt
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--fixture", type=Path, default=DEFAULT_FIXTURE)
parser.add_argument("--output", type=Path)
return parser.parse_args(argv)
def main(argv: list[str] | None = None) -> int:
args = parse_args(argv)
receipt = run_canary(args.fixture.resolve(), args.output.resolve() if args.output else None)
print(json.dumps(receipt, sort_keys=True, separators=(",", ":")))
return 0 if receipt["status"] == "pass" else 1
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,79 @@
"""Focused tests for the strict approved-change clone receipt."""
from __future__ import annotations
import sys
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
import run_approve_claim_clone_canary as canary # noqa: E402
def _passing_result(expected_rows: dict, expected_deltas: dict) -> dict:
proposal_id = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"
return {
"status": "pass",
"fixture_ids": {"proposal_id": proposal_id},
"apply_transition": {
"applied_readback": {
"id": proposal_id,
"status": "applied",
"applied_at": "2026-07-12 12:00:00+00",
"applied_by_handle": "kb-apply",
}
},
"row_readback": expected_rows,
"clone_counts_before_apply": {key: 0 for key in expected_deltas},
"clone_counts_after_apply": expected_deltas,
"clone_apply_table_deltas": expected_deltas,
"clone_dropped": True,
"cleanup_readback": {"leftover_clone_database_count": 0},
"source_database_mutated": False,
"checks": {"conflict_transaction_rolled_back_exactly": True},
}
def test_service_state_records_unavailable_systemctl(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(
canary,
"_run",
lambda *_args, **_kwargs: (_ for _ in ()).throw(FileNotFoundError()),
)
assert canary._service_state("unused.service") == {
"available": False,
"returncode": 127,
"reason": "systemctl_unavailable",
}
def test_strict_receipt_requires_exact_ids_counts_applied_at_and_cleanup() -> None:
expected_rows = canary._expected_bundle_rows(canary.build_fixture("unit")["apply_payload"])
expected_deltas = canary._expected_table_deltas(expected_rows)
result = _passing_result(expected_rows, expected_deltas)
receipt = canary._strict_receipt(result, expected_rows, expected_deltas)
assert receipt["pass"] is True
assert receipt["proposal"]["status"] == "applied"
assert receipt["proposal"]["applied_at"]
assert receipt["canonical_row_keys"]["actual"] == receipt["canonical_row_keys"]["expected"]
assert receipt["row_counts"]["actual_deltas"] == expected_deltas
assert receipt["rollback_cleanup"]["clone_database_removed"] is True
result["apply_transition"]["applied_readback"]["applied_at"] = None
result["row_readback"] = {**expected_rows, "claims": []}
result["clone_apply_table_deltas"] = {**expected_deltas, "public.claims": 0}
result["clone_dropped"] = False
failed = canary._strict_receipt(result, expected_rows, expected_deltas)
assert failed["pass"] is False
assert failed["checks"]["proposal_applied_at_present"] is False
assert failed["checks"]["canonical_row_keys_exact"] is False
assert failed["checks"]["table_deltas_exact"] is False
assert failed["checks"]["clone_database_removed"] is False

View file

@ -0,0 +1,102 @@
"""Platform-path regression tests for the approved-change clone canary."""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
WRAPPER = ROOT / "scripts" / "run_approve_claim_isolated_container_canary.sh"
import apply_proposal as apply # noqa: E402
import run_approve_claim_clone_canary as canary # noqa: E402
def test_role_psql_resolves_docker_before_scrubbing_path(
monkeypatch: pytest.MonkeyPatch,
) -> None:
captured: dict[str, object] = {}
monkeypatch.setattr(
canary.shutil,
"which",
lambda executable: "/opt/homebrew/bin/docker"
if executable == "docker"
else None,
)
def fake_run(command: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]:
captured["command"] = command
captured["env"] = kwargs["env"]
return subprocess.CompletedProcess(command, 0, "", "")
monkeypatch.setattr(canary, "_run", fake_run)
canary._role_psql(
"local-postgres",
"teleo",
"select 1;",
role="kb_apply",
password="test-only-password",
)
assert captured["command"][0] == "/opt/homebrew/bin/docker"
assert captured["env"] == {
"PGPASSWORD": "test-only-password",
"PATH": "/usr/bin:/bin:/usr/local/bin",
}
def test_apply_tool_resolves_docker_before_scrubbing_path(
monkeypatch: pytest.MonkeyPatch,
) -> None:
captured: dict[str, object] = {}
monkeypatch.setattr(
apply.shutil,
"which",
lambda executable: "/opt/homebrew/bin/docker"
if executable == "docker"
else None,
)
def fake_run(command: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]:
captured["command"] = command
captured["env"] = kwargs["env"]
return subprocess.CompletedProcess(command, 0, "ok", "")
monkeypatch.setattr(apply.subprocess, "run", fake_run)
args = type(
"Args",
(),
{
"container": "local-postgres",
"role": "kb_apply",
"host": "127.0.0.1",
"db": "teleo",
},
)()
assert apply.run_psql(args, "select 1;", "test-only-password") == "ok"
assert captured["command"][0] == "/opt/homebrew/bin/docker"
assert captured["env"] == {
"PGPASSWORD": "test-only-password",
"PATH": "/usr/bin:/bin:/usr/local/bin",
}
def test_outer_wrapper_enforces_local_source_and_networkless_tmpfs() -> None:
text = WRAPPER.read_text(encoding="utf-8")
assert 'source_canary_label" != "working-leo-approved-source"' in text
assert "--network none" in text
assert "--tmpfs /var/lib/postgresql/data:rw,nosuid,size=512m" in text
assert 'CANARY_NETWORK_MODE="$container_network_mode"' in text
assert 'CANARY_MOUNTS_JSON="$container_mounts_json"' in text
assert 'data["checks"]["outer_source_tier_enforced"]' in text
assert 'data["checks"]["outer_container_network_disabled"]' in text
assert 'data["checks"]["outer_container_has_no_docker_volumes"]' in text
assert 'source_tier != "live-readonly" or service_observable' in text

View file

@ -0,0 +1,164 @@
from __future__ import annotations
import copy
import json
import sys
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO_ROOT / "scripts"))
import run_leo_local_ingestion_proposal_canary as canary # noqa: E402
def _loaded() -> tuple[dict, dict, dict]:
fixture, input_receipt = canary.load_fixture(canary.DEFAULT_FIXTURE)
row_ids = canary.build_row_ids(input_receipt["artifact_sha256"])
return fixture, input_receipt, row_ids
def test_fixture_is_realistic_hash_bound_and_exactly_evidenced() -> None:
fixture, input_receipt, row_ids = _loaded()
assert fixture["extraction"]["evidence"]["body"] in fixture["source"]["body"]
assert len(input_receipt["artifact_sha256"]) == 64
assert len(input_receipt["source_content_sha256"]) == 64
assert input_receipt["artifact_sha256"] != input_receipt["source_content_sha256"]
assert len(set(row_ids.values())) == 4
def test_fixture_validation_fails_closed_when_evidence_is_not_in_source(tmp_path: Path) -> None:
fixture = json.loads(canary.DEFAULT_FIXTURE.read_text(encoding="utf-8"))
fixture["extraction"]["evidence"]["body"] = "invented evidence"
path = tmp_path / "bad-fixture.json"
path.write_text(json.dumps(fixture), encoding="utf-8")
with pytest.raises(canary.CanaryError, match="exact substring"):
canary.load_fixture(path)
def test_fixture_validation_fails_closed_when_claim_body_is_not_in_source(
tmp_path: Path,
) -> None:
fixture = json.loads(canary.DEFAULT_FIXTURE.read_text(encoding="utf-8"))
fixture["extraction"]["claim"]["body"] = "invented claim body"
path = tmp_path / "bad-claim-fixture.json"
path.write_text(json.dumps(fixture), encoding="utf-8")
with pytest.raises(canary.CanaryError, match="claim body must be an exact substring"):
canary.load_fixture(path)
def test_capture_sql_escapes_quotes_and_backslashes_from_fixture(
tmp_path: Path,
) -> None:
fixture = json.loads(canary.DEFAULT_FIXTURE.read_text(encoding="utf-8"))
fixture["source"]["title"] = "O'Brien\\review"
fixture["source"]["metadata"]["note"] = "quoted ' value \\ path"
path = tmp_path / "quoted-fixture.json"
path.write_text(json.dumps(fixture), encoding="utf-8")
loaded, input_receipt = canary.load_fixture(path)
row_ids = canary.build_row_ids(input_receipt["artifact_sha256"])
sql = canary.build_capture_sql(loaded, input_receipt, row_ids)
assert canary.ap.sql_literal(fixture["source"]["title"]) in sql
assert canary.ap.sql_literal(
json.dumps(fixture["source"]["metadata"], sort_keys=True)
) in sql
def test_parent_normalizes_to_hash_bound_pending_proposal_with_embedded_row_links() -> None:
fixture, input_receipt, row_ids = _loaded()
parent = canary.build_parent_packet(fixture, input_receipt, row_ids)
child = canary.normalized_stage.prepare_normalized_child(parent)
payload = child["payload"]["apply_payload"]
assert child["status"] == "pending_review"
assert child["proposal_type"] == "approve_claim"
assert len(payload["claims"]) == 1
assert len(payload["sources"]) == 2
assert len(payload["evidence"]) == 2
assert input_receipt["source_content_sha256"] in {row["hash"] for row in payload["sources"]}
excerpts = "\n".join(row["excerpt"] for row in payload["sources"])
assert input_receipt["artifact_sha256"] in excerpts
assert row_ids["source_capture_id"] in excerpts
assert row_ids["claim_extraction_id"] in excerpts
assert row_ids["evidence_extraction_id"] in excerpts
def test_capture_and_stage_sql_never_mutate_canonical_public_tables() -> None:
fixture, input_receipt, row_ids = _loaded()
child = canary.normalized_stage.prepare_normalized_child(
canary.build_parent_packet(fixture, input_receipt, row_ids)
)
sql = "\n".join(
(
canary.build_schema_sql(),
canary.build_capture_sql(fixture, input_receipt, row_ids),
canary.normalized_stage.build_stage_sql(child),
)
).lower()
assert "insert into public." not in sql
assert "update public." not in sql
assert "delete from public." not in sql
assert "insert into kb_canary.source_captures" in sql
assert "insert into kb_canary.claim_extractions" in sql
assert "insert into kb_canary.evidence_extractions" in sql
assert "insert into kb_stage.kb_proposals" in sql
def test_check_evaluation_requires_every_row_link_and_staging_boundary() -> None:
fixture, input_receipt, row_ids = _loaded()
child = canary.normalized_stage.prepare_normalized_child(
canary.build_parent_packet(fixture, input_receipt, row_ids)
)
apply_payload = child["payload"]["apply_payload"]
readback = {
"source_capture": {
"id": row_ids["source_capture_id"],
"artifact_sha256": input_receipt["artifact_sha256"],
"content_sha256": input_receipt["source_content_sha256"],
"source_identity": input_receipt["source_identity"],
},
"claim_extraction": {
"id": row_ids["claim_extraction_id"],
"source_capture_id": row_ids["source_capture_id"],
"body": fixture["extraction"]["claim"]["body"],
"metadata": {"text": fixture["extraction"]["claim"]["text"]},
},
"evidence_extraction": {
"id": row_ids["evidence_extraction_id"],
"claim_extraction_id": row_ids["claim_extraction_id"],
"source_capture_id": row_ids["source_capture_id"],
"body": fixture["extraction"]["evidence"]["body"],
"metadata": fixture["extraction"]["evidence"]["metadata"],
},
"staged_proposal": {
"id": child["id"],
"status": "pending_review",
"source_ref": child["source_ref"],
"payload": {"apply_payload": apply_payload},
"reviewed_by_handle": None,
"reviewed_at": None,
"applied_by_handle": None,
"applied_at": None,
},
"counts": {
"source_captures": 1,
"claim_extractions": 1,
"evidence_extractions": 1,
"staged_proposals": 1,
},
}
checks = canary.evaluate_checks(fixture, input_receipt, row_ids, readback)
assert all(checks.values())
broken = copy.deepcopy(readback)
broken["evidence_extraction"]["claim_extraction_id"] = canary.stable_uuid("0" * 64, "wrong")
assert (
canary.evaluate_checks(fixture, input_receipt, row_ids, broken)["evidence_links_to_claim_and_source"] is False
)