Storage: PostgreSQL (chunk rows + manifests) and Neo4j
-
PostgreSQL
Chunk rows with provenance, chunk summaries, caches, and the generation manifest.
-
Qdrant
Per-corpus Qdrant generations hold the dense and sparse chunk vectors both retrieval legs query.
-
Neo4j
Generation-scoped entities and relationships linked to chunks (
FROM_CHUNK), plus GDS Leiden communities.
One Postgres, Many Corpora
Partition by repo_id/corpus_id in schema to keep corpus isolation at the data layer.
TSConfig
indexing.postgres_ts_config resolves the text search config (simple or a stemmer language) based on tokenizer settings.
Neo4j Isolation
neo4j_database_mode=per_corpus avoids expensive cross-corpus filters but requires Enterprise Edition.
PostgreSQL Client Responsibilities
- Upsert chunk rows with metadata, content, and provenance
- Store the generation manifest (Qdrant collection + Neo4j graph id) and the dense/sparse contracts
- Serve chunk hydration for every retrieval leg
Neo4j Client Responsibilities
- Resolve the corpus database (per mode)
- Store generation-scoped entities, relationships, and
FROM_CHUNKchunk links - Derive GDS Leiden communities at index time when
graph_storage.include_communitiesis on - Serve entity traversal seeded from the manifest's Qdrant generation
Concept diagram (where each artifact lives only — the retrieval flow is on the generated retrieval-pipeline page):
flowchart LR
CH["Chunks + provenance"] --> PG["PostgreSQL"]
MAN["Generation manifest"] --> PG
VEC["Dense + sparse vectors"] --> QD["Qdrant"]
ENT["Entities"] --> NEO["Neo4j"]
REL["Relationships"] --> NEO
COM["GDS Leiden communities"] --> NEO Configuration Hooks
| Section | Field(s) | Meaning |
|---|---|---|
| indexing | postgres_url | DSN for Postgres |
| graph_storage | neo4j_uri, neo4j_user, neo4j_password | Neo4j connectivity |
| graph_storage | neo4j_database_mode, neo4j_database_prefix | DB isolation strategy |
| graph_indexing | enabled, build_code_graph | Derived graph policy selection |
# Resolve Neo4j database name for a corpus (1)!
from server.models.tribrid_config_model import GraphStorageConfig
print(GraphStorageConfig().resolve_database("dev_corpus"))
- Uses prefix + sanitized corpus id in per_corpus mode
Qdrant vectors
Dense and sparse vectors live in per-corpus Qdrant generations; the corpus manifest names the physical collection and the contracts they were built under.