Skip to content

Data Models

This page documents every field of every core domain model. The models are Pydantic v2 types. They travel through the pipeline, serialize into index.json, and seal into a .indx archive. For a concept-level tour of how these objects fit together, see Core objects.

A few rules apply across all models:

  • Identifiers are stable strings generated from deterministic input such as relative path and position. In the current implementation they are short SHA-256-derived hashes, for example a3f4..., not sequential counters. Re-running over unchanged input yields identical ids.
  • Vectors are list[float]. They are 32-bit floats in the on-disk matrix and plain Python floats in memory.
  • Free-form metadata is typed dict[str, Any]. It is serialized with sorted keys for diff-friendly output.

Typed graph edges between documents and/or chunks. RelationType is a str enum, so its members serialize to their string values.

class RelationType(str, Enum):
SIBLING = "sibling" # same folder / same logical group
PARENT = "parent" # folder lineage / containment
REFERENCES = "references" # outgoing citation, link, or mention
CONTINUES = "continues" # next unit in a split sequence
DUPLICATE_OF = "duplicate-of" # near/exact duplicate content
ValueMeaning
siblingSame folder or same logical group.
parentFolder lineage / containment.
referencesOutgoing citation, link, or mention.
continuesNext unit in a split sequence.
duplicate-ofNear or exact duplicate content.

Provenance of a chunk or parsed unit — where the content came from in the walked tree.

FieldTypeDescription
pathstrOriginal file path, relative to the walked root. Required.
folderstrContaining folder, relative to root. Defaults to "".
typestr | NoneDetected or enriched document type, e.g. "policy". Defaults to None until enrichment or type detection fills it.
class Source(BaseModel):
path: str
folder: str = ""
type: str | None = None

A typed, directed edge in the knowledge graph. A Relation may connect chunk-to-document, document-to-document, or chunk-to-chunk ids.

The current implementation stores an explicit src and dst for every edge, so relations remain self-contained when serialized or moved between collections.

FieldTypeDefaultDescription
srcstr— (required)Source id or path.
dststr— (required)Target id or path.
typeRelationType— (required)The kind of edge.
scorefloat1.0Confidence / similarity score in [0, 1] where applicable.
class Relation(BaseModel):
src: str
dst: str
type: RelationType
score: float = 1.0

The raw output of a Parser for a single source file. It is produced in stage 02 Parse, before chunking. It carries ordered structural blocks; text is exposed as a property that joins block text in order. Returned by Parser.parse(file) -> ParsedDoc.

FieldTypeDefaultDescription
source_pathstr— (required)Source file path relative to the walked root.
parserstrplaintextParser implementation that produced the record.
parser_versionstr0Parser version string recorded for reproducibility.
blockslist[Block][]Ordered structural blocks: headings, paragraphs, table cells, captions, code, and similar units.
text (property)strderivedNormalized full-text rendering, joined from blocks in order.
class ParsedDoc(BaseModel):
source_path: str
parser: str = "plaintext"
parser_version: str = "0"
blocks: list[Block] = []

A retrievable unit of content. A Chunk remembers its source document, its position within that document, the ids of its immediate neighbor chunks, and any typed relations.

The embedding vector is populated in stage 06 Embed+Pack. It is typically not inlined into index.json; it lives in embeddings/.

FieldTypeDefaultDescription
idstr— (required)Stable id generated from document id and position.
textstr— (required)The retrievable text payload.
doc_idstr— (required)Id of the parent Document.
positionint— (required)0-based position within the parent document.
prev_idstr | NoneNonePrevious chunk id, when one exists.
next_idstr | NoneNoneNext chunk id, when one exists.
sourceSource | NoneNoneOriginating document provenance.
index (property)intderivedAlias of position.
metadatadict[str, Any]{}Enriched values: topics, summary, tags.
neighborslist[str][]Adjacent chunk ids (previous, next).
relationslist[Relation][]Outgoing typed edges from this chunk.
embeddinglist[float] | NoneNoneVector, populated in stage 06. May be omitted from index.json.
class Chunk(BaseModel):
id: str
doc_id: str
position: int
text: str
prev_id: str | None = None
next_id: str | None = None
embedding: list[float] | None = None
source: Source | None = None
metadata: dict[str, Any] = {}
relations: list[Relation] = []

One source file, enriched. A Document holds:

  • Folder lineage and detected type.
  • LLM-derived topics, tags, and summary from stage 05 Enrich.
  • Resolved outgoing and incoming references from stage 04 Relate.
