Artifact-Backed Indexes
Build full-text, vector, and graph indexes over one or more generated artifact streams
Overview
An artifact-backed index consumes records produced by named enrichments. The
canonical sources array can union up to 64 streams in one full-text, embeddings,
or graph index. Each source member has the stable identity (artifact, key), so
records from different streams cannot collide even when their keys match.
Check deployment support before offering this workflow:
curl http://localhost:8080/db/v1/status
index_capabilities.artifact_sources must be true. Embedded, standalone, and
distributed deployments support artifact sources. Serverless rejects them and
does not emulate older artifact-index behavior.
Document And Chunk Vectors In One Index
This pattern closes the gap between one document-level semantic field and the more precise chunks produced by document extraction. Both embedding enrichments must have compatible dimensions and semantic vector spaces.
{
"type": "embeddings",
"dimension": 768,
"sources": [
{ "artifact": "document_dense_v1" },
{ "artifact": "document_chunk_dense_v1" }
],
"enrichments": [
{
"name": "document_chunks_v1",
"kind": "chunk",
"field": "semantic_content",
"chunk_size": 512
},
{
"name": "document_dense_v1",
"kind": "embedding",
"field": "semantic_content",
"expected_dims": 768,
"vector_space": "searchaf:v1"
},
{
"name": "document_chunk_dense_v1",
"kind": "embedding",
"field": "text",
"source_artifact_name": "document_chunks_v1",
"expected_dims": 768,
"vector_space": "searchaf:v1"
}
]
}
Create it at POST /db/v1/tables/{table}/indexes/document_vectors. The
vector_space value is an application-owned compatibility identifier. Every
source in a multi-source index must either use the same explicit identifier or
use semantically identical producer configurations; explicit and implicit modes
cannot be mixed.
Query document_vectors through the normal semantic search API. Raw member
results retain artifact identity. Use hierarchy grouping when the UI needs one
source document with matching chunks nested beneath it; request the documented
top-level field projection when grouping.
Full-Text Sources With Different Shapes
A shared top-level field is inherited by every source that does not override
it. A source-local field supports unions whose artifact records use different
JSON shapes:
{
"type": "full_text",
"field": "text",
"sources": [
{ "artifact": "document_units_v1", "field": "summary" },
{ "artifact": "document_chunks_v1" }
]
}
Here document_units_v1 indexes summary, while document_chunks_v1 inherits
text. If neither level specifies a field, Antfly uses the default text
projection. Missing, null, and non-text values add no postings.
To query a named full-text index, set full_text_index together with
full_text_search or a scoring text clause in the recursive query AST:
{
"full_text_index": "document_text",
"full_text_search": { "query": "retrieval augmented generation" },
"limit": 10
}
Filter-only and exclusion-only query trees are not scoring text queries and
receive HTTP 422 when combined with full_text_index.
Graph Sources
Graph sources are ordered. When two sources materialize the same edge identity,
the earlier source wins. Mapping (path, format, nodes, edge, and
context) belongs on each source because streams can use different record
shapes. The optional source object is the one-source convenience form and is
mutually exclusive with sources.
Artifact-backed edges are owned by the source document key; nodes.target
maps the other endpoint. Source ownership is intentionally not configurable,
so replay, deletion, routing, and range splits share one identity contract.
Outgoing traversal routes directly to that source owner. Incoming and
bidirectional traversal use an exact, bounded coordinator route directory
fenced by the table topology and per-shard read generations. A cold or
generation-mismatched entry falls back to compact, bounded reverse-index probes
and records the proven source shards; expansion is then sent only to those
shards. This preserves exact cross-range paths without synchronous cross-shard
dual writes, while repeated traversals avoid cluster-wide probe fanout.
Readiness And Operations
Creation starts materialization and replay; it does not imply complete coverage.
Poll GET /db/v1/tables/{table}/indexes/{index} and use
readiness.queryable for serving eligibility and readiness.complete for full
coverage. pending_reasons provides typed aggregate blockers or failure reasons.
Artifact-backed indexes also return readiness.sources in configuration order.
Each entry identifies the artifact stream and reports its state, completeness,
and typed blockers, so operators can distinguish (for example) document-vector
lag from chunk-vector lag without inspecting internal replay state. Internal
replay watermarks remain diagnostics; use queryable and complete as the
serving and convergence authorities.
Every index kind reports a catalog-assigned incarnation at both the status
root and in readiness. A waiter succeeds only from a runtime observation for
that same semantic definition, so dropping and recreating a full-text, graph,
algebraic, or embeddings index under the same name cannot reuse stale
readiness or searchable counts.
Changing source membership, projection fields, analyzer semantics, embedding space, or graph mapping changes index semantics and requires a new materialized generation. Execution batching fields tune work but do not change artifact identity.
API Names And Compatibility
sources is the canonical multi-source API. The following are supported
one-source alternatives, not deprecated aliases: full-text artifact_name,
embeddings embedding_name, and graph source. Normalized responses expose
canonical sources where the released contract requires it.
The released v0.2 embeddings fields remain supported for v0.2 compatibility;
no removal release is currently scheduled. source_artifact_name is descriptive
when paired with embedding_name; the matching enrichment is authoritative.
Internal graph manifest and edge materialization fields are engine-owned, not
alternate public APIs. No graph status aliases were released, and the unreleased
Go v0.2 SDK surface does not create an additional compatibility obligation.