teleo-infrastructure/tests/test_export_kb_transition_replay_material.py

232 lines
9.1 KiB
Python

from __future__ import annotations
import argparse
import copy
import json
import os
import stat
import sys
from pathlib import Path
import pytest
from ops import run_local_genesis_ledger_rebuild as genesis_rebuild
REPO_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO_ROOT / "scripts"))
import export_kb_transition_replay_material as exporter # noqa: E402
import kb_apply_replay_receipt as replay_receipt # noqa: E402
PROPOSAL_ID = "70000000-0000-4000-8000-000000000001"
REVIEWER_ID = "70000000-0000-4000-8000-000000000002"
SERVICE_ID = "70000000-0000-4000-8000-000000000003"
CLAIM_A = "70000000-0000-4000-8000-000000000004"
CLAIM_B = "70000000-0000-4000-8000-000000000005"
def _material() -> dict:
payload = {
"apply_payload": {
"from_claim": CLAIM_A,
"to_claim": CLAIM_B,
"edge_type": "supports",
"weight": 0.75,
},
"title": "Private exact transition packet",
}
approved = {
"id": PROPOSAL_ID,
"proposal_type": "add_edge",
"status": "approved",
"proposed_by_handle": "leo",
"proposed_by_agent_id": REVIEWER_ID,
"channel": "private_export_test",
"source_ref": "private://transition/source",
"rationale": "Retain the exact approved row for deterministic reconstruction.",
"payload": payload,
"reviewed_by_handle": "m3ta",
"reviewed_by_agent_id": REVIEWER_ID,
"reviewed_at": "2026-07-18T10:01:00+00:00",
"review_note": "Approved the exact strict packet.",
"applied_by_handle": None,
"applied_by_agent_id": None,
"applied_at": None,
"created_at": "2026-07-18T10:00:00+00:00",
"updated_at": "2026-07-18T10:01:00.000001+00:00",
}
applied = {
**approved,
"status": "applied",
"applied_by_handle": "kb-apply",
"applied_by_agent_id": SERVICE_ID,
"applied_at": "2026-07-18T10:02:00+00:00",
"updated_at": "2026-07-18T10:02:00.000001+00:00",
}
approval = {
"proposal_id": PROPOSAL_ID,
"proposal_type": "add_edge",
"payload": payload,
"reviewed_by_handle": "m3ta",
"reviewed_by_agent_id": REVIEWER_ID,
"reviewed_by_db_role": "kb_review",
"reviewed_at": "2026-07-18T10:01:00+00:00",
"review_note": "Approved the exact strict packet.",
}
receipt_proposal = {field: applied[field] for field in exporter.RECEIPT_PROPOSAL_FIELDS}
receipt = replay_receipt.build_replay_receipt(
receipt_proposal,
{
"claim_edges": [
{
"id": "70000000-0000-4000-8000-000000000006",
"from_claim": CLAIM_A,
"to_claim": CLAIM_B,
"edge_type": "supports",
"weight": 0.75,
"created_by": None,
"created_at": "2026-07-18T10:01:30+00:00",
}
]
},
apply_sql_sha256=replay_receipt.sha256_text("exact guarded apply SQL"),
apply_sql_source="exact_executed_sql",
exported_at_utc="2026-07-18T10:03:00+00:00",
)
return {
"artifact": exporter.MATERIAL_ARTIFACT,
"contract_version": exporter.MATERIAL_CONTRACT_VERSION,
"sequence": 1,
"approved_proposal": approved,
"approval_snapshot": approval,
"applied_proposal": applied,
"replay_receipt": receipt,
}
def test_material_matches_genesis_replay_row_contract() -> None:
material = exporter.validate_material(
_material(),
expected_proposal_id=PROPOSAL_ID,
expected_sequence=1,
)
assert exporter.MATERIAL_ARTIFACT == genesis_rebuild.MATERIAL_ARTIFACT
assert exporter.MATERIAL_CONTRACT_VERSION == genesis_rebuild.MATERIAL_CONTRACT_VERSION
assert exporter.PROPOSAL_FIELDS == genesis_rebuild.PROPOSAL_FIELDS
assert exporter.APPROVAL_FIELDS == genesis_rebuild.APPROVAL_FIELDS
genesis_rebuild._validate_proposal_rows(
material["approved_proposal"],
material["applied_proposal"],
material["approval_snapshot"],
material["replay_receipt"]["proposal"],
)
@pytest.mark.parametrize(
("mutation", "message"),
[
(lambda value: value["approved_proposal"].__setitem__("unexpected", True), "invalid fields"),
(
lambda value: value["applied_proposal"].__setitem__("rationale", "post-approval drift"),
"exact guarded apply transition",
),
(
lambda value: value["approval_snapshot"].__setitem__("review_note", "different review"),
"does not match approved proposal",
),
(
lambda value: value["replay_receipt"]["proposal"].__setitem__("id", CLAIM_A),
"worker replay receipt",
),
(lambda value: value.__setitem__("sequence", 0), "positive integer"),
],
)
def test_material_validation_fails_closed_on_drift(mutation, message: str) -> None:
material = copy.deepcopy(_material())
mutation(material)
with pytest.raises(exporter.ExportError, match=message):
exporter.validate_material(material, expected_proposal_id=PROPOSAL_ID)
def test_json_parser_rejects_duplicate_and_nonfinite_fields() -> None:
with pytest.raises(exporter.ExportError, match="duplicate"):
exporter._parse_json_object('{"artifact":"a","artifact":"b"}', label="fixture")
with pytest.raises(exporter.ExportError, match="invalid numeric"):
exporter._parse_json_object('{"sequence":NaN}', label="fixture")
def test_private_writer_is_atomic_idempotent_and_refuses_alias_or_rerun_drift(tmp_path: Path) -> None:
material = exporter.validate_material(_material(), expected_proposal_id=PROPOSAL_ID)
protected = tmp_path / "worker-receipt.json"
protected.write_text("private worker receipt", encoding="utf-8")
protected.chmod(0o600)
output = tmp_path / "material.json"
written, disposition = exporter.write_private_material(output, material, protected_paths=(protected,))
assert written == output
assert disposition == "created"
assert stat.S_IMODE(output.stat().st_mode) == 0o600
assert output.stat().st_nlink == 1
assert json.loads(output.read_text(encoding="utf-8")) == material
_, rerun_disposition = exporter.write_private_material(output, material, protected_paths=(protected,))
assert rerun_disposition == "unchanged"
drifted = copy.deepcopy(material)
drifted["sequence"] = 2
with pytest.raises(exporter.ExportError, match="different replay material"):
exporter.write_private_material(output, drifted, protected_paths=(protected,))
with pytest.raises(exporter.ExportError, match="aliases a protected"):
exporter.write_private_material(protected, material, protected_paths=(protected,))
dangling = tmp_path / "dangling-output.json"
dangling.symlink_to(tmp_path / "missing-target.json")
with pytest.raises(exporter.ExportError, match="non-symlink"):
exporter.write_private_material(dangling, material, protected_paths=(protected,))
hardlink = tmp_path / "hardlink.json"
os.link(output, hardlink)
with pytest.raises(exporter.ExportError, match="hard-link"):
exporter.write_private_material(output, material, protected_paths=(protected,))
def test_private_receipt_loader_requires_exact_mode_and_rejects_symlinks(tmp_path: Path) -> None:
receipt = _material()["replay_receipt"]
receipt_path = tmp_path / "receipt.json"
receipt_path.write_text(json.dumps(receipt), encoding="utf-8")
receipt_path.chmod(0o600)
assert exporter._load_private_receipt(receipt_path) == receipt
receipt_path.chmod(0o640)
with pytest.raises(exporter.ExportError, match="exactly 0600"):
exporter._load_private_receipt(receipt_path)
receipt_path.chmod(0o600)
receipt_link = tmp_path / "receipt-link.json"
receipt_link.symlink_to(receipt_path)
with pytest.raises(exporter.ExportError, match="non-symlink"):
exporter._load_private_receipt(receipt_link)
def test_transition_fetch_uses_only_read_only_narrow_function(monkeypatch: pytest.MonkeyPatch) -> None:
calls: list[tuple[str, bool]] = []
rows = {key: _material()[key] for key in ("approved_proposal", "approval_snapshot", "applied_proposal")}
def fake_run_psql(args, sql: str, password: str, *, redact_output_on_error: bool = False) -> str:
assert args.role == "kb_apply"
assert password == "private-password"
calls.append((sql, redact_output_on_error))
return json.dumps(rows)
monkeypatch.setattr(exporter.apply_engine, "run_psql", fake_run_psql)
args = argparse.Namespace(container="disposable", db="teleo", host="127.0.0.1", role="kb_apply")
assert exporter.fetch_transition_rows(args, "private-password", PROPOSAL_ID) == rows
assert len(calls) == 1
sql, redacted = calls[0]
assert "transaction isolation level repeatable read read only" in sql
assert "kb_stage.export_applied_proposal_replay_rows" in sql
assert not any(keyword in sql.lower() for keyword in ("insert ", "update ", "delete ", "truncate "))
assert redacted is True