Limits & Caveats
This is the honest, code-verified picture of what works, what is partial, and what is not wired yet — so adopters can set accurate expectations. Source: docs/src/end-users/limits.md.
The governed core is real: bi-temporal store, planner with ACL + org isolation, provenance/audit hash chain, SmartIngest identity detection, and all ten protocol-compatibility doors (ADR-163–170) are implemented and smoke-tested.
Query surface — what the parser actually accepts
| Feature | Status | Note |
|---|---|---|
SELECT + WHERE / ORDER BY / LIMIT / JOIN / GROUP BY | Working | JOIN is INNER hash join (O(n+m), #622); GROUP BY + COUNT(*) in the executor |
PURPOSE '…' prefix | Working, optional | ADR-125; recorded for audit when declared |
AS OF <ts> / AS OF SYSTEM TIME <ts> | Working | i64 ns UTC or UTC ISO-8601; non-UTC offsets rejected |
LIMIT n AFTER 'cursor' | Working | cursor = decimal system_from ns; cannot combine with ORDER BY |
ORDER BY | Partial | single column, ASC/DESC (#625); no multi-column yet |
WITH PROVENANCE | Working | must be a trailing modifier (after LIMIT) |
WHERE expressions | Working | col op literal, arithmetic, now(), now() - INTERVAL 'N days|hours|...' |
MATCH(col,'q'[,PHRASE|FUZZY|STEMMED]) | Working | Default mode from BM25 posting list (#624); PHRASE from positional index; FUZZY/STEMMED fall back to substring scan |
Streaming windows TUMBLE/HOP/SESSION | Working | HOP overlapping bucket fan-out; SESSION per-key activity-gap grouping |
EXPLAIN POLICY | Partial | prefix parsed but flag not consulted; use the explain_policy MCP tool |
EXPLAIN REPLAY('<id>', SEQ => n) | Working | re-derives a logged exhibit link’s seal byte-identically |
EXPLAIN PATH | Working | returns {strategy, graph_node_count, pll_warm} JSON |
CTE / WITH … AS, UNION, multi-col ORDER BY | Not implemented |
Operators & TVFs
Working and reachable from SQL: LOOKUP_IDENTITY, PATHS_BETWEEN, HYBRID_SEARCH, BENEFICIAL_OWNERSHIP_CHAIN, SANCTIONS_SCREEN, CRYPTO_TRACE, WIRE_RECONSTRUCTION, HAWALA_TRACE, GRAPH_COMMUNITY, GEOFENCE, WATCH PURPOSE …, and pgvector KNN (<=>/<->/<#>).
The DataFusion TVF form SELECT * FROM <tvf>(...) works for all 9 registered TVFs (#1001, #1004). Each TVF call is translated to its governed keyword form so it runs under the same purpose + ACL + org-isolation path.
All 17 analytics operators (13 ScorerOp + ANPR_TRACE + NETWORK_EXPAND + DISPATCH_PRIORITY + CRIME_PATTERN_CLUSTER) are reachable from SQL (#34).
DDL — the ontology is the schema
| Statement | Status | Note |
|---|---|---|
CREATE EXTENSION vector / DROP EXTENSION vector | Working (pgwire) | no-op OK tag |
CREATE TABLE (pgvector) | Working (pgwire) | registers the type; column list is ignored |
INSERT / UPDATE / DELETE | Working (pgwire) | the only native SQL DML path |
ALTER TABLE … ADD/DROP COLUMN | Parses, then 501s | use the ontology API (#985) |
CREATE MATERIALIZED VIEW … REFRESH (INCREMENTAL|FULL) EVERY <s> | Working | runs initial full refresh + background loop |
CREATE INDEX / CREATE TYPE / CREATE SCHEMA | Not implemented |
Agent memory surface
All 10 cognitive verbs are wired through to the runtime — 10 MCP tools (serve/mcp.rs) and 10 HTTP /memory/* routes (serve.rs), with e2e coverage in tests/http_e2e.rs:
| Claimed | Reality |
|---|---|
| 10 cognitive verbs | 10 implemented: original 7 plus associate / resolve / summarise |
recall = BM25 + vector hybrid | Hybrid BM25 ⊕ vector fused via RRF, re-scored by confidence × recency × forgetting curve |
recognize returns a memory | returns a MemoryItem projection |
consolidate supersedes | closes the superseded row’s valid_to and inserts the new belief |
forget deletes | RetentionMark enforced by ForgetScheduler on a background cadence |
| 5 memory canonical types | all producers wired — MemoryItem, AgentSession, ToolCall, DecisionRecord, Episode |
Canonical types & SmartIngest
- 75 canonical kinds ship (
pub enum CanonicalKindincrates/relata-canonical/src/lib.rs), not the often-quoted ~170 — that number is ADR-041’s target catalogue. The enum is#[non_exhaustive]with reserved headroom. - A few kinds (GSTIN, BTC address, FARA) ship validators but no SmartIngest detection gate — they round-trip but are not auto-detected from free text.
- OT/ICS kinds (Modbus, OPC UA, DNP3, S7, IEC 61850) auto-detected via the opt-in
icsdetector pack (#696); ambiguous forms require a label (MODBUS:17). relata detect "<text>"runs all detector packs;RELATA_DETECT_PACKSonly governs HTTP/ingestand per-row ingest paths.- Default packs:
network,contact,crypto. Opt-in:financial,payment,social,transport,device,ics. Orall/none.
Protocol compatibility doors
See the Protocol Compatibility page for per-protocol detail.
- Read-only doors: ClickHouse (HTTP + native), Neo4j (HTTP + Bolt) only run governed SELECTs / Cypher; they cannot create Relata types.
- pgvector: ANN index is cosine-only;
<->/<#>are metric-correct via over-fetch + re-rank, so prefer<=>for normalised vectors. - Mongo: no transactions, change streams, or
$push/$pull/$unset;maxWireVersion: 17; nested equality via flattened columns only. - Redis: no
MULTI/EXEC,BLPOP, scripting, or cluster commands; Pub/Sub is in-memory (zero persistence). - S3: buckets must be empty to delete; multipart parts are in-memory only (lost on restart); ETag is SHA-256. Object bodies ≥
RELATA_S3_BLOB_THRESHOLD_MB(default 4 MiB) spill to the content-addressed blob store. - All doors bind to
127.0.0.1and shareRELATA_BEARER_TOKEN. pgwire refuses to start without a token; the others default to open dev mode.
Capacity & scaling limits
- Execution path no longer materializes — streaming scan (#617), spilling hash-join + aggregate (#667), streaming results (#668), and spill-to-disk that actually frees RAM (#526) have shipped. Big results, joins, and aggregates no longer OOM.
- Aggregation is columnar for filter-free
GROUP BY, row-path when filtered (#984). Filtered aggregates fall back to per-row field access and scale super-linearly at 10M rows. - Authoritative data is RAM-resident by default, disk-paged when opted in. Rows spill to disk under memory pressure; secondary/range/FTS indexes are RAM-bounded with a scan fallback; graph, vectors, and identity ship paged backends that are default-on for the
server/clusterprofiles (#990).
| Structure | Paged backend |
|---|---|
| Authoritative rows | spill-to-disk (#626) |
| Secondary / range indexes | DiskIndexSource (#907) |
| Full-text postings | DiskIndexSource (#907) |
| Vector index (HNSW) | PagedAnnIndex (#651) + IVF cold tier (#906) |
| Graph adjacency (CSR) | PagedCsrGraph (#874) |
| Identity index | live-paged (#853/#889) |
Performance characteristics (measured)
- Conditional ACL: ~1.32× raw-scan p50. Budget gate: < 2.5×.
- Bitmap row filtering: ~1.0× (branch-predicted bitset).
- Cell masking: ~2.6× raw-scan p50. Avoid cell-level masking on hot scan paths in latency-sensitive deployments (#1099).
- Cold-restart RTO at 10M rows: WAL+Parquet flush ~15s; cold-load from Parquet ~55s. Single-node RTO ≈ 1 minute.
Async text embedding resilience (#1104)
| Knob | Default | Effect |
|---|---|---|
RELATA_EMBED_QUEUE_MAX | 100 000 | Hard cap on the in-process embedding backlog. At cap, tasks dropped (metric relata_embed_queue_dropped_total). |
RELATA_EMBED_TIMEOUT_MS | 30 000 | Timeout for sidecar HTTP calls. A GPU hang can’t stall the drain worker. |
RELATA_EMBED_CIRCUIT_COOLDOWN_MS | 60 000 | After 5 consecutive errors, the circuit opens. /health/ready returns 503 with reason: embedder_unhealthy. Writes always succeed. |
Deferred — honest deferral register (#962)
These capabilities are explicitly deferred — advertised as design targets but not shipping yet. A reader must not infer they are live.
| Capability | Current state | Ticket |
|---|---|---|
| Hardware attestation (SEV-SNP / TDX) | Software stub — Platform::Stub synthetic report for dev/CI; the API + /attestation endpoint ship, but there’s no /dev/sev-guest / TDX-driver-backed report. | #965 |
| Real Cedar SDK integration | Ships a Cedar-inspired ABAC engine (deny-wins, attribute conditions), not the open-source cedar-policy crate. Policy semantics are Relata’s own. | #966 |
Cypher MATCH patterns + WITH WARRANT | Referenced in pack docs as target syntax; the parser only handles WITH PROVENANCE. | #968 |
| SQL:2011 period predicates | FOR SYSTEM_TIME FROM/TO/BETWEEN, OVERLAPS/CONTAINS/PRECEDES, auto period-splitting are not parsed — use explicit valid_from/system_from predicates (AS OF covers point-in-time). | #969 |
| Biometric ACL | ADR-155 deferred pending legal review (#409). | #409 |
Release-readiness rule
A capability is release-ready only when it has: (1) committed implementation, (2) public-safe docs if user-facing, (3) tests or validation output, (4) known limits documented here, (5) linked issue/PR evidence. Anything listed above as “parses, then errors” or “not wired” is not yet release-ready.