From the PR #422 Copilot re-review (suppressed comment, src/aorta/chat/rag/embeddings/base.py:64). Verified live on 1090cd26.
def build_collection_name(prefix: str, model: str) -> str:
return (prefix + model_slug(model))[:MAX_COLLECTION_NAME].rstrip("_")
model_slug folds every non-alphanumeric run to _, then the result is truncated. Two consequences:
- Punctuation variants collapse.
org/model-v1 and org/model.v1 slug identically.
- Long ids collide on their prefix. Two models sharing the first
MAX_COLLECTION_NAME characters of their slug get the same sqlite collection.
The provider contract is that model identity separates vector spaces -- different models have different dimensions and are not mutually queryable -- so a collision means rebuilding for one model silently resets the other's collection, and in the equal-dimension case queries return vectors from the wrong model without any error.
Fix: include a short stable digest of the full model id in the name (e.g. f"{prefix}{slug[:N]}_{sha256(model)[:8]}"), so truncation stays cosmetic and identity stays exact. Note the manifest compatibility check added in #422 catches a mismatched index but not a collided one, since the manifest would name whichever model wrote last.
Needs a migration thought (existing collections change name), which is why it is not in #422.
From the PR #422 Copilot re-review (suppressed comment,
src/aorta/chat/rag/embeddings/base.py:64). Verified live on1090cd26.model_slugfolds every non-alphanumeric run to_, then the result is truncated. Two consequences:org/model-v1andorg/model.v1slug identically.MAX_COLLECTION_NAMEcharacters of their slug get the same sqlite collection.The provider contract is that model identity separates vector spaces -- different models have different dimensions and are not mutually queryable -- so a collision means rebuilding for one model silently resets the other's collection, and in the equal-dimension case queries return vectors from the wrong model without any error.
Fix: include a short stable digest of the full model id in the name (e.g.
f"{prefix}{slug[:N]}_{sha256(model)[:8]}"), so truncation stays cosmetic and identity stays exact. Note the manifest compatibility check added in #422 catches a mismatched index but not a collided one, since the manifest would name whichever model wrote last.Needs a migration thought (existing collections change name), which is why it is not in #422.