fix: harden model catalog projections

This commit is contained in:
Codex
2026-09-02 19:25:01 +02:00
parent ce4c31a6fb
commit a6a5bf2036
38 changed files with 573 additions and 83 deletions
+57 -5
View File
@@ -214,7 +214,7 @@ embeddings: {provider: ollama_internal, base_url: http://embedding:11434, model:
assert cfg.vectors.writer.api_key == "writer"
def test_accepts_only_internal_ollama_embedding_contract(tmp_path):
def test_accepts_catalog_selected_internal_ollama_embedding_contract(tmp_path):
workspace = tmp_path / "workspace.yaml"
workspace.write_text(
"""
@@ -225,8 +225,9 @@ resources:
embeddings:
provider: ollama_internal
base_url: http://embedding:11434
model: qwen3-embedding:0.6b
dimensions: 1024
id: ollama/bge-m3
model: bge-m3
dimensions: 1536
"""
)
@@ -234,8 +235,59 @@ resources:
assert cfg.embeddings.provider == "ollama_internal"
assert cfg.embeddings.base_url == "http://embedding:11434"
assert cfg.embeddings.model == "qwen3-embedding:0.6b"
assert cfg.embeddings.dim == 1024
assert cfg.embeddings.id == "ollama/bge-m3"
assert cfg.embeddings.model == "bge-m3"
assert cfg.embeddings.dim == 1536
def test_installation_embedding_projection_completes_model_free_runtime_source(
tmp_path, monkeypatch,
):
monkeypatch.setenv("THT_INTERNAL_EMBEDDING_ID", "ollama/bge-m3")
monkeypatch.setenv("THT_INTERNAL_EMBEDDING_MODEL", "bge-m3")
monkeypatch.setenv("THT_INTERNAL_EMBEDDING_DIMENSIONS", "1536")
workspace = tmp_path / "workspace.yaml"
workspace.write_text(
"""
dwh:
type: postgres_direct
connection: {database: analytics, schema: mart, user: reader, password: secret}
resources:
embeddings:
provider: ollama_internal
base_url: http://embedding:11434
"""
)
cfg = load_config(workspace)
assert cfg.embeddings.id == "ollama/bge-m3"
assert cfg.embeddings.model == "bge-m3"
assert cfg.embeddings.dim == 1536
def test_workspace_embedding_values_cannot_override_installation_projection(
tmp_path, monkeypatch,
):
monkeypatch.setenv("THT_INTERNAL_EMBEDDING_ID", "ollama/bge-m3")
monkeypatch.setenv("THT_INTERNAL_EMBEDDING_MODEL", "bge-m3")
monkeypatch.setenv("THT_INTERNAL_EMBEDDING_DIMENSIONS", "1536")
workspace = tmp_path / "workspace.yaml"
workspace.write_text(
"""
dwh:
type: postgres_direct
connection: {database: analytics, schema: mart, user: reader, password: secret}
resources:
embeddings:
provider: ollama_internal
base_url: http://embedding:11434
model: workspace-owned-model
"""
)
with pytest.raises(ConfigError, match="proprietà dell'installazione|diverge"):
load_config(workspace)
def test_accepts_internal_qdrant_resource_contract(tmp_path):
+21
View File
@@ -40,6 +40,7 @@ def test_manifest_contains_provenance_without_credentials():
manifest_id="manifest:abc",
created_at=datetime(2026, 7, 12, tzinfo=UTC),
pipeline_version="evidence-v1",
embedding_id="ollama/nomic-embed-text",
embedding_model="nomic-embed-text",
embedding_dimensions=768,
documents=[document()],
@@ -52,6 +53,7 @@ def test_manifest_contains_provenance_without_credentials():
assert "etag:abc" in payload
assert "evidence-v1" in payload
assert "nomic-embed-text" in payload
assert '"embedding_id":"ollama/nomic-embed-text"' in payload
assert "api_key" not in payload
@@ -93,6 +95,25 @@ def test_manifest_validates_embedding_compatibility_fields():
)
def test_schema_v1_manifest_without_canonical_embedding_id_remains_readable():
manifest = CorpusManifest.model_validate({
"schema_version": 1,
"embedding_model": "legacy-model",
"embedding_dimensions": 768,
})
assert manifest.embedding_id is None
def test_schema_v2_embedding_generation_requires_canonical_id():
with pytest.raises(ValidationError, match="embedding_id"):
CorpusManifest(
schema_version=2,
embedding_model="model-v2",
embedding_dimensions=768,
)
def test_canonical_metadata_rejects_secrets_and_non_json_values():
with pytest.raises(ValidationError, match="credential-like"):
CanonicalDocument.model_validate(
+21 -1
View File
@@ -105,11 +105,13 @@ def item(name, fingerprint):
)
def pipeline(tmp_path, source, *, embedder=None, vectors=None, model="model-a", policy=None,
def pipeline(tmp_path, source, *, embedder=None, vectors=None, model="model-a",
embedding_id=None, policy=None,
retain=3, candidate_evaluator=None):
return CorpusPipeline(
store=CorpusStore(tmp_path / "corpus"), sources=[source],
embedder=embedder or Embedder(), vector_store=vectors or Vectors(),
embedding_id=embedding_id,
embedding_model=model, embedding_dimensions=3,
chunk_policy=policy or ChunkPolicy(version="chunk-v1", max_chars=100),
pipeline_version="evidence-v1",
@@ -875,6 +877,24 @@ def test_model_or_chunk_policy_change_forces_full_rebuild(tmp_path):
assert source.acquire_calls == ["fs:one"]
def test_canonical_embedding_id_change_forces_full_rebuild_and_is_persisted(tmp_path):
one = item("one", "a")
first = pipeline(
tmp_path, Source([(one, "hello")]), model="same-upstream",
embedding_id="ollama/catalog-a",
).run()
assert first.manifest.embedding_id == "ollama/catalog-a"
source = Source([(one, "hello")])
changed = pipeline(
tmp_path, source, model="same-upstream", embedding_id="ollama/catalog-b",
).run()
assert changed.changed == ("fs:one",)
assert changed.manifest.embedding_id == "ollama/catalog-b"
assert source.acquire_calls == ["fs:one"]
def test_partial_vector_failure_never_changes_active_or_exposes_generation(tmp_path):
one = item("one", "a")
good = pipeline(tmp_path, Source([(one, "old")]))
+16 -2
View File
@@ -21,7 +21,8 @@ def _write_cfg(tmp_path, raw):
return cfg
def _cfg(tmp_path, *, transport="thoth_rest", base_url="http://dwh.example.invalid", collection="psd", model="qwen3-embedding:0.6b"):
def _cfg(tmp_path, *, transport="thoth_rest", base_url="http://dwh.example.invalid",
collection="psd", model="qwen3-embedding:0.6b", dimensions=1024):
return {
"schemaVersion": 1,
"workspace": {"schema_version": 3, "id": "psd", "name": "PSD", "language": "it"},
@@ -34,7 +35,10 @@ def _cfg(tmp_path, *, transport="thoth_rest", base_url="http://dwh.example.inval
"connection": {"host": "h", "port": 5432, "database": "warehouse", "schema": "dw", "user": "reader", "password": "secret"},
},
"vectors": {"type": "qdrant", "base_url": "http://qdrant:6333", "collection": collection, "collection_lifecycle": "self_heal"},
"embeddings": {"provider": "ollama_internal", "base_url": "http://embedding:11434", "model": model, "dimensions": 1024},
"embeddings": {
"provider": "ollama_internal", "base_url": "http://embedding:11434",
"id": f"ollama/{model}", "model": model, "dimensions": dimensions,
},
"roots": {"artifacts": str(tmp_path / "artifacts"), "indexes": str(tmp_path / "indexes")},
"paths": {"artifacts": str(tmp_path / "artifacts"), "indexes": str(tmp_path / "indexes"), "sessions": str(tmp_path / "sessions")},
}
@@ -52,6 +56,16 @@ def test_canonical_json_is_deterministic_and_key_ordered(cfg):
assert keys == ["schemaVersion", "dwh", "vector", "embedding", "roots"]
def test_catalog_embedding_identity_and_dimensions_drive_effective_config(tmp_path):
cfg = _write_cfg(tmp_path, _cfg(tmp_path, model="bge-m3", dimensions=1536))
document = __import__("json").loads(canonical_effective_config_json(cfg))
assert document["embedding"] == {
"id": "ollama/bge-m3", "model": "bge-m3", "dimensions": 1536,
}
assert document["vector"]["dimensions"] == 1536
def test_canonical_excludes_credentials_and_evidence(cfg):
doc = canonical_effective_config_json(cfg)
assert "secret" not in doc
@@ -149,6 +149,7 @@ def test_preprocessing_factory_forwards_only_evidence_pipeline_dependencies(monk
"sources": [object()],
"embedder": object(),
"vector_store": object(),
"embedding_id": "ollama/model",
"embedding_model": "model",
"embedding_dimensions": 3,
"chunk_policy": object(),
+2
View File
@@ -10,6 +10,8 @@ from tht.config import EmbeddingsConfig
def _cfg(**kw):
kw.setdefault("model", "nomic-embed-text-v2-moe")
kw.setdefault("dim", 768)
emb = EmbeddingsConfig(base_url="http://localhost:11434", **kw)
return SimpleNamespace(embeddings=emb)
+3
View File
@@ -284,6 +284,7 @@ def test_run_from_config_uses_runtime_identity_workspace_id(monkeypatch, tmp_pat
sources,
embedder,
vector_store,
embedding_id,
embedding_model,
embedding_dimensions,
chunk_policy,
@@ -293,6 +294,7 @@ def test_run_from_config_uses_runtime_identity_workspace_id(monkeypatch, tmp_pat
candidate_evaluator,
):
calls["init"] = {
"embedding_id": embedding_id,
"embedding_model": embedding_model,
"embedding_dimensions": embedding_dimensions,
"pipeline_version": pipeline_version,
@@ -314,6 +316,7 @@ def test_run_from_config_uses_runtime_identity_workspace_id(monkeypatch, tmp_pat
command.run_from_config(config)
assert calls["init"]["embedding_id"] == "ollama/qwen3-embedding:0.6b"
assert calls["init"]["sparse_language"] == "english"
assert calls["init"]["candidate_evaluator"] is None
assert calls["run_as_job"]["workspace_id"] == "psd-clinical"