913 lines
36 KiB
Python
913 lines
36 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
|
|
|
import compile_kb_source_packet as compiler # noqa: E402
|
|
import run_leo_integrated_learning_lifecycle as lifecycle # noqa: E402
|
|
|
|
|
|
def _write_source_packet(tmp_path: Path) -> Path:
|
|
packet = tmp_path / "source-packet"
|
|
prepared = packet / "prepared"
|
|
prepared.mkdir(parents=True)
|
|
artifact = REPO_ROOT / "fixtures" / "working-leo" / "document-ingestion-v1.json"
|
|
manifest = REPO_ROOT / "fixtures" / "working-leo" / "source-compiler-manifest-v1.json"
|
|
extracted = prepared / "extracted-text.txt"
|
|
manifest_target = prepared / "source-manifest.json"
|
|
shutil.copyfile(artifact, extracted)
|
|
shutil.copyfile(manifest, manifest_target)
|
|
expected = compiler.compile_source_packet(extracted, extracted, manifest_target)
|
|
(packet / "proposal-packet.json").write_text(
|
|
json.dumps(expected, indent=2, sort_keys=True) + "\n",
|
|
encoding="utf-8",
|
|
)
|
|
return packet
|
|
|
|
|
|
def _docker_available() -> bool:
|
|
if not shutil.which("docker"):
|
|
return False
|
|
result = subprocess.run(
|
|
["docker", "info", "--format", "{{.ServerVersion}}"],
|
|
text=True,
|
|
capture_output=True,
|
|
check=False,
|
|
)
|
|
return result.returncode == 0
|
|
|
|
|
|
def _commit_test_repository(path: Path, files: dict[str, str]) -> None:
|
|
subprocess.run(["git", "init", "-q", str(path)], check=True)
|
|
for relative_path, contents in files.items():
|
|
target = path / relative_path
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text(contents, encoding="utf-8")
|
|
subprocess.run(["git", "-C", str(path), "add", "."], check=True)
|
|
subprocess.run(
|
|
[
|
|
"git",
|
|
"-C",
|
|
str(path),
|
|
"-c",
|
|
"user.name=Lifecycle Test",
|
|
"-c",
|
|
"user.email=lifecycle-test@example.invalid",
|
|
"commit",
|
|
"-qm",
|
|
"test engine",
|
|
],
|
|
check=True,
|
|
)
|
|
|
|
|
|
def test_source_packet_recompiles_to_retained_expectation(tmp_path: Path) -> None:
|
|
packet = _write_source_packet(tmp_path)
|
|
|
|
compiled, expected, paths = lifecycle.compile_source_packet(packet)
|
|
|
|
assert compiled == expected
|
|
assert lifecycle.sha256_file(paths["artifact"]) == expected["validated_manifest"]["artifact_sha256"]
|
|
assert compiled["status"] == "pending_review"
|
|
assert compiled["strict_child_proposal"]["status"] == "pending_review"
|
|
|
|
|
|
def test_source_packet_refuses_retained_packet_drift(tmp_path: Path) -> None:
|
|
packet = _write_source_packet(tmp_path)
|
|
expected_path = packet / "proposal-packet.json"
|
|
expected = json.loads(expected_path.read_text(encoding="utf-8"))
|
|
expected["strict_child_proposal"]["status"] = "approved"
|
|
expected_path.write_text(json.dumps(expected), encoding="utf-8")
|
|
|
|
with pytest.raises(lifecycle.LifecycleError, match="does not match retained"):
|
|
lifecycle.compile_source_packet(packet)
|
|
|
|
|
|
def test_execution_identity_requires_exact_committed_dependency_bytes(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
repo = tmp_path / "repo"
|
|
repo.mkdir()
|
|
_commit_test_repository(repo, {"scripts/engine.py": "print('committed')\n"})
|
|
engine = repo / "scripts" / "engine.py"
|
|
monkeypatch.setattr(lifecycle, "REPO_ROOT", repo)
|
|
monkeypatch.setattr(lifecycle, "ENGINE_INPUT_PATHS", {"engine.runner": engine})
|
|
|
|
identity = lifecycle.execution_identity()
|
|
assert identity["engine_paths_match_head"] is True
|
|
assert identity["engine_relpaths"] == ["scripts/engine.py"]
|
|
assert identity["engine_head_sha256"]["engine.runner"] == hashlib.sha256(engine.read_bytes()).hexdigest()
|
|
|
|
engine.write_text("print('dirty')\n", encoding="utf-8")
|
|
with pytest.raises(lifecycle.LifecycleError, match="does not match"):
|
|
lifecycle.execution_identity()
|
|
|
|
|
|
def test_engine_dependency_closure_includes_transitive_imports() -> None:
|
|
assert {
|
|
"engine.proposal_normalizer",
|
|
"engine.rich_proposal_plan",
|
|
"engine.clone_checkpoint",
|
|
} <= lifecycle.ENGINE_INPUT_PATHS.keys()
|
|
|
|
|
|
def test_exact_identities_adds_observed_evidence_ids(tmp_path: Path) -> None:
|
|
packet = _write_source_packet(tmp_path)
|
|
compiled, _expected, _paths = lifecycle.compile_source_packet(packet)
|
|
child = compiled["strict_child_proposal"]
|
|
apply_payload = child["payload"]["apply_payload"]
|
|
planned = apply_payload["evidence"][0]
|
|
evidence_id = "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee"
|
|
|
|
identities = lifecycle.exact_identities(
|
|
child,
|
|
{
|
|
"claim_evidence": [{"id": evidence_id, **planned}],
|
|
"claim_edges": [],
|
|
},
|
|
)
|
|
|
|
assert identities["proposal_id"] == child["id"]
|
|
assert identities["claim_ids"] == [row["id"] for row in apply_payload["claims"]]
|
|
assert identities["source_ids"] == [row["id"] for row in apply_payload["sources"]]
|
|
assert identities["planned_evidence_keys"] == [
|
|
{
|
|
"claim_id": row["claim_id"],
|
|
"source_id": row["source_id"],
|
|
"role": row["role"],
|
|
}
|
|
for row in apply_payload["evidence"]
|
|
]
|
|
assert identities["evidence_ids"] == [evidence_id]
|
|
|
|
|
|
def test_lifecycle_requires_explicit_approve_action(tmp_path: Path) -> None:
|
|
with pytest.raises(lifecycle.LifecycleError, match="only supported explicit review action"):
|
|
lifecycle.run_lifecycle(
|
|
tmp_path / "unused",
|
|
tmp_path / "receipt.json",
|
|
review_action="inspect",
|
|
)
|
|
|
|
|
|
def _application_role(*, complete_settings: bool = True) -> dict:
|
|
role = {
|
|
"name": "kb_apply",
|
|
"can_login": True,
|
|
"superuser": False,
|
|
"create_db": False,
|
|
"create_role": False,
|
|
"inherit": False,
|
|
"replication": False,
|
|
"bypass_rls": False,
|
|
"connection_limit": -1,
|
|
"default_transaction_read_only": None,
|
|
}
|
|
if complete_settings:
|
|
role["settings"] = []
|
|
role["database_settings"] = []
|
|
return role
|
|
|
|
|
|
def _minimal_loaded_manifest(*, complete_settings: bool = True) -> dict:
|
|
return {
|
|
"singleton": {
|
|
"identity": {"database": lifecycle.DATABASE, "transaction_read_only": "on"},
|
|
"application_roles": {"items": [_application_role(complete_settings=complete_settings)]},
|
|
"role_memberships": {"items": []},
|
|
"object_acl": {"items": []},
|
|
},
|
|
"tables": {"public.fixture": {"row_count": 0, "rowset_md5": "0" * 32}},
|
|
"performance": {},
|
|
}
|
|
|
|
|
|
def _write_exporter_receipt(
|
|
path: Path,
|
|
dump: Path,
|
|
manifest_path: Path,
|
|
loaded_manifest: dict,
|
|
*,
|
|
source: dict[str, str] | None = None,
|
|
) -> dict:
|
|
source = source or {
|
|
"ssh_target": "disposable-test",
|
|
"container": "teleo-test-source",
|
|
"database": lifecycle.DATABASE,
|
|
"service": "disposable-postgres-test",
|
|
}
|
|
snapshot = {
|
|
"captured_at_utc": "2026-07-18T00:00:00+00:00",
|
|
"exported_snapshot_id": "00000003-00000001-1",
|
|
"txid_snapshot": "1:1:",
|
|
"wal_lsn": "0/1",
|
|
"system_identifier": "123456789",
|
|
}
|
|
authorization_ref = "codex-delegation:disposable-genesis-test"
|
|
manifest_sha256 = lifecycle.sha256_file(manifest_path)
|
|
dump_sha256 = lifecycle.sha256_file(dump)
|
|
manifest_sql_sha256 = lifecycle.sha256_file(lifecycle.PARITY_SQL_PATH)
|
|
source_context_sha256 = hashlib.sha256(b"disposable-source-context").hexdigest()
|
|
binding = lifecycle.snapshot_capture.build_provenance_binding(
|
|
run_id="disposable-genesis-test",
|
|
authorization_ref=authorization_ref,
|
|
source=source,
|
|
snapshot=snapshot,
|
|
dump_sha256=dump_sha256,
|
|
manifest_sql_sha256=manifest_sql_sha256,
|
|
source_manifest_sha256=manifest_sha256,
|
|
source_context_sha256=source_context_sha256,
|
|
)
|
|
service_state = {
|
|
"ActiveState": "active",
|
|
"SubState": "running",
|
|
"MainPID": "123",
|
|
"NRestarts": "0",
|
|
"ActiveEnterTimestamp": "2026-07-18T00:00:00+00:00",
|
|
}
|
|
receipt = {
|
|
"artifact": lifecycle.TRUSTED_EXPORTER_ARTIFACT,
|
|
"schema": lifecycle.snapshot_capture.SOURCE_SNAPSHOT_RECEIPT_SCHEMA,
|
|
"receipt_version": 2,
|
|
"status": "pass",
|
|
"run_id": "disposable-genesis-test",
|
|
"capture_authorization_ref": authorization_ref,
|
|
"source": source,
|
|
"snapshot_exported": True,
|
|
"snapshot": snapshot,
|
|
"dump": {"path": str(dump), "bytes": dump.stat().st_size, "sha256": dump_sha256},
|
|
"manifest": {
|
|
"path": str(manifest_path),
|
|
"sha256": manifest_sha256,
|
|
"manifest_sql_sha256": manifest_sql_sha256,
|
|
"table_count": len(loaded_manifest["tables"]),
|
|
"total_rows": sum(int(row["row_count"]) for row in loaded_manifest["tables"].values()),
|
|
"application_roles": loaded_manifest["singleton"]["application_roles"]["items"],
|
|
},
|
|
"source_context": {"path": "source-context.txt", "sha256": source_context_sha256},
|
|
"source_service": {"before": service_state, "after": service_state, "unchanged": True},
|
|
"provenance_binding": binding,
|
|
"service_unchanged": True,
|
|
"production_db_mutated": False,
|
|
"telegram_send_attempted": False,
|
|
}
|
|
path.write_text(json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
path.chmod(0o600)
|
|
return receipt
|
|
|
|
|
|
def _trust_test_exporter_receipt(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
path: Path,
|
|
receipt: dict,
|
|
) -> None:
|
|
registry = dict(lifecycle.TRUSTED_EXPORTER_RECEIPTS)
|
|
registry[lifecycle.sha256_file(path)] = {
|
|
"run_id": receipt["run_id"],
|
|
"capture_authorization_ref": receipt["capture_authorization_ref"],
|
|
"source": receipt["source"],
|
|
"dump_sha256": receipt["dump"]["sha256"],
|
|
"manifest_sha256": receipt["manifest"]["sha256"],
|
|
"manifest_sql_sha256": receipt["manifest"]["manifest_sql_sha256"],
|
|
"provenance_binding_sha256": receipt["provenance_binding"]["sha256"],
|
|
}
|
|
monkeypatch.setattr(lifecycle, "TRUSTED_EXPORTER_RECEIPTS", registry)
|
|
|
|
|
|
def _genesis_cli(tmp_path: Path) -> list[str]:
|
|
return [
|
|
"--source-packet",
|
|
str(tmp_path / "packet"),
|
|
"--output",
|
|
str(tmp_path / "lifecycle-receipt.json"),
|
|
"--review-action",
|
|
"approve",
|
|
"--genesis-dump",
|
|
str(tmp_path / "genesis.dump"),
|
|
"--genesis-manifest",
|
|
str(tmp_path / "manifest.jsonl"),
|
|
"--genesis-exporter-receipt",
|
|
str(tmp_path / "exporter-receipt.json"),
|
|
]
|
|
|
|
|
|
def test_genesis_cli_requires_complete_exporter_receipt_set(tmp_path: Path) -> None:
|
|
with pytest.raises(SystemExit):
|
|
lifecycle.parse_args(_genesis_cli(tmp_path)[:-2])
|
|
|
|
|
|
def test_genesis_cli_rejects_caller_only_hash_flags(tmp_path: Path) -> None:
|
|
with pytest.raises(SystemExit):
|
|
lifecycle.parse_args([*_genesis_cli(tmp_path), "--genesis-dump-sha256", "a" * 64])
|
|
|
|
|
|
def test_genesis_cli_rejects_moving_image_tag(tmp_path: Path) -> None:
|
|
with pytest.raises(SystemExit):
|
|
lifecycle.parse_args([*_genesis_cli(tmp_path), "--image", "postgres:16-alpine"])
|
|
|
|
|
|
def test_exporter_receipt_dump_drift_fails_before_docker(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
dump = tmp_path / "genesis.dump"
|
|
manifest = tmp_path / "manifest.jsonl"
|
|
exporter_receipt = tmp_path / "exporter-receipt.json"
|
|
dump.write_bytes(b"PGDMP-real-enough-for-signature-validation")
|
|
manifest.write_text("{}\n", encoding="utf-8")
|
|
loaded_manifest = _minimal_loaded_manifest()
|
|
receipt = _write_exporter_receipt(exporter_receipt, dump, manifest, loaded_manifest)
|
|
_trust_test_exporter_receipt(monkeypatch, exporter_receipt, receipt)
|
|
dump.write_bytes(dump.read_bytes() + b"drift")
|
|
monkeypatch.setattr(lifecycle, "load_manifest", lambda _path: loaded_manifest)
|
|
|
|
with pytest.raises(lifecycle.LifecycleError, match="dump_hash_from_exporter_receipt"):
|
|
lifecycle.validate_genesis_inputs(
|
|
dump,
|
|
manifest,
|
|
exporter_receipt,
|
|
lifecycle.DEFAULT_GENESIS_IMAGE,
|
|
)
|
|
|
|
|
|
def test_exporter_receipt_rebound_source_identity_fails_closed(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
dump = tmp_path / "genesis.dump"
|
|
manifest = tmp_path / "manifest.jsonl"
|
|
exporter_receipt = tmp_path / "exporter-receipt.json"
|
|
dump.write_bytes(b"PGDMP-real-enough-for-signature-validation")
|
|
manifest.write_text("{}\n", encoding="utf-8")
|
|
loaded_manifest = _minimal_loaded_manifest()
|
|
receipt = _write_exporter_receipt(exporter_receipt, dump, manifest, loaded_manifest)
|
|
_trust_test_exporter_receipt(monkeypatch, exporter_receipt, receipt)
|
|
receipt["source"]["database"] = "attacker_rebound"
|
|
receipt["provenance_binding"] = lifecycle.snapshot_capture.build_provenance_binding(
|
|
run_id=receipt["run_id"],
|
|
authorization_ref=receipt["capture_authorization_ref"],
|
|
source=receipt["source"],
|
|
snapshot=receipt["snapshot"],
|
|
dump_sha256=receipt["dump"]["sha256"],
|
|
manifest_sql_sha256=receipt["manifest"]["manifest_sql_sha256"],
|
|
source_manifest_sha256=receipt["manifest"]["sha256"],
|
|
source_context_sha256=receipt["source_context"]["sha256"],
|
|
)
|
|
exporter_receipt.write_text(json.dumps(receipt), encoding="utf-8")
|
|
exporter_receipt.chmod(0o600)
|
|
monkeypatch.setattr(lifecycle, "load_manifest", lambda _path: loaded_manifest)
|
|
|
|
with pytest.raises(lifecycle.LifecycleError, match="trusted_exporter_receipt_hash"):
|
|
lifecycle.validate_genesis_inputs(
|
|
dump,
|
|
manifest,
|
|
exporter_receipt,
|
|
lifecycle.DEFAULT_GENESIS_IMAGE,
|
|
)
|
|
|
|
|
|
def test_legacy_manifest_role_settings_projection_is_narrow_and_nonmutating() -> None:
|
|
manifest = {
|
|
"singleton": {
|
|
"application_roles": {
|
|
"items": [
|
|
{
|
|
"name": "kb_observatory_read",
|
|
"default_transaction_read_only": "on",
|
|
},
|
|
{
|
|
"name": "kb_apply",
|
|
"default_transaction_read_only": None,
|
|
},
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
projected = lifecycle.manifest_for_role_replay(manifest)
|
|
|
|
assert "settings" not in manifest["singleton"]["application_roles"]["items"][0]
|
|
assert projected["singleton"]["application_roles"]["items"][0]["settings"] == [
|
|
{"name": "default_transaction_read_only", "value": "on"}
|
|
]
|
|
assert projected["singleton"]["application_roles"]["items"][0]["database_settings"] == []
|
|
assert projected["singleton"]["application_roles"]["items"][1]["settings"] == []
|
|
assert lifecycle.role_settings_capture_complete(manifest) is False
|
|
|
|
|
|
def test_private_staging_is_read_only_and_original_path_drift_is_not_consumed(tmp_path: Path) -> None:
|
|
packet = _write_source_packet(tmp_path)
|
|
dump = tmp_path / "genesis.dump"
|
|
manifest = tmp_path / "manifest.jsonl"
|
|
exporter_receipt = tmp_path / "exporter-receipt.json"
|
|
dump.write_bytes(b"PGDMP-staged-input")
|
|
manifest.write_text("{}\n", encoding="utf-8")
|
|
exporter_receipt.write_text("{}\n", encoding="utf-8")
|
|
exporter_receipt.chmod(0o600)
|
|
|
|
staged = lifecycle.stage_lifecycle_inputs(packet, dump, manifest, exporter_receipt)
|
|
try:
|
|
before = lifecycle.verify_staged_inputs(staged)
|
|
dump.write_bytes(b"PGDMP-mutated-original")
|
|
(packet / "proposal-packet.json").write_text("{}\n", encoding="utf-8")
|
|
after = lifecycle.verify_staged_inputs(staged)
|
|
|
|
assert before == after
|
|
assert staged.genesis_dump.read_bytes() == b"PGDMP-staged-input"
|
|
assert staged.root.stat().st_mode & 0o777 == 0o500
|
|
assert all(
|
|
(staged.root / row["relative_path"]).stat().st_mode & 0o777 == 0o400 for row in staged.files.values()
|
|
)
|
|
finally:
|
|
cleanup = lifecycle.cleanup_staged_inputs(staged.root)
|
|
|
|
assert cleanup["root_absent"] is True
|
|
|
|
|
|
def test_private_staging_detects_consumed_byte_mutation(tmp_path: Path) -> None:
|
|
packet = _write_source_packet(tmp_path)
|
|
dump = tmp_path / "genesis.dump"
|
|
manifest = tmp_path / "manifest.jsonl"
|
|
exporter_receipt = tmp_path / "exporter-receipt.json"
|
|
dump.write_bytes(b"PGDMP-staged-input")
|
|
manifest.write_text("{}\n", encoding="utf-8")
|
|
exporter_receipt.write_text("{}\n", encoding="utf-8")
|
|
exporter_receipt.chmod(0o600)
|
|
staged = lifecycle.stage_lifecycle_inputs(packet, dump, manifest, exporter_receipt)
|
|
staged_dump = staged.genesis_dump
|
|
try:
|
|
staged_dump.chmod(0o600)
|
|
staged_dump.write_bytes(b"PGDMP-mutated-staging")
|
|
staged_dump.chmod(0o400)
|
|
with pytest.raises(lifecycle.LifecycleError, match="staging bytes drifted"):
|
|
lifecycle.verify_staged_inputs(staged)
|
|
finally:
|
|
cleanup = lifecycle.cleanup_staged_inputs(staged.root)
|
|
|
|
assert cleanup["root_absent"] is True
|
|
|
|
|
|
def test_genesis_initialization_cannot_call_synthetic_bootstrap(tmp_path: Path) -> None:
|
|
class RestoreOnlyPostgres:
|
|
def __init__(self) -> None:
|
|
self.restored = False
|
|
|
|
def restore_genesis(self, _inputs):
|
|
self.restored = True
|
|
return {"parity": {"status": "pass"}}
|
|
|
|
def psql(self, sql: str) -> str:
|
|
assert sql.startswith("alter role kb_review password")
|
|
return ""
|
|
|
|
postgres = RestoreOnlyPostgres()
|
|
|
|
result = lifecycle.initialize_database(
|
|
postgres,
|
|
genesis=object(),
|
|
review_password="unused",
|
|
apply_password="unused",
|
|
)
|
|
|
|
assert postgres.restored is True
|
|
assert result["mode"] == "exporter_receipt_bound_genesis_restore"
|
|
assert result["synthetic_schema_bootstrap_skipped"] is True
|
|
assert result["canonical_payload_preseed_performed"] is False
|
|
|
|
|
|
def test_fresh_initial_state_rejects_proposal_and_payload_preseed() -> None:
|
|
empty_rows = {family: [] for family in lifecycle.apply_lifecycle.ROW_TABLES}
|
|
with pytest.raises(lifecycle.LifecycleError, match="proposal or approval preseed"):
|
|
lifecycle.require_fresh_initial_state(
|
|
{"state": {"proposal": {"id": "preseed"}, "immutable_approval": None, "canonical_rows": empty_rows}}
|
|
)
|
|
|
|
preseed_rows = {family: [] for family in lifecycle.apply_lifecycle.ROW_TABLES}
|
|
preseed_rows["claims"] = [{"id": "preseed"}]
|
|
with pytest.raises(lifecycle.LifecycleError, match="canonical payload target preseed"):
|
|
lifecycle.require_fresh_initial_state(
|
|
{"state": {"proposal": None, "immutable_approval": None, "canonical_rows": preseed_rows}}
|
|
)
|
|
|
|
|
|
def test_payload_controlled_fingerprint_ignores_generated_fields_but_detects_payload_drift() -> None:
|
|
rows = {family: [] for family in lifecycle.PAYLOAD_CONTROLLED_FIELDS}
|
|
rows["claims"] = [
|
|
{
|
|
"id": "11111111-1111-4111-8111-111111111111",
|
|
"type": "fact",
|
|
"text": "Stable payload text",
|
|
"status": "open",
|
|
"confidence": 0.7,
|
|
"tags": ["test"],
|
|
"created_by": None,
|
|
"superseded_by": None,
|
|
"created_at": "2026-01-01T00:00:00+00:00",
|
|
}
|
|
]
|
|
first = lifecycle.payload_controlled_fingerprint(rows)
|
|
rows["claims"][0]["created_at"] = "2027-01-01T00:00:00+00:00"
|
|
rows["claims"][0]["updated_at"] = "2027-01-01T00:00:01+00:00"
|
|
second = lifecycle.payload_controlled_fingerprint(rows)
|
|
rows["claims"][0]["text"] = "Drifted payload text"
|
|
drifted = lifecycle.payload_controlled_fingerprint(rows)
|
|
|
|
assert first["sha256"] == second["sha256"]
|
|
assert drifted["sha256"] != first["sha256"]
|
|
|
|
|
|
def _fake_genesis_run(run_number: int) -> dict:
|
|
controlled = {
|
|
"schema": "livingip.leoPayloadControlledRowsFingerprint.v1",
|
|
"sha256": "c" * 64,
|
|
"table_sha256": {family: "d" * 64 for family in lifecycle.PAYLOAD_CONTROLLED_FIELDS},
|
|
"row_counts": {family: 0 for family in lifecycle.PAYLOAD_CONTROLLED_FIELDS},
|
|
"rows": {family: [] for family in lifecycle.PAYLOAD_CONTROLLED_FIELDS},
|
|
}
|
|
return {
|
|
"status": "pass",
|
|
"run_number": run_number,
|
|
"source": {
|
|
"artifact_sha256": "1" * 64,
|
|
"manifest_canonical_sha256": "2" * 64,
|
|
"retained_proposal_packet_file_sha256": "3" * 64,
|
|
"retained_proposal_packet_canonical_sha256": "4" * 64,
|
|
},
|
|
"compiled": {"bundle_sha256": "4" * 64},
|
|
"identities": {
|
|
"proposal_id": "11111111-1111-4111-8111-111111111111",
|
|
"claim_ids": [],
|
|
"source_ids": [],
|
|
"planned_evidence_keys": [],
|
|
"evidence_ids": [f"generated-{run_number}"],
|
|
"edge_ids": [],
|
|
},
|
|
"phases": {
|
|
"staged_pending_review": {"proposal": {"status": "pending_review"}},
|
|
"approved_unapplied": {"proposal": {"status": "approved"}},
|
|
"applied": {
|
|
"proposal": {"status": "applied", "applied_at": f"2026-01-0{run_number}T00:00:00+00:00"},
|
|
"payload_controlled_fingerprint": controlled,
|
|
"worker_action": {
|
|
"exact_candidate_id": "11111111-1111-4111-8111-111111111111",
|
|
"credential_role": "kb_apply",
|
|
"retry_failure_count": 1,
|
|
"failure_state_after_success": {},
|
|
"private_receipt_mode": "0600",
|
|
},
|
|
"apply_receipt": {
|
|
"hashes": {"apply_payload_sha256": "5" * 64},
|
|
"expected_row_counts": controlled["row_counts"],
|
|
"actual_row_counts": controlled["row_counts"],
|
|
},
|
|
},
|
|
"recompiled_readback": {
|
|
"bundle_sha256": "4" * 64,
|
|
"matches_initial_compile": True,
|
|
},
|
|
},
|
|
"database_initialization": {
|
|
"genesis": {
|
|
"dump": {"sha256": "6" * 64},
|
|
"manifest": {"sha256": "7" * 64},
|
|
"exporter_receipt": {
|
|
"sha256": "8" * 64,
|
|
"provenance_binding_sha256": "9" * 64,
|
|
},
|
|
"image": {"reference": lifecycle.DEFAULT_GENESIS_IMAGE},
|
|
"parity": {
|
|
"status": "pass",
|
|
"problems": [],
|
|
"claim_scope": "full_captured_manifest_including_role_and_database_settings",
|
|
"role_global_parity": {
|
|
"status": "proven",
|
|
"captured_source_settings_present": True,
|
|
"reason": None,
|
|
},
|
|
},
|
|
"key_counts": {"public.claims": 10},
|
|
"canonical_schema_table_count": 10,
|
|
}
|
|
},
|
|
"cleanup": {"all": True},
|
|
}
|
|
|
|
|
|
def _mocked_genesis_case(tmp_path: Path) -> tuple[Path, Path, Path, Path]:
|
|
packet = _write_source_packet(tmp_path)
|
|
dump = tmp_path / "genesis.dump"
|
|
manifest = tmp_path / "genesis-manifest.jsonl"
|
|
exporter_receipt = tmp_path / "exporter-receipt.json"
|
|
dump.write_bytes(b"PGDMPx")
|
|
manifest.write_text("{}\n", encoding="utf-8")
|
|
_write_exporter_receipt(exporter_receipt, dump, manifest, _minimal_loaded_manifest())
|
|
return packet, dump, manifest, exporter_receipt
|
|
|
|
|
|
def _fake_validate_genesis(
|
|
dump: Path,
|
|
manifest: Path,
|
|
exporter_receipt: Path,
|
|
image: str,
|
|
**paths,
|
|
) -> lifecycle.GenesisInputs:
|
|
payload = json.loads(exporter_receipt.read_text(encoding="utf-8"))
|
|
return lifecycle.GenesisInputs(
|
|
dump=dump,
|
|
dump_sha256=lifecycle.sha256_file(dump),
|
|
dump_bytes=dump.stat().st_size,
|
|
manifest_path=manifest,
|
|
manifest_sha256=lifecycle.sha256_file(manifest),
|
|
manifest_bytes=manifest.stat().st_size,
|
|
manifest=_minimal_loaded_manifest(),
|
|
image=image,
|
|
exporter_receipt_path=exporter_receipt,
|
|
exporter_receipt_sha256=lifecycle.sha256_file(exporter_receipt),
|
|
exporter_receipt=payload,
|
|
source_identity=payload["source"],
|
|
capture_authorization_ref=payload["capture_authorization_ref"],
|
|
provenance_binding_sha256=payload["provenance_binding"]["sha256"],
|
|
trust_root_receipt_sha256=lifecycle.sha256_file(exporter_receipt),
|
|
role_settings_capture_complete=True,
|
|
parity_sql_path=paths["parity_sql_path"],
|
|
guard_prerequisites_path=paths["guard_prerequisites_path"],
|
|
approve_script_path=paths["approve_script_path"],
|
|
apply_worker_script_path=paths["apply_worker_script_path"],
|
|
apply_script_path=paths["apply_script_path"],
|
|
)
|
|
|
|
|
|
def test_genesis_lifecycle_repeats_semantically_and_writes_private_receipt(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
packet, dump, manifest, exporter_receipt = _mocked_genesis_case(tmp_path)
|
|
calls: list[int] = []
|
|
|
|
monkeypatch.setattr(lifecycle, "validate_genesis_inputs", _fake_validate_genesis)
|
|
|
|
def fake_run(*_args, run_number: int, **_kwargs):
|
|
calls.append(run_number)
|
|
return _fake_genesis_run(run_number)
|
|
|
|
monkeypatch.setattr(lifecycle, "run_lifecycle", fake_run)
|
|
monkeypatch.setattr(
|
|
lifecycle,
|
|
"verify_run_group_cleanup",
|
|
lambda run_group: {"checked": True, "run_group": run_group, "container_names": [], "all_absent": True},
|
|
)
|
|
output = tmp_path / "genesis-lifecycle-receipt.json"
|
|
|
|
receipt = lifecycle.run_genesis_lifecycle(
|
|
packet,
|
|
output,
|
|
review_action="approve",
|
|
genesis_dump=dump,
|
|
genesis_manifest=manifest,
|
|
genesis_exporter_receipt=exporter_receipt,
|
|
image=lifecycle.DEFAULT_GENESIS_IMAGE,
|
|
)
|
|
|
|
assert calls == [1, 2]
|
|
assert receipt["status"] == "pass"
|
|
assert receipt["repeatability"]["semantic_match"] is True
|
|
assert len(set(receipt["repeatability"]["semantic_fingerprints_sha256"])) == 1
|
|
assert receipt["repeatability"]["identical_post_apply_fingerprints"] is True
|
|
assert receipt["checks"]["both_runs_consumed_preflight_bound_bytes"] is True
|
|
assert receipt["cleanup"]["zero_staging_leftovers"] is True
|
|
assert receipt["cleanup"]["zero_orphan_containers"] is True
|
|
assert output.stat().st_mode & 0o777 == 0o600
|
|
assert json.loads(output.read_text(encoding="utf-8")) == receipt
|
|
|
|
|
|
def test_genesis_lifecycle_fails_closed_on_semantic_repeatability_drift(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
packet, dump, manifest, exporter_receipt = _mocked_genesis_case(tmp_path)
|
|
monkeypatch.setattr(lifecycle, "validate_genesis_inputs", _fake_validate_genesis)
|
|
|
|
def drifted_run(*_args, run_number: int, **_kwargs):
|
|
run = _fake_genesis_run(run_number)
|
|
if run_number == 2:
|
|
run["phases"]["applied"]["payload_controlled_fingerprint"]["sha256"] = "e" * 64
|
|
return run
|
|
|
|
monkeypatch.setattr(lifecycle, "run_lifecycle", drifted_run)
|
|
monkeypatch.setattr(
|
|
lifecycle,
|
|
"verify_run_group_cleanup",
|
|
lambda run_group: {"checked": True, "run_group": run_group, "container_names": [], "all_absent": True},
|
|
)
|
|
|
|
receipt = lifecycle.run_genesis_lifecycle(
|
|
packet,
|
|
tmp_path / "repeatability-drift-receipt.json",
|
|
review_action="approve",
|
|
genesis_dump=dump,
|
|
genesis_manifest=manifest,
|
|
genesis_exporter_receipt=exporter_receipt,
|
|
image=lifecycle.DEFAULT_GENESIS_IMAGE,
|
|
)
|
|
|
|
assert receipt["status"] == "fail"
|
|
assert receipt["checks"]["both_runs_passed"] is True
|
|
assert receipt["checks"]["both_runs_match_semantically"] is False
|
|
assert receipt["checks"]["identical_post_apply_fingerprints"] is False
|
|
assert len(set(receipt["repeatability"]["semantic_fingerprints_sha256"])) == 2
|
|
|
|
|
|
def test_genesis_lifecycle_fails_closed_on_orphan_cleanup(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
packet, dump, manifest, exporter_receipt = _mocked_genesis_case(tmp_path)
|
|
monkeypatch.setattr(lifecycle, "validate_genesis_inputs", _fake_validate_genesis)
|
|
monkeypatch.setattr(
|
|
lifecycle,
|
|
"run_lifecycle",
|
|
lambda *_args, run_number, **_kwargs: _fake_genesis_run(run_number),
|
|
)
|
|
monkeypatch.setattr(
|
|
lifecycle,
|
|
"verify_run_group_cleanup",
|
|
lambda run_group: {
|
|
"checked": True,
|
|
"run_group": run_group,
|
|
"container_names": ["orphaned-container"],
|
|
"all_absent": False,
|
|
},
|
|
)
|
|
|
|
receipt = lifecycle.run_genesis_lifecycle(
|
|
packet,
|
|
tmp_path / "failed-cleanup-receipt.json",
|
|
review_action="approve",
|
|
genesis_dump=dump,
|
|
genesis_manifest=manifest,
|
|
genesis_exporter_receipt=exporter_receipt,
|
|
image=lifecycle.DEFAULT_GENESIS_IMAGE,
|
|
)
|
|
|
|
assert receipt["status"] == "fail"
|
|
assert receipt["checks"]["zero_orphan_containers"] is False
|
|
|
|
|
|
@pytest.mark.skipif(not _docker_available(), reason="Docker daemon is required for the isolated lifecycle")
|
|
def test_disposable_postgres_lifecycle_end_to_end(tmp_path: Path) -> None:
|
|
packet = _write_source_packet(tmp_path)
|
|
output = tmp_path / "integrated-learning-receipt.json"
|
|
|
|
receipt = lifecycle.run_lifecycle(
|
|
packet,
|
|
output,
|
|
review_action="approve",
|
|
review_note="Approved exact fixture payload for isolated lifecycle regression coverage.",
|
|
)
|
|
|
|
assert receipt["status"] == "pass", receipt.get("error")
|
|
assert receipt["current_tier"] == "realistic_isolated_local_container_end_to_end"
|
|
assert receipt["phases"]["staged_pending_review"]["proposal"]["status"] == "pending_review"
|
|
assert receipt["phases"]["approved_unapplied"]["proposal"]["status"] == "approved"
|
|
assert receipt["phases"]["approved_unapplied"]["proposal"]["applied_at"] is None
|
|
assert receipt["phases"]["applied"]["proposal"]["status"] == "applied"
|
|
worker = receipt["phases"]["applied"]["worker_action"]
|
|
assert worker["report_only"]["expected_marker_present"] is True
|
|
assert worker["expected_retry_failure"]["returncode"] == 1
|
|
assert worker["retry_failure_count"] == 1
|
|
assert worker["failure_state_after_success"] == {}
|
|
assert worker["enabled_retry"]["expected_marker_present"] is True
|
|
assert worker["post_apply_exact_refusal"]["returncode"] == 1
|
|
assert worker["post_apply_exact_refusal"]["expected_refusal_marker_present"] is True
|
|
assert worker["private_receipt_mode"] == "0600"
|
|
assert receipt["phases"]["applied"]["apply_receipt"]["replay_ready"] is True
|
|
assert receipt["phases"]["recompiled_readback"]["matches_initial_compile"] is True
|
|
assert receipt["identities"]["evidence_ids"]
|
|
assert len(receipt["checks"]) >= 20
|
|
assert all(receipt["checks"].values())
|
|
assert receipt["cleanup"]["all"] is True
|
|
assert output.stat().st_mode & 0o777 == 0o600
|
|
assert json.loads(output.read_text(encoding="utf-8")) == receipt
|
|
|
|
|
|
def _build_real_docker_genesis(tmp_path: Path) -> tuple[Path, Path, Path]:
|
|
run_id = uuid.uuid4().hex[:10]
|
|
source = lifecycle.DisposablePostgres(
|
|
f"leo-real-genesis-source-{os.getpid()}-{run_id}",
|
|
"disposable-admin-password",
|
|
image=lifecycle.DEFAULT_GENESIS_IMAGE,
|
|
genesis_backed=True,
|
|
run_group=f"leo-real-genesis-source-{run_id}",
|
|
)
|
|
dump = tmp_path / "real-genesis.dump"
|
|
manifest_path = tmp_path / "real-genesis-manifest.jsonl"
|
|
exporter_receipt = tmp_path / "real-genesis-exporter-receipt.json"
|
|
try:
|
|
source.start()
|
|
source.psql(lifecycle.bootstrap_sql("review-password", "apply-password"))
|
|
source.psql(
|
|
"alter role kb_apply set statement_timeout to '17s';\n"
|
|
"alter role kb_review in database teleo set lock_timeout to '19s';"
|
|
)
|
|
manifest_output = source.psql(lifecycle.PARITY_SQL_PATH.read_text(encoding="utf-8"))
|
|
manifest_path.write_text(manifest_output + "\n", encoding="utf-8")
|
|
manifest_path.chmod(0o600)
|
|
container_dump = "/tmp/leo-real-genesis.dump"
|
|
source._run(
|
|
[
|
|
"exec",
|
|
source.name,
|
|
"pg_dump",
|
|
"-U",
|
|
"postgres",
|
|
"-d",
|
|
lifecycle.DATABASE,
|
|
"--format=custom",
|
|
"--compress=9",
|
|
"--no-owner",
|
|
f"--file={container_dump}",
|
|
]
|
|
)
|
|
source._run(["cp", f"{source.name}:{container_dump}", str(dump)])
|
|
dump.chmod(0o600)
|
|
loaded_manifest = lifecycle.load_manifest(manifest_path)
|
|
roles = {role["name"]: role for role in loaded_manifest["singleton"]["application_roles"]["items"]}
|
|
assert roles["kb_apply"]["settings"] == [{"name": "statement_timeout", "value": "17s"}]
|
|
assert roles["kb_review"]["database_settings"] == [{"name": "lock_timeout", "value": "19s"}]
|
|
_write_exporter_receipt(
|
|
exporter_receipt,
|
|
dump,
|
|
manifest_path,
|
|
loaded_manifest,
|
|
source={
|
|
"ssh_target": "disposable-docker-test",
|
|
"container": source.name,
|
|
"database": lifecycle.DATABASE,
|
|
"service": "disposable-postgres-test",
|
|
},
|
|
)
|
|
finally:
|
|
cleanup = source.cleanup()
|
|
assert all(
|
|
(
|
|
cleanup["container_absent"],
|
|
cleanup["name_readback_clear"],
|
|
cleanup["instance_label_readback_clear"],
|
|
cleanup["run_group_readback_clear"],
|
|
cleanup["network_mode_was_none"],
|
|
cleanup["tmpfs_data_dir_was_present"],
|
|
cleanup["docker_volume_mounts_observed"] == [],
|
|
)
|
|
)
|
|
return dump, manifest_path, exporter_receipt
|
|
|
|
|
|
@pytest.mark.skipif(not _docker_available(), reason="Docker daemon is required for the real genesis lifecycle")
|
|
def test_real_docker_genesis_restore_worker_parity_and_repeatability(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
packet = _write_source_packet(tmp_path)
|
|
dump, manifest, exporter_receipt = _build_real_docker_genesis(tmp_path)
|
|
receipt_payload = json.loads(exporter_receipt.read_text(encoding="utf-8"))
|
|
_trust_test_exporter_receipt(monkeypatch, exporter_receipt, receipt_payload)
|
|
output = tmp_path / "real-genesis-lifecycle-receipt.json"
|
|
|
|
receipt = lifecycle.run_genesis_lifecycle(
|
|
packet,
|
|
output,
|
|
review_action="approve",
|
|
review_note="Approved exact Docker genesis payload for regression coverage.",
|
|
genesis_dump=dump,
|
|
genesis_manifest=manifest,
|
|
genesis_exporter_receipt=exporter_receipt,
|
|
image=lifecycle.DEFAULT_GENESIS_IMAGE,
|
|
)
|
|
|
|
assert receipt["status"] == "pass", receipt.get("error")
|
|
assert receipt["execution"]["git_head"]
|
|
assert receipt["execution"]["engine_set_sha256"]
|
|
assert receipt["execution"]["engine_paths_match_head"] is True
|
|
assert receipt["execution"]["engine_sha256"] == receipt["execution"]["engine_head_sha256"]
|
|
assert receipt["pre_docker_validation"]["trusted_exporter_receipt_validated"] is True
|
|
assert receipt["pre_docker_validation"]["committed_engine_dependency_closure_verified"] is True
|
|
assert receipt["checks"]["both_runs_consumed_preflight_bound_bytes"] is True
|
|
assert receipt["checks"]["committed_engine_dependency_closure_verified"] is True
|
|
assert receipt["checks"]["portable_receipt_has_no_absolute_paths"] is True
|
|
assert lifecycle.absolute_path_value_pointers(receipt) == []
|
|
assert receipt["repeatability"]["identical_post_apply_fingerprints"] is True
|
|
assert len(set(receipt["repeatability"]["post_apply_fingerprints_sha256"])) == 1
|
|
assert receipt["cleanup"]["zero_orphan_containers"] is True
|
|
assert receipt["cleanup"]["zero_staging_leftovers"] is True
|
|
for run in receipt["runs"]:
|
|
assert run["status"] == "pass", run.get("error")
|
|
assert (
|
|
run["consumed_inputs"]["preflight_manifest_sha256"]
|
|
== receipt["immutable_staging"]["preflight_manifest_sha256"]
|
|
)
|
|
assert run["consumed_inputs"]["executing_git_head"] == receipt["execution"]["git_head"]
|
|
assert run["consumed_inputs"]["engine_set_sha256"] == receipt["execution"]["engine_set_sha256"]
|
|
assert run["database_initialization"]["genesis"]["parity"]["role_global_parity"]["status"] == "proven"
|
|
assert run["phases"]["applied"]["worker_action"]["retry_failure_count"] == 1
|
|
assert run["phases"]["applied"]["worker_action"]["private_receipt_mode"] == "0600"
|
|
assert output.stat().st_mode & 0o777 == 0o600
|
|
assert json.loads(output.read_text(encoding="utf-8")) == receipt
|