"""F-05: refuse to become ready on a corpus/model manifest mismatch. Two different embedding models can produce vectors of the same dimensionality; Qdrant returns plausible-looking but meaningless nearest neighbours with no error at query time — a stale or wrong collection is otherwise invisible until a clinician notices the answers are subtly off. The ingestion loader already writes a sidecar manifest recording what a collection was built from (`ingestion/ingestion/load/manifest.py`); this is the query-time half — compare it against the configured query embedder *before* serving anything, not after a bad answer is reported. """ from __future__ import annotations MANIFEST_POINT_ID = "00000000-0000-5000-8000-000000000001" class ManifestMismatch(RuntimeError): """The configured query embedder does not match what the collection was built from. Raised at startup so the service refuses to become ready rather than search with mismatched vectors.""" def manifest_collection(name: str) -> str: return f"{name}__manifest" def check_manifest( payload: dict | None, collection: str, expected_model_id: str, expected_dimensions: int, ) -> None: """Raises `ManifestMismatch` unless `payload` (the manifest sidecar point's payload, or `None` if the sidecar/point is missing entirely) matches the configured query embedder. A collection with no manifest at all is refused for the same reason a mismatched one is: nothing can be said about what it was built from, and "probably fine" is not a load-bearing claim for a medical formulary. """ if payload is None: raise ManifestMismatch( f"{collection!r} has no corpus manifest " f"({manifest_collection(collection)!r}) — refusing to query an " "unattested corpus." ) mismatches = [] if payload.get("model_id") != expected_model_id: mismatches.append( f"model_id: corpus={payload.get('model_id')!r} " f"query_embedder={expected_model_id!r}" ) if payload.get("dimensions") != expected_dimensions: mismatches.append( f"dimensions: corpus={payload.get('dimensions')!r} " f"query_embedder={expected_dimensions!r}" ) if mismatches: raise ManifestMismatch( f"{collection!r}'s corpus manifest does not match the configured " "query embedder — " + "; ".join(mismatches) )