Question | Definition field | What it controls |
|---|---|---|
What kind of index is this? | kind | The storage format and query path: path, metadata filter, typed JSON, full text, vector, or hybrid. |
Which source records are eligible? | selector_json | Build-time source selection, usually by object key or append stream prefix and content type. |
What data is extracted? | extractor_json and build_policy_json | Text fields, typed fields, vector provenance, tokenisation, ANN settings, and related build options. |
Who may see query hits? | authorization_mode | Whether the query path also checks object-level read visibility for each hit. |
Field | Type | Notes |
|---|---|---|
bucket_name | string | Tenant bucket that owns the index and the source records. |
name | string | Index name within the bucket. It is used in later list, query, update, disable, diagnostics, and drop calls. |
kind | enum | INDEX_KIND_PATH, INDEX_KIND_METADATA_FILTER, INDEX_KIND_FULL_TEXT, INDEX_KIND_VECTOR, INDEX_KIND_HYBRID, INDEX_KIND_PERSONALDB_ROW_METADATA, INDEX_KIND_GIT_SOURCE, or INDEX_KIND_TYPED_JSON. |
selector_json | JSON string | Parsed as JSON. {} and null usually mean all records of the source kind. |
extractor_json | JSON string | Parsed as JSON. Used mainly by full text and the text side of hybrid. For vector, the real extractor is in build_policy_json. |
authorization_mode | string | The field name is American-spelled in the API. Supported values are inherit_object, index_only, and public. |
build_policy_json | JSON string | Parsed as JSON. Strictly validated for full-text, vector, hybrid, and typed JSON indexes. |
anvil --profile acme index create documents by_state typed-json \
--selector-json '{"prefix":"cases/"}' \
--build-policy-json '{"source_kind":"object_current","fields":[{"name":"state","extractor":"/state"}]}'
let request = anvil_api::CreateIndexRequest {
bucket_name: "documents".to_string(),
name: "by_state".to_string(),
kind: anvil_api::IndexKind::TypedJson as i32,
selector_json: r#"{"prefix":"cases/"}"#.to_string(),
extractor_json: "{}".to_string(),
authorization_mode: "inherit_object".to_string(),
build_policy_json: r#"{
"source_kind":"object_current",
"fields":[{"name":"state","extractor":"/state"}]
}"#.to_string(),
};
CLI kind | Stored kind | Use it for | Current behaviour and limitations |
|---|---|---|---|
path | path | Fast prefix-style object discovery over current object metadata. | Query with path_prefix; optional metadata equality filters can narrow results. Scores are constant. |
metadata, metadata-filter, metadata_filter | metadata_filter | Object metadata equality filters. | Uses the same current-object metadata segment as path. The service rejects an empty metadata-filter string, but {} is currently accepted, so supply at least one filter for the intended semantics. |
typed-json, typed_json | typed_json | Equality, range, existence, and ordered queries over named JSON values from object bodies or append records. | No relevance scoring. Direct typed queries do not use metadata_filters_json. Current field types are inferred from JSON values, not declared in the definition. |
full-text, full_text, fulltext | full_text | Token-based text search over extracted object text. | query_text is a plain text string, not a boolean query language. Phrase queries require positions in the build policy. |
vector | vector | Nearest-neighbour search over extracted or provider-generated vectors. | query_vector must match the configured dimension. Text embedding through a provider requires server configuration, except the deterministic test_only provider when explicitly enabled. |
hybrid | hybrid | Combining full-text and vector signals in one index. | Accepts text, vector, or both. Weights are currently fixed by the service, not caller-configurable. |
personaldb-row-metadata, personaldb_row_metadata | personaldb_row_metadata | Reserved PersonalDB row-metadata index kind. | Accepted by the generic definition API, but not materialised or queried by the generic index builder path today. Use PersonalDB-specific surfaces where available. |
git-source, git_source | git_source | Reserved source repository indexing concept. | Accepted by the generic definition API, but not materialised or queried by the generic index builder path today. |
Mode | Result visibility | Use when |
|---|---|---|
inherit_object | The query path also checks whether the caller can read the underlying object, either by public policy scope or relationship authorisation. | This is the safest default for indexes derived from private object data. |
index_only | The caller needs authority to query the index, but each hit is not rechecked against object read authority. | The indexed fields are a deliberately separate derived view with its own access boundary. |
public | Same current query-path shape as index_only: the hit is not rechecked against object read authority. | The indexed data is intended to be visible to principals with index read authority. This does not make the index anonymously queryable by itself. |
Key | Type | Behaviour |
|---|---|---|
prefix | string | Object key must start with this prefix. |
content_type | string | Object content type must exactly match this value. |
Key | Type | Behaviour |
|---|---|---|
prefix | string | Append stream key must start with this prefix. |
content_type | string | Append record content type must exactly match this value. |
{
"prefix": "cases/2026/",
"content_type": "application/json"
}
{}
{
"prefix": "documents/"
}
Key | Type | Default | Behaviour |
|---|---|---|---|
positions | boolean | true | Stores term positions. Phrase queries require this to be true. |
language | string | simple | Stored language label. It must not be empty. |
max_token_chars | integer | 128 | Tokens longer than this many characters are skipped. Valid range is 1 to 128. |
lowercase | boolean | true | Applies case folding before tokenisation. |
normalize_nfkc | boolean | true | Applies NFKC normalisation before tokenisation. |
record_original_ranges | boolean | true | Records original byte ranges in token metadata. |
stop_words_enabled | boolean | false | Stored in the definition. The current tokenizer path does not expose a full configurable stop-word list here. |
stemming | string | omitted | Optional stored stemming label. The value must not be empty if present. |
require_index_success | boolean | false | Stored build requirement flag. Current extraction failures are reported as diagnostics. |
{
"positions": true,
"language": "simple",
"max_token_chars": 128,
"lowercase": true,
"normalize_nfkc": true
}
{
"source": "json_pointer",
"pointer": "/summary"
}
{
"fields": [
{"source": "object_key"},
{"source": "metadata_field", "field": "owner"},
{"source": "json_pointer", "json_pointer": "/body"}
]
}
Source | Extra keys | Behaviour |
|---|---|---|
object_body_utf8, utf8, body, git_blob_text | none | Decode the object payload as UTF-8. |
object_key, key | none | Index the object key. |
content_type | none | Index the object's content type if present. |
json_pointer | json_pointer, pointer, or path | Decode the payload as JSON and read the pointer. Strings, numbers, and booleans become text; arrays and objects are stringified JSON. |
metadata_field | field, metadata_field, key, or path | Read object user metadata. A value beginning with / is treated as a JSON Pointer into the metadata object; otherwise it is a top-level metadata key. |
media_transcript | none | Runs the current media extraction path and indexes the text transcript output. The object must have a content type. |
personaldb_table_column | column, column_name, or field; optional table or table_name | Decode the payload as JSON and read a PersonalDB row-style column from common shapes such as columns, row, new_values, values, or top-level fields. |
{
"source_kind": "object_current",
"fields": [
{"name": "state", "extractor": "/state", "required": true},
{"name": "priority", "extractor": "/priority"},
{"name": "owner", "extractor": "object_user_metadata_json_pointer:/owner"}
],
"default_order": [
{"field": "priority", "direction": "desc"},
{"field": "state", "direction": "asc"}
]
}
Key | Type | Default | Behaviour |
|---|---|---|---|
source_kind or source | string | object_current | Source family: object_current, object_version, or append_record. |
fields | array | required | Field definitions used by predicates and ordering. |
default_order | array | [] | Used when the API sends an empty typed_order_json string. The current CLI default sends [], so it bypasses this default unless you deliberately pass an empty value through a surface that permits it. |
Key | Type | Default | Behaviour |
|---|---|---|---|
name | string | required | Field name used by typed_predicates_json, typed_order_json, and query specs. |
extractor or json_pointer | string | required | Extractor string, described below. |
required | boolean | false | If extraction yields JSON null, the row is rejected and a diagnostic is recorded. |
Extractor | Behaviour |
|---|---|
created_at | Object creation timestamp as an RFC 3339 string. |
object_key | Object key. |
object_content_type | Object content type as a string, or JSON null. |
/path | JSON Pointer into the object body. |
object_body_json_pointer:/path | Explicit JSON Pointer into the object body. |
object_user_metadata_json_pointer:/path | JSON Pointer into object user metadata. |
Extractor | Behaviour |
|---|---|
created_at | Append record creation timestamp as an RFC 3339 string. |
append_stream_key | Append stream key. |
append_record_sequence | Append record sequence as a JSON number. |
append_content_type | Append record content type as a string, or JSON null. |
/path | JSON Pointer into the append payload. |
append_payload_json_pointer:/path | Explicit JSON Pointer into the append payload. |
append_user_metadata_json_pointer:/path | JSON Pointer into append record user metadata. |
{
"schema": "anvil.index.vector_definition.v1",
"source": {"kind": "object_current"},
"extractor": {
"kind": "object_body_json_vector",
"json_pointer": "/embedding"
},
"embedding": {
"provider": "caller_supplied",
"model": "acme-embedding-v1",
"dimension": 3,
"modality": "text",
"normalisation": "unit_l2",
"chunking": {"strategy": "whole_object"}
},
"ann": {
"algorithm": "hnsw",
"metric": "cosine"
}
}
Key | Type | Behaviour |
|---|---|---|
schema | string | Must be anvil.index.vector_definition.v1. |
source | object | Required provenance object. Current source filtering still uses selector_json. |
extractor | object | Required and must include a string kind. It decides how vectors are extracted or produced. |
embedding | object | Required provider/model/dimension/modality provenance and chunking metadata. |
ann | object | Required approximate-nearest-neighbour settings. Current algorithm is HNSW. |
Key | Type | Behaviour |
|---|---|---|
provider | string | Required non-empty provider or provenance name. For text embedding, the provider must be configured unless it is the server-enabled test_only provider. For payloads that already contain vectors, names such as caller_supplied are provenance labels. |
model | string | Required non-empty model name. |
model_version | string | Optional. If a configured embedding provider returns a different version, extraction records a diagnostic. |
dimension | integer | Required non-zero u16. Stored and query vectors must match this length. |
modality | string | text, image, audio, or video. |
normalisation | string | Required non-empty provenance string. The string records how vectors are expected to be prepared; the current scorer still calculates cosine normalisation at scoring time for cosine metric. |
chunking | object | Required provenance object, for example {"strategy":"whole_object"}. |
Key | Type | Default | Behaviour |
|---|---|---|---|
algorithm | string | required | Must be hnsw. |
metric | string | required | cosine, dot, or l2. |
m | integer | 32 | HNSW graph degree. Must be non-zero if supplied. |
ef_construction | integer | 200 | HNSW construction breadth. Must be non-zero if supplied. |
ef_search_default | integer | 80 | Default search breadth. Must be non-zero if supplied. |
Extractor kind | Payload shape |
|---|---|
object_body_json_vector, object_body_json, json_vector | Object body is JSON. The selected value can be an array of numbers, an object with vector, values, or embedding, an array of vector arrays, an object with a vectors array, or an array of vector objects. Optional per-vector fields are chunk_id, source_start, and source_len. The extractor may include json_pointer, vector_pointer, or pointer to select a subvalue first. |
object_body_f32_le, f32_le | Object body is raw little-endian f32 values. Payload byte length must be divisible by four, and the resulting vector length must equal embedding.dimension. |
object_body_utf8, utf8, body | Object body is sent to a configured embedding provider as text. test_only produces deterministic vectors for development/test only and is disabled unless the server explicitly allows it. |
{
"full_text": {
"positions": true,
"language": "simple"
},
"vector": {
"schema": "anvil.index.vector_definition.v1",
"source": {"kind": "object_current"},
"extractor": {"kind": "object_body_json_vector", "json_pointer": "/embedding"},
"embedding": {
"provider": "caller_supplied",
"model": "acme-embedding-v1",
"dimension": 3,
"modality": "text",
"normalisation": "unit_l2",
"chunking": {"strategy": "whole_object"}
},
"ann": {"algorithm": "hnsw", "metric": "cosine"}
}
}
{
"text": {
"source": "json_pointer",
"pointer": "/body"
}
}
Field or CLI flag | Applies to | Behaviour |
|---|---|---|
bucket_name, index_name | all | Selects the index. |
query_text / --text | full-text, hybrid | Plain text query string. Required for full text; optional for hybrid if a vector is supplied. Invalid for path, metadata-filter, typed JSON, and vector. |
query_vector / --vector | vector, hybrid | Inline float vector. CLI format is comma-delimited, for example --vector 0.2,0.1,0.9. Required for vector; optional for hybrid if text is supplied. |
limit / --limit | all | Service default for zero is 10; the service caps at 1000. The CLI default is 20. |
phrase / --phrase | full-text, hybrid text side | Treats tokenised query_text as a phrase. Requires positions to be enabled in the full-text policy. |
path_prefix / --path-prefix | path, metadata-filter, typed JSON, full-text, vector, hybrid | Narrows hits by object key or typed row object key after build selection. |
metadata_filters_json / --metadata-filters-json | path, metadata-filter, full-text, vector, hybrid | Exact equality filters against object user metadata. Ignored by direct typed JSON queries. |
typed_predicates_json / --typed-predicates-json | typed JSON | Predicate array for direct typed JSON queries. Direct full-text, vector, and hybrid queries do not evaluate it. |
typed_order_json / --typed-order-json | typed JSON | Ordering array for direct typed JSON queries. Score-based indexes ignore it. |
page_token / --page-token | all | Opaque token from the previous response. |
require_caught_up_to_watch_cursor / --require-caught-up-to-watch-cursor | metadata-backed, typed JSON | Decimal cursor string. Returns IndexLagging if the source or segment is behind. |
lag_timeout_ms / --lag-timeout-ms | API field, CLI flag | Present today, but current direct query paths return immediately rather than waiting for catch-up. |
{
"tenant": "acme",
"/workflow/state": "open",
"priority": 20
}
[
{"field": "state", "op": "eq", "value": "open"},
{"field": "priority", "op": "gte", "value": 10},
{"field": "owner", "op": "in", "values": ["alice", "bob"]},
{"field": "closed_at", "op": "is_null"}
]
Key | Type | Behaviour |
|---|---|---|
field or field_name | string | Name from the typed JSON index definition. |
op or operator | string | Predicate operator. |
value | any JSON value | Single comparison value. |
values | array | Multiple comparison values, mainly for in. |
Operator spellings | Behaviour |
|---|---|
eq, =, == | Actual value equals the first supplied value. |
in | Actual value equals any supplied value. |
lt, < | Actual value is less than the first supplied value. |
lte, <= | Actual value is less than or equal to the first supplied value. |
gt, > | Actual value is greater than the first supplied value. |
gte, >= | Actual value is greater than or equal to the first supplied value. |
exists | Field is present and not JSON null. |
is_null | Field is missing or JSON null. |
[
{"field": "priority", "direction": "desc"},
{"field": "state", "direction": "asc"},
{"field": "created_at"}
]
Field | Type | Behaviour |
|---|---|---|
query_spec_json | JSON string | Must parse to the schema described below. |
page_token | string | Opaque token from a previous QuerySpec response. |
lag_timeout_ms | integer | Passed through to selected index queries; current direct paths do not wait. |
accept_degraded | boolean | If true, the planner may use a path index when there is no bounded primitive predicate. |
{
"schema": "anvil.query.spec.v1",
"scope": {
"bucket_name": "documents",
"anvil_storage_tenant_id": "123",
"mesh_id": "local-mesh",
"authz_scope": {"realm_id": "default"}
},
"source_kind": "object_current",
"where": {
"all": [
{"path_prefix": "cases/"},
{"field": "state", "op": "eq", "value": "open"},
{"full_text": {"query": "quarterly report", "phrase": false}},
{"can": {"relation": "read"}}
]
},
"order_by": [
{"field": "priority", "direction": "desc"}
],
"limit": 20,
"consistency": {
"min_source_cursor": "42",
"min_authz_revision": "12",
"allow_stale_index": false
}
}
Field | Type | Behaviour |
|---|---|---|
schema | string | Must be anvil.query.spec.v1. |
scope.bucket_name | string | Required. The caller also needs index:read on this bucket. |
scope.anvil_storage_tenant_id | string | Optional. If present and non-empty, it must match the authenticated tenant id. |
scope.mesh_id | string | Optional. If present, it must not be empty. |
scope.authz_scope | object | Optional shape carried in the spec; it must be an object if present. |
source_kind | string | Defaults to object_current. Used when selecting a typed JSON index that covers field predicates/order. |
where.all | array | Conjunction of supported predicates. Every item must be understood by the current parser. |
order_by | array | Typed field order terms with field and optional direction. Direction must be asc or desc. |
limit | integer | Defaults to 100 if omitted. Direct query limits are still capped by the selected query path. |
consistency.min_source_cursor | string or integer | Becomes require_caught_up_to_watch_cursor for the selected query. |
consistency.min_authz_revision | string or integer | Fails with AuthzRevisionLagging if the latest authz revision is lower. |
consistency.allow_stale_index | boolean | If exactly false, a response whose selected index reports is_caught_up=false fails with IndexLagging. |
Predicate shape | Behaviour |
|---|---|
{"path_prefix":"cases/"} | Narrows by source object key or typed row object key. |
{"field":"state","op":"eq","value":"open"} | Adds a typed JSON predicate. values may be used instead of value; in with an array expands to multiple values. |
{"full_text":{"query":"quarterly report","phrase":true}} | Adds a full-text query. |
{"vector":{"near":[0.1,0.2,0.3]}} | Adds an inline numeric query vector. |
{"can":{"relation":"read"}} | States the expected object authorisation relation for protected results. Current QuerySpec planning supports only read. |
Intent | Selected index shape |
|---|---|
Text and vector | Requires a hybrid index. |
Typed predicates or order only | Uses a covering typed_json index. |
Text only | Uses a full_text index; may compose with a covering typed_json filter. |
Vector only | Uses a vector index; may compose with a covering typed_json filter. |
Path prefix only | Uses a path or typed_json path-capable index. |
No bounded primitive predicate | Fails unless accept_degraded is true, in which case it can use a path index. |
Field | Behaviour |
|---|---|
hits | Ordered result hits. Score-based indexes order by score descending with stable tie-breakers. Metadata-backed indexes order by object key and source identity. Typed JSON indexes order by typed_order_json or source identity. |
index_kind | Kind used to answer the query. |
index_generation | Generation of the materialised segment used. Hybrid reports the maximum of text/vector generations. |
authz_revision | Authorisation revision considered by the query path. |
scoring_recipe_json | JSON string describing the current scoring recipe, such as BM25, vector metric, constant score, or hybrid weights. |
next_page_token | Opaque token for the next page, if more rows are available. |
source_watch_cursor_high | Latest known source cursor for freshness comparison where supported. |
index_watch_cursor_applied | Source cursor materialised by the selected index segment where supported. |
is_caught_up | Whether the selected segment has caught up to the latest known source cursor where supported. |
lag_record_count_hint | Best-effort source-cursor gap where supported. |
Field | Behaviour |
|---|---|
kind | Index kind that produced the hit. |
score | Relevance, vector, hybrid, or constant score depending on index kind. |
object_key | Source object key or append stream key for append-backed typed rows. |
object_version_id | Object version id for object-backed hits. Append-backed typed rows currently use the append record sequence string in this field. |
document_id, field_id | Full-text document/field identifiers where relevant. |
vector_id, chunk_id, source_start, source_len | Vector/chunk source information where relevant. |
metadata_json | JSON string with kind-specific metadata, such as matched terms, typed values, user metadata, vector metric, or hybrid component scores. |
Field or CLI flag | Behaviour |
|---|---|
bucket_name, index_name | Selects diagnostics for one index. |
page.page_token / --page-token | Continues from the opaque token returned by the preceding page. The token is bound to the same caller and diagnostic filter. |
page.page_size / --page-size | Maximum diagnostics to return. CLI default is 100. |
severity / --severity | Optional filter. Supported values are info, warning, and error. |
Field | Behaviour |
|---|---|
cursor | Monotonic diagnostic cursor for pagination. |
bucket_name, index_name | Index identity. |
object_key | Source object key or append stream key. |
version_id | Source object version id where available. |
severity | info, warning, or error. |
code | Machine-readable diagnostic code, such as TextPayloadNotUtf8, VectorDimensionMismatch, or TypedJsonRowExtractionFailed. |
message | Human-readable explanation. |
details_json | JSON string with extractor-specific details. |
created_at | Timestamp. |
anvil --profile acme index diagnostics documents by_state --severity error --page-size 50
anvil --profile acme index create documents docs_text full-text \
--selector-json '{"prefix":"docs/","content_type":"application/json"}' \
--extractor-json '{"source":"json_pointer","pointer":"/body"}' \
--build-policy-json '{"positions":true,"language":"simple","max_token_chars":128}'
anvil --profile acme index query documents docs_text \
--text "quarterly report" \
--path-prefix docs/ \
--metadata-filters-json '{"visibility":"internal"}' \
--limit 20
anvil --profile acme index create documents queue_by_due typed-json \
--selector-json '{"prefix":"queue/","content_type":"application/json"}' \
--build-policy-json '{"source_kind":"object_current","fields":[{"name":"state","extractor":"/state","required":true},{"name":"due_at","extractor":"/due_at"},{"name":"priority","extractor":"/priority"}],"default_order":[{"field":"due_at","direction":"asc"}]}'
anvil --profile acme index query documents queue_by_due \
--typed-predicates-json '[{"field":"state","op":"eq","value":"ready"}]' \
--typed-order-json '[{"field":"due_at","direction":"asc"},{"field":"priority","direction":"desc"}]' \
--limit 20
anvil --profile acme index create documents embedding_v1 vector \
--selector-json '{"prefix":"docs/","content_type":"application/json"}' \
--build-policy-json '{"schema":"anvil.index.vector_definition.v1","source":{"kind":"object_current"},"extractor":{"kind":"object_body_json_vector","json_pointer":"/embedding"},"embedding":{"provider":"caller_supplied","model":"acme-embedding-v1","dimension":3,"modality":"text","normalisation":"unit_l2","chunking":{"strategy":"whole_object"}},"ann":{"algorithm":"hnsw","metric":"cosine"}}'
anvil --profile acme index query documents embedding_v1 --vector 0.1,0.2,0.3 --limit 10