"""Adoption seam: Door A ingest is the shared llm-ingestion-okf library (§11). This repo's local ingest implementation was replaced by the shared library (first consumer adoption). These load-bearing tests bind the adapter seam: - Delegation — ``ingest.materialize`` IS a call into the library (RED if a local reimplementation sneaks back in). - Offline invariant — the adapter NEVER passes the per-run network opt-in: an http-source manifest is refused at the library's network gate (RED if the adapter starts granting network access). - Error contract — the consumer-facing error types ARE the library's typed hierarchy rooted in ``IngestError`` (RED if the seam re-wraps or forks). """ from __future__ import annotations import json from pathlib import Path from typing import Any import pytest import llm_ingestion_okf from portfolio_optimiser_claude import ingest INGESTED_AT = "2026-07-16T12:00:00Z" def _http_manifest() -> dict[str, Any]: return { "manifest_version": 1, "source": {"type": "http", "id": "api", "base_url": "https://example.invalid"}, "bundle_summary": "s", "extractions": [ {"id": "e", "title": "T", "query": "rows", "okf_type": "dataset", "max_rows": 1} ], } class TestDelegation: """Seam: the consumer entry points are the library's (RED if detached).""" def test_load_manifest_is_the_library_entry_point(self) -> None: assert ingest.load_manifest is llm_ingestion_okf.load_manifest def test_materialize_delegates_with_the_offline_default( self, monkeypatch: pytest.MonkeyPatch, tmp_path: Path ) -> None: calls: dict[str, Any] = {} def fake( manifest_path: Path, bundle_dir: Path, ingested_at: str, **kwargs: Any ) -> llm_ingestion_okf.IngestResult: calls["args"] = (manifest_path, bundle_dir, ingested_at) calls["kwargs"] = kwargs return llm_ingestion_okf.IngestResult(written=(tmp_path / "ingest-e.md",)) monkeypatch.setattr(ingest, "materialize_bundle", fake) out = ingest.materialize(tmp_path / "manifest.json", tmp_path / "bundle", INGESTED_AT) assert out == [tmp_path / "ingest-e.md"] # IngestResult.written → list, order kept assert calls["args"] == (tmp_path / "manifest.json", tmp_path / "bundle", INGESTED_AT) # The offline invariant at the seam: allow_network/http_get are NEVER # passed — the library's local-only default stays in force. assert calls["kwargs"] == {} class TestOfflineInvariant: """Seam: the adapter cannot grant network access (RED if it opts in).""" def test_http_source_is_refused_at_the_network_gate(self, tmp_path: Path) -> None: manifest = tmp_path / "manifest.json" manifest.write_text(json.dumps(_http_manifest()), encoding="utf-8") bundle = tmp_path / "bundle" with pytest.raises(ingest.NetworkGateError): ingest.materialize(manifest, bundle, INGESTED_AT) assert not bundle.exists() or not any(bundle.iterdir()) # gate fires before any write class TestErrorContract: """Seam: consumer-facing errors ARE the library hierarchy (RED if forked).""" def test_error_types_are_the_library_types(self) -> None: for name in ( "IngestError", "ManifestError", "MaterializationError", "NetworkGateError", "RenderError", "SourceError", ): assert getattr(ingest, name) is getattr(llm_ingestion_okf, name) def test_every_error_roots_in_ingest_error(self) -> None: for exc in ( ingest.ManifestError, ingest.MaterializationError, ingest.NetworkGateError, ingest.RenderError, ingest.SourceError, ): assert issubclass(exc, ingest.IngestError) class TestLibraryGuarantees: """K2.9 (R-3): library-side guarantees this consumer relies on, bound at the seam. Pre-adoption the local connector crashed mid-materialization on an empty CSV and left a PARTIAL bundle on disk (run-proven R-3). The library stages in memory, so the typed ``SourceError`` fires BEFORE the disk phase. Bound THROUGH the consumer entry point so a pin bump can never silently regress either guarantee. """ def test_empty_csv_fails_typed_before_any_disk_write(self, tmp_path: Path) -> None: case = tmp_path / "case" fixture = case / "fixture" fixture.mkdir(parents=True) (fixture / "e.csv").write_text("", encoding="utf-8") manifest = { "manifest_version": 1, "source": {"type": "file", "id": "arkiv", "root": "fixture"}, "bundle_summary": "s", "extractions": [ {"id": "e", "title": "T", "query": "e.csv", "okf_type": "dataset", "max_rows": 5} ], } manifest_path = case / "manifest.json" manifest_path.write_text(json.dumps(manifest), encoding="utf-8") bundle = tmp_path / "bundle" with pytest.raises(ingest.SourceError): ingest.materialize(manifest_path, bundle, INGESTED_AT) assert not bundle.exists() # never a partial bundle (in-memory staging) def test_non_select_sql_fails_typed_with_no_partial_bundle( self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: import sqlite3 db = tmp_path / "src.sqlite" con = sqlite3.connect(db) con.execute("CREATE TABLE t (a INTEGER)") con.commit() con.close() monkeypatch.setenv("SRC_DSN", str(db)) manifest = { "manifest_version": 1, "source": {"type": "sql", "id": "db", "connection_ref": "SRC_DSN"}, "bundle_summary": "s", "extractions": [ {"id": "e", "title": "T", "query": "BEGIN", "okf_type": "dataset", "max_rows": 5} ], } manifest_path = tmp_path / "manifest.json" manifest_path.write_text(json.dumps(manifest), encoding="utf-8") bundle = tmp_path / "bundle" with pytest.raises(ingest.SourceError, match="returned no columns"): ingest.materialize(manifest_path, bundle, INGESTED_AT) assert not bundle.exists()