FieldTypeDefaultDescription
idstr— (required)Stable id generated from the relative path.
pathstr— (required)Original path relative to root.
lineagelist[str][]Folder ancestry, root→leaf.
size_bytesint0Source file size in bytes.
doc_typestr | NoneNoneDetected / enriched document type.
type (property)str | NonederivedAlias of doc_type.
folder (property)strderivedContaining folder, joined from lineage.
topicslist[str][]Enrichment-derived topics.
tagslist[str][]Enrichment-derived tags.
summarystr | NoneNoneEnrichment-derived summary.
chunk_idslist[str][]Chunks produced from this document, in order.
referenceslist[Relation][]Outgoing references resolved in stage 04.
referenced_bylist[Relation][]Incoming references (reverse edges).
metadatadict[str, Any]{}Free-form additional metadata.
class Document(BaseModel):
id: str
path: str
lineage: list[str] = []
size_bytes: int = 0
doc_type: Optional[str] = None
topics: list[str] = []
tags: list[str] = []
summary: Optional[str] = None
chunk_ids: list[str] = []
references: list[Relation] = []
referenced_by: list[Relation] = []
metadata: dict[str, Any] = {}

Aggregate counts surfaced via space.stats. The same shape appears under the stats key of index.json and is what indx inspect --json emits.

FieldTypeDefaultDescription
documentsint— (required)Number of documents.
chunksint— (required)Number of chunks.
relationsint— (required)Number of relations.
embeddingsint— (required)Number of stored vectors.
embed_dimint | NoneNoneVector dimensionality, e.g. 1024 for bge-m3.
typesdict[str, int]{}Document count per detected type.
bytes_sourceint0Total bytes of source material walked.
class SpaceStats(BaseModel):
documents: int
chunks: int
relations: int
embeddings: int
embed_dim: Optional[int] = None
types: dict[str, int] = {}
bytes_source: int = 0

A single result from space.search(...). It exposes the matched chunk, its neighbor chunks (resolved into full Chunk objects for context windows), and a convenience source property.

FieldTypeDefaultDescription
chunkChunk— (required)The matched chunk.
scorefloat— (required)Similarity score; higher is better.
neighborslist[Chunk][]Resolved neighbor chunks of chunk.
source (property)Source | NonederivedProvenance of the matched chunk — shorthand for hit.chunk.source.
class SearchHit(BaseModel):
chunk: Chunk
score: float
neighbors: list[Chunk] = []
@property
def source(self) -> Source | None:
return self.chunk.source

The top-level result of processing a directory. It holds the document graph, chunks, relations, and metadata, and serializes to a single portable .indx archive. Beyond its data fields, KnowledgeSpace provides first-class accessors for stats, document filtering, semantic search, and load/save.

FieldTypeDefaultDescription
manifestManifestdefault manifestSchema version, indx version, source root, selected components, embedding model, and embedding dimension.
documentslist[Document][]The document graph. (Stored internally as documents_ with a property shim; the public callable is documents(type=...) below.)
chunkslist[Chunk][]All chunks in the space.
relationslist[Relation][]Graph-level edges (optional mirror of per-object edges).
space.stats # -> SpaceStats
space.documents(type="policy") # -> list[Document], optionally filtered
space.search("how long is data retained?", k=5) # -> list[SearchHit]
KnowledgeSpace.load(archive) # classmethod -> KnowledgeSpace
space.save(archive) # -> None

Full signatures, behavior, and examples for these methods live in the SDK reference.

The shared, mutable carrier threaded through every pipeline stage. Each stage receives this object and returns the same object, mutated — run(ctx: SpaceContext) -> SpaceContext. Earlier stages populate collections that later stages read; see Pipeline and stages for the full flow.

SpaceContext sets model_config = {"arbitrary_types_allowed": True} so custom stages can attach runtime objects without fighting Pydantic validation.

FieldTypeDefaultDescription
rootPath— (required)Path being processed.
seedint0Deterministic seed for ordering, sampling, and test fixtures.
spaceKnowledgeSpaceempty spaceThe accumulated document graph, chunks, relations, and manifest.
parseddict[str, ParsedDoc]{}02 Parsedoc_idParsedDoc.
errorslist[StageErrorRecord][]Non-fatal per-item failures. --strict promotes these to fatal pipeline errors.

Most stage output is accumulated inside ctx.space:

FieldTypeDefaultDescription
CollectionPopulated byNotes
---------
ctx.space.documents_01 Walk onwardSource documents, then enrichment fields.
ctx.parsed02 ParseParser output keyed by document id.
ctx.space.chunks03 Chunk onwardRetrievable chunks with neighbor ids.
ctx.space.relations04 RelateGraph-level edges.
ctx.errorsany stagePer-item skips and fatal diagnostics.

The pipeline returns ctx.space, which is the KnowledgeSpace that writers serialize and the .indx archive seals.