# Frequently Asked Questions Source: https://stratadb.org/docs/faq ## What it is ### What is StrataDB? An embedded, multi-model database. It runs inside your process against a local directory — one binary, one database directory, no server. Five data capabilities share one storage substrate: key-value, JSON documents, an event log, vectors, and a graph. On top of that substrate you get git-style branches and time travel. See [Your first database](/docs/getting-started/first-database) for a hands-on tour. ### Is it a server? No. StrataDB is embedded and in-process, like SQLite or DuckDB. You do not start a daemon, open a port, or manage a connection pool — you point the CLI or the [Python SDK](/docs/python) at a directory and it opens the database in-process. There is no network mode in this line. ### Is it a replacement for Postgres or Redis? No — it complements them. Keep Postgres for relational application data and Redis for a shared cache. Reach for StrataDB when you want branch-isolated, versioned state with a KV, JSON, event, vector, and graph model in one place — agent memory, experiment isolation, and replayable history are the sweet spot. ### Why not just use SQLite? SQLite is a great relational store, but it has no branch-scoped isolation, no built-in vector or graph capability, and no per-commit time travel. StrataDB gives you those on one substrate instead of asking you to build them yourself. ## Storage and durability ### Durable mode versus cache mode? Point StrataDB at a path and it runs **durable**: writes go through a write-ahead log and survive the process exiting. Run it with `--cache` and it runs **in-memory** — nothing is written to disk and the data is gone when the process ends. Durable mode is the default for any named path; cache mode is for tests, scratch work, and ephemeral MCP servers. ### Where does my data live? In the directory you name. A durable database directory holds a write-ahead log, a manifest, and lock files — treat the directory as one unit; do not edit files inside it by hand. Global CLI configuration lives separately under your home directory, so uninstalling the binary never touches your databases. ### How does branching relate to git? The mental model is the same: fork a branch, get an isolated line of data, and writes on the fork are invisible to its parent. A fork is cheap because it shares the parent's data until you change something (copy-on-write), and every write is a commit you can read back with `--as-of`. Where it differs from git: this release has no merge command. You fork, isolate, and time-travel; you do not merge two divergent branches back together. The workflow is fork-and-replay, not fork-and-merge. See [Branches](/docs/concepts/branches) and [Commits](/docs/concepts/commits). ## What changed in this line The V1 line is a clean break, so a few things from earlier previews are gone or deferred. Straight answers: ### What happened to the state cell? Removed. There is no separate state-cell capability. Use the KV store for mutable keyed state, or a JSON document for structured state. ### What happened to sessions and transactions? Removed as a public surface. There is no `begin` / `commit` / `rollback`. Writes auto-commit, and multi-item batches commit itemwise or under one shared commit — you do not manage a transaction by hand. ### What happened to branch bundles? Replaced by hub clones. Instead of exporting a bundle file, you clone a dataset from a hub into a new local database with `strata clone`, and `strata remote` shows where a database was cloned from. See [Cloning datasets](/docs/guides/cloning-datasets). ### What happened to search? Vector similarity search is here — create a collection and run `vector query`. The broader standalone search surface and its optimizer are deferred beyond this line; the substrate for them is in place. See [Vectors](/docs/data/vectors). ### Can it run local models? Not with the released binary. The shipped build executes inference through cloud providers (Anthropic, OpenAI, Google — bring an API key); local GGUF execution is compiled in only when the binary is built with the local feature. The model catalog commands work either way. See [Inference](/docs/inference). ## Language SDKs and MCP ### Is there a Python or Node SDK? The **Python SDK** (`stratadb`) links the engine in your process and speaks the same command surface, value shapes, and error codes as the CLI — see the [Python SDK](/docs/python) section. Its V1 wheels are rolling out to PyPI. A Node SDK is later work. Beyond those, the `strata` CLI and its MCP server mean any language that can run a subprocess or speak MCP can drive Strata today. ### How do I use it from an AI agent? The Model Context Protocol server is built into the binary — run `strata mcp serve`; there is no separate package to install. See [For AI agents](/docs/agents) and [Agents and MCP](/docs/agents). ## Still stuck? Check [Troubleshooting](/docs/troubleshooting) for concrete failure modes, or the [error reference](/docs/reference/error-reference) to look up a specific code. --- # StrataDB Documentation Source: https://stratadb.org/docs/ StrataDB is an embedded database. It runs inside your process against a local directory — no server to start, no daemon to manage — the way SQLite or DuckDB does. One binary and one database file tree hold everything. Five data capabilities share a single storage substrate: - **Key-value** — store and read values by key. - **JSON documents** — set and read values at JSON paths. - **Event log** — an append-only, hash-chained record of typed events. - **Vectors** — collections you upsert embeddings into and search by similarity. - **Graph** — nodes and edges with properties. All five sit on top of one branch-aware MVCC store, so they share the same branches, the same versioning, and the same durability guarantees. ## What makes it different - **Git-style branches.** Fork a branch and its data is isolated; writes on the fork are invisible to its parent. A fork is cheap — it shares the parent's data until you change something. See [Branches](/docs/concepts/branches). - **Time travel.** Every write returns a commit with a timestamp. Pass that value back to any read with `--as-of` to see the data as it was at that commit. See [Time travel](/docs/concepts/time-travel). - **Durable or in-memory.** Point StrataDB at a directory and it persists through a write-ahead log; run it with `--cache` and nothing touches disk. See [Durability](/docs/concepts/durability). - **Built for agents.** The binary describes itself — a usage guide, a command catalog, and an error registry are all emitted from the running binary — and it speaks the Model Context Protocol over stdio. See [For AI agents](/docs/agents). ## Start here | I want to… | Go to | |---|---| | Decide whether StrataDB fits my problem | [Why Strata](/docs/why-strata) | | Install the CLI | [Installation](/docs/getting-started/installation) | | Create a database and run real commands | [Your first database](/docs/getting-started/first-database) | | Use it from Python | [Python SDK](/docs/python) | | Wire StrataDB into a coding agent | [For AI agents](/docs/agents) | | Understand the mental model | [Concepts](/docs/concepts) | | Learn one data primitive in depth | [Working with data](/docs/data/key-value) | | Build a real pattern | [Cookbook](/docs/cookbook) | | Look up a command or error | [Reference](/docs/reference) | ## Section map - **[Why Strata](/docs/why-strata)** — what it is, [when to use it (and when not)](/docs/why-strata/when-to-use), and [honest comparisons](/docs/why-strata/comparisons) vs SQLite, DuckDB, Redis, Postgres, and vector databases. - **[Getting started](/docs/getting-started)** — [install the CLI](/docs/getting-started/installation) and create your [first database](/docs/getting-started/first-database). - **[Concepts](/docs/concepts)** — the mental model: [embedded architecture](/docs/concepts/embedded-architecture), [primitives](/docs/concepts/primitives), [branches](/docs/concepts/branches), [time travel](/docs/concepts/time-travel), [commits](/docs/concepts/commits), [durability](/docs/concepts/durability), [spaces](/docs/concepts/spaces), [value types](/docs/concepts/value-types), [hub and clone](/docs/concepts/hub-and-clone), and [errors](/docs/concepts/errors). - **[Working with data](/docs/data/key-value)** — one primitive at a time: [key-value](/docs/data/key-value), [JSON](/docs/data/json), [events](/docs/data/events), [vectors](/docs/data/vectors), and [graph](/docs/data/graph), plus [combining primitives](/docs/data/combining-primitives). - **[Inference](/docs/inference)** — chat, embeddings, and reranking over cloud providers with [your own keys](/docs/inference/providers-and-keys), or [local models](/docs/inference/local-models). - **[Guides](/docs/guides)** — cross-cutting how-to: [branching workflows](/docs/guides/branching-workflows), [time travel](/docs/guides/time-travel), [spaces](/docs/guides/spaces), [configuration](/docs/guides/configuration), [observability](/docs/guides/observability), [error handling](/docs/guides/error-handling), [import/export](/docs/guides/import-export), [cloning datasets](/docs/guides/cloning-datasets), [migrating](/docs/guides/migrating), and [deploying](/docs/guides/deploying). - **[Cookbook](/docs/cookbook)** — end-to-end patterns: [agent state](/docs/cookbook/agent-state-management), [multi-agent coordination](/docs/cookbook/multi-agent-coordination), [RAG with vectors](/docs/cookbook/rag-with-vectors), [deterministic replay](/docs/cookbook/deterministic-replay), and [A/B testing with branches](/docs/cookbook/ab-testing-with-branches). - **[Python SDK](/docs/python)** — [install the wheel](/docs/python/installation), the [namespace surface](/docs/python/namespaces), [typed errors](/docs/python/errors), [inference](/docs/python/inference), and [agent helpers](/docs/python/agents). - **[For AI agents](/docs/agents)** — the [MCP server](/docs/agents/mcp-server), the [self-describing binary](/docs/agents/agents-guide), the [machine-readable catalogs](/docs/agents/command-index), and [machine docs](/docs/agents/machine-docs). - **[Reference](/docs/reference)** — the generated command reference by family, the [CLI](/docs/reference/cli), [configuration](/docs/reference/configuration-reference), [value types](/docs/reference/value-type-reference), and [errors](/docs/reference/error-reference). - **[Architecture](/architecture)** — how V1 is built: the layered stack, the storage substrate, durability and recovery, and the capability model. Stuck? Check the [FAQ](/docs/faq) or [Troubleshooting](/docs/troubleshooting). --- # Machine-readable docs Source: https://stratadb.org/docs/agents/machine-docs The binary describes itself; the **documentation** is machine-readable too. An agent evaluating or using Strata can load these docs the same way it loads any other structured source — no scraping of rendered HTML required. ## `llms.txt` — the front door [`stratadb.org/llms.txt`](https://stratadb.org/llms.txt) is a short, curated index of the most useful pages, in the [llms.txt](https://llmstxt.org) convention: a one-paragraph description of what Strata is, then a linked list of the pages an agent should read first. It is generated alongside the docs, so its links cannot drift from what exists. For the whole corpus in one file, [`stratadb.org/llms-full.txt`](https://stratadb.org/llms-full.txt) concatenates the documentation into a single plain-text document. ## `.md` mirror of every page Append `.md` to any documentation URL to get that page as clean CommonMark instead of HTML: ```text https://stratadb.org/docs/data/vectors → the HTML page https://stratadb.org/docs/data/vectors.md → the same page as markdown ``` The markdown is generated from the same content collection as the HTML, so the two front doors cannot disagree. This is the fastest way to feed a specific page into a model's context: fetch the `.md` URL directly. ## The error registry Every public error code has a page at [`stratadb.org/e/`](/e/), and the index at [`/e/`](/e/) lists them all. The same registry is available as JSON straight from the binary (`strata agents errors --json`; see [the command index](/docs/agents/command-index)), and each runtime error carries its `https://stratadb.org/e/` URL in the envelope. An agent that hits an error can resolve the code to a stable explanation without a web search. ## Putting it together A typical agent onboarding flow uses all three surfaces: 1. Read [`llms.txt`](https://stratadb.org/llms.txt) to learn what Strata is and which pages matter. 2. Fetch the `.md` mirror of the pages it needs. 3. When a call fails, resolve the `/e/` URL from the error envelope. And from the binary itself: [`strata agents guide`](/docs/agents/agents-guide) for the prose guide, and [`strata agents commands --json`](/docs/agents/command-index) for the structured catalog. ## Related - [For AI agents](/docs/agents) — the section overview. - [The command index](/docs/agents/command-index) — the binary's structured catalogs. - [Error reference](/docs/reference/error-reference) — the human-readable error model. --- # The agents guide Source: https://stratadb.org/docs/agents/agents-guide Strata ships a single, complete usage guide generated from the installed build — targeting rules, every capability, branches, and time travel. It is the first thing to hand an agent that is about to use Strata, and it is reachable three ways. All three return the **same** guide, matched to the version you have installed, so it can never describe a surface your binary does not have. ## From the CLI `strata agents guide` prints the guide as markdown, with no network call: ```bash strata --cache agents guide ``` ```text ## Targeting a database 1. Explicit path or `--db ` — always wins: `strata ./my-db kv get k` 2. `STRATA_DB=` — set once per session, used when no path is passed 3. `--cache` — explicit in-memory database (nothing persisted) ``` Because it is offline and version-matched, it is safe to pipe straight into an agent's context at the start of a session. ## From the Python SDK The `stratadb` package exposes the same guide as a module-level function, so an agent working in Python never has to shell out: ```python import stratadb print(stratadb.agents_guide()) # the same guide, matched to the wheel's engine ``` ## From the MCP server Over MCP, the guide is the `strata_guide` tool — the server's own instructions tell a client to call it first when unsure how anything works. See [The MCP server](/docs/agents/mcp-server). ## Why three front doors An agent might reach Strata through a shell, through Python, or through an MCP client. Each entry point returns the identical guide from the identical source, so whichever way the agent arrives, it gets the same authoritative instructions — and they always match the installed version. When you need the *structured* surface rather than the prose, use [the command index](/docs/agents/command-index). ## Related - [For AI agents](/docs/agents) — the section overview. - [The command index](/docs/agents/command-index) — the machine-readable catalogs. - [Repo onboarding](/docs/agents#onboard-a-repository) — `strata agents init` drops a pointer to this guide into a repo. --- # The command index Source: https://stratadb.org/docs/agents/command-index Where [the agents guide](/docs/agents/agents-guide) is prose, the command index is **structured**: two JSON catalogs an agent can load and enumerate directly, so it never has to guess a verb or the meaning of an error. Both come straight from the installed binary, and both are the same source the generated [command reference](/docs/reference/kv) is built from. ## The command catalog `strata agents commands --json` returns the command catalog — each command with its access class, batching and commit behavior, description, docs path, and the error codes it can raise: ```bash strata --cache agents commands --json ``` ```text {"data":{"command_count":32,"commands":[{"access":"write","batch":"itemwise", ... }]}} ``` Each entry is fully described: its path, access mode (`read`/`write`), batch semantics, commit behavior, response model, and the exact error codes it can return. An agent can route on those fields — for example, only calling `write` commands inside a branch it forked, or knowing in advance which codes a command may raise. ## The error registry `strata agents errors --json` returns the public error registry — every code with its class, hint, retry policy, and reference URL: ```bash strata --cache agents errors --json ``` ```text {"data":{"count":204,"errors":[{"class":"invalid_argument","code":"invalid_argument.engine.branch_catalog","commit_outcome":"not_started","hint":"Correct the invalid field named by the error message and retry the operation.","message":"The request contains invalid input.","ref":"https://stratadb.org/e/invalid_argument.engine.branch_catalog","retry_policy":"never"}, ... ]}} ``` This is the same registry that backs the browsable [`/e/`](/e/) pages and the [error reference](/docs/reference/error-reference). Recover by **code**, never by message text — the message is for humans and may change; the code is stable. ## One source, many renderings The command index is the IDL: the machine-readable contract for every command. The generated [command reference](/docs/reference/kv) on this site, the CLI's own help, and the MCP tool schemas are all renderings of it. Because they share one source, they cannot drift — if a page and the binary ever disagree, the binary wins, and you should check that your installed version matches these docs. ## Related - [For AI agents](/docs/agents) — the section overview. - [The agents guide](/docs/agents/agents-guide) — the prose counterpart. - [Machine-readable docs](/docs/agents/machine-docs) — the website's own machine surface (`llms.txt`, `.md` mirrors, the `/e/` registry). - [Command reference](/docs/reference/kv) — the human-readable rendering, per family. --- # Troubleshooting Source: https://stratadb.org/docs/troubleshooting Every StrataDB failure carries a stable code. Read the code, not the prose, and these situations resolve quickly. ## Start with `strata doctor` `strata doctor` is the first diagnostic. With no argument it checks the installation; give it a database path and it also tries to open it and reports what it finds. It exits non-zero when something needs attention, so it is safe to script. A healthy run reports `path_ok: true` and an empty `issues` array. When a database will not open, `doctor` says so and names the code (output abbreviated): ```bash strata ./mydb doctor ``` ```text { "database": { "exists": true, "open_ok": false, "path": "./mydb" }, "issues": [ { "code": "unavailable.engine.persistence", "hint": "Retry after the local persistence layer is available." } ], "path_ok": true, "platform": "linux-x86_64" } ``` ## How to read an error Failures print a `..` code, a one-line hint, and a reference URL: ```text not_found.engine.branch: source branch `nonesuch` does not exist (err_local_37433bfb_000001) hint: Check that the requested branch, space, collection, graph, document, key, or model exists. ref: https://stratadb.org/e/not_found.engine.branch ``` The **class** (the first segment) tells you how to react: `not_found`, `invalid_argument`, and `already_exists` mean fix the request; `failed_precondition` means the database is in a state that blocks the operation; `unavailable` means retry after the underlying layer recovers; `corruption` means stop and inspect. Open the `ref` URL — the same `/e/` page — for the details, or look any code up offline with `strata agents errors --json`. Add `--json` to any command to get the same information as a structured envelope. Recover by code, never by message text. ## `command not found` after install If your shell prints `strata: command not found`, the binary is installed but not on your `PATH` for this shell. Open a new terminal (the installer edits your shell profile), or follow the PATH steps in [Installation](/docs/getting-started/installation). `strata doctor` reports `path_ok` once the binary is reachable. ## No database specified ```text error: [invalid_argument.cli.no_database]: no database specified hint: pass a path (strata ./mydb kv put …), set STRATA_DB, or use --cache for ephemeral ``` StrataDB never opens the current directory implicitly. Pass a path (`strata ./mydb …`), set `STRATA_DB`, or use `--cache` for an ephemeral database. This is the `invalid_argument.cli.no_database` code — CLI usage errors like it print a plain `error:` line, exit with status 2, and are not in the `/e/` registry, so look them up by reading the printed hint. ## The database will not open A path that is not a directory, a directory the process cannot read or write, or a database whose files were altered underneath it all surface as [`unavailable.engine.persistence`](/e/unavailable.engine.persistence): ```text unavailable.engine.persistence: persistence lower layer is unavailable (err_local_010d5985_000001) hint: Retry after the local persistence layer is available. ref: https://stratadb.org/e/unavailable.engine.persistence ``` Check that the path points at a database directory you own and can write, that no other process is holding it, and that the disk is not full. `strata doctor` confirms whether the open succeeds — the path is a global argument, so it comes before the subcommand. Treat a database directory as one unit — do not edit or remove files inside it by hand. ## Opening a pre-V1 database Databases created before the V1 line are rejected on open with [`failed_precondition.engine.layout_version`](/e/failed_precondition.engine.layout_version), class `failed_precondition`. From the registry, its message is "The database layout is incompatible with this runtime," and its hint is to open the database with a compatible version. This line does not migrate pre-V1 development databases — create a fresh database and reload your data. Look the code up with `strata agents errors --json`. ## Durability and recovery failures If the storage layer cannot make a write durable, the writer stops rather than report a false success, and operations surface in the `unavailable` class (`unavailable.engine.persistence` and related codes) with a retry-after-recovery hint. Recovery is explicit: fix the underlying condition — free space, permissions, a healthy disk — and reopen the database. If stored data fails validation while recovering, you get [`corruption.engine.persistence_recovery`](/e/corruption.engine.persistence_recovery), whose hint is blunt: "Stop writing to the database and inspect recovery diagnostics before continuing." Do exactly that — take a copy of the directory and inspect it before any further writes. ## Getting more help - [FAQ](/docs/faq) — what changed in this line and why. - [Error reference](/docs/reference/error-reference) — every code with its class and meaning. - [Observability guide](/docs/guides/observability) — health and metrics surfaces beyond `doctor`. --- # The MCP server Source: https://stratadb.org/docs/agents/mcp-server `strata mcp serve` runs a [Model Context Protocol](https://modelcontextprotocol.io) server over **stdio**: newline-delimited JSON-RPC on stdin/stdout, logs on stderr. It exposes the same database, the same JSON envelopes, and the same [error codes](/docs/reference/error-reference) as the CLI — no separate package to install. For the section overview see [For AI agents](/docs/agents). ## Running the server The server opens a database the same way every command does — it needs a durable path, `--cache`, or `STRATA_DB`. ```bash strata ./my-db mcp serve # durable, positional path strata --db ./my-db mcp serve strata --cache mcp serve # ephemeral, in-memory ``` With no target it refuses with `invalid_argument.cli.no_database`: ```text $ strata mcp serve error: [invalid_argument.cli.no_database]: no database specified hint: pass a path (strata ./mydb kv put …), set STRATA_DB, or use --cache for ephemeral ``` ## Handshake A client sends `initialize`, then the `notifications/initialized` notification, then may call `tools/list` and `tools/call`. You can drive it by hand with newline-delimited JSON: ```bash printf '%s\n%s\n%s\n' \ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}' \ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \ '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \ | strata ./agent mcp serve ``` The `initialize` result advertises the tools capability and carries an `instructions` string: ```json {"id":1,"jsonrpc":"2.0","result":{ "protocolVersion":"2025-06-18", "capabilities":{"tools":{"listChanged":false}}, "serverInfo":{"name":"strata","version":"…"}, "instructions":"Strata is an embedded multi-model database (KV, JSON, vectors, events, graphs) with branches and time travel. When unsure, call the `strata_guide` tool first …" }} ``` The server **echoes back the `protocolVersion` the client requested** rather than pinning one of its own — send `2024-11-05` and the result says `2024-11-05`. `serverInfo.name` is `strata` and `serverInfo.version` matches the running binary. Tool results come back as MCP `content` items whose text is the same JSON envelope the CLI prints; errors carry the same `class` and `code`. On the wire, byte fields (KV keys and values, list cursors) are **base64**. ## Tools `tools/list` returns **20 tools**. Two are meta-tools; the rest are one canonical verb per capability. Every tool takes optional `branch` and `space` arguments. | Tool | Required inputs | Optional inputs | Purpose | |------|-----------------|-----------------|---------| | `strata_guide` | — | — | Return the complete usage guide (markdown, matched to this binary). Call first when unsure. | | `strata_command` | `command` | — | Escape hatch: run any cataloged command as raw wire JSON. Byte fields are base64. | | `strata_kv_put` | `key`, `value` | `branch`, `space` | Write one key (text value). Returns a commit receipt. | | `strata_kv_get` | `key` | `as_of`, `branch`, `space` | Read one key. `data.value` is base64. | | `strata_kv_delete` | `key` | `branch`, `space` | Delete one key. | | `strata_kv_list` | — | `prefix`, `limit`, `cursor`, `as_of`, `branch`, `space` | List keys with base64 cursor pagination. | | `strata_json_set` | `key`, `path`, `value` | `branch`, `space` | Set a JSON path (`$` replaces the document). | | `strata_json_get` | `key`, `path` | `as_of`, `branch`, `space` | Read a JSON path. | | `strata_json_delete` | `key`, `path` | `branch`, `space` | Delete a JSON path. | | `strata_vector_create_collection` | `collection`, `dimension` | `metric`, `branch`, `space` | Create a collection (`metric`: `cosine`, `euclidean`, `dot_product`). | | `strata_vector_upsert` | `collection`, `key`, `vector` | `metadata`, `branch`, `space` | Upsert one embedding. | | `strata_vector_query` | `collection`, `query` | `k`, `filter`, `as_of`, `branch`, `space` | Similarity search with an AND-composed metadata filter. | | `strata_event_append` | `event_type`, `payload` | `branch`, `space` | Append one immutable, hash-chained event. | | `strata_event_list` | — | `event_type`, `limit`, `after_sequence`, `as_of`, `branch`, `space` | List events, optionally by type. | | `strata_graph_create` | `graph` | `branch`, `space` | Create a graph. | | `strata_graph_add_node` | `graph`, `node_id` | `properties`, `branch`, `space` | Add or replace a node. | | `strata_graph_add_edge` | `graph`, `src`, `edge_type`, `dst` | `weight`, `properties`, `branch`, `space` | Add or replace a typed, optionally weighted edge. | | `strata_graph_neighbors` | `graph`, `node_id` | `direction`, `edge_type`, `limit`, `as_of`, `branch`, `space` | Traverse a node's neighbors (`direction`: `outgoing`, `incoming`, `both`). | | `strata_branch_list` | — | — | List branches with status and lineage. | | `strata_branch_fork` | `source`, `branch` | `version`, `timestamp` | Fork a branch; anchor to a retained `version` or `timestamp` for time travel. | The curated tools cover the core verbs. Anything else in the catalog — graph deletes, analytics, history, spaces, batches — is reachable through `strata_command`; the guide lists the full command catalog. `as_of` accepts a commit timestamp taken from a prior write receipt's `data.commit.timestamp`. ### The two meta-tools - **`strata_guide`** returns the full, version-matched usage guide as markdown. A client that is unsure how anything works should call this before guessing. - **`strata_command`** executes any cataloged command by its raw wire JSON, for example `{"command":{"type":"kv_scan","limit":10}}`. Invalid input returns the exact field-level [error envelope](/docs/reference/error-reference). ### Wire values are not CLI flags When calling tools by hand, wire values are not always spelled like CLI flags. The vector metric is `dot_product` (underscore) in a `strata_vector_create_collection` call, where the CLI's `vector collection create` takes `dot-product` (hyphen). When in doubt, the tool's `inputSchema` from `tools/list` is authoritative. ## Client configuration A Claude-style `mcpServers` entry, with the database path baked into the arguments: ```json { "mcpServers": { "strata": { "command": "strata", "args": ["/absolute/path/to/my-db", "mcp", "serve"] } } } ``` Use `strata` if it is on `PATH`, otherwise an absolute path to the binary. For an ephemeral database use `["--cache", "mcp", "serve"]`; to keep the path out of the arguments, drop the path argument and set `STRATA_DB` in the server's environment. ## See also - [For AI agents](/docs/agents) — the section overview and database targeting. - [The command index](/docs/agents/command-index) — the catalog the tools draw from. - [Value Type Reference](/docs/reference/value-type-reference) — the value forms behind each tool. - [Error Reference](/docs/reference/error-reference) — the `class`/`code` model shared with the CLI. --- # Commits Source: https://stratadb.org/docs/concepts/commits Every write in StrataDB is a **commit**. When you put a key, set a JSON path, append an event, upsert a vector, or add a graph node, that change is applied atomically and becomes durable on its own — there is no separate step to commit it. This keeps one canonical path for every write and removes a whole class of "did I remember to commit?" bugs. ## Writes auto-commit A write returns a receipt telling you what happened: ```text $ strata ./db kv put config prod created config applied=true ``` The `--json` envelope carries the full commit facts: ```text $ strata --json ./db kv put config staging {"data":{"commit":{"delete_count":0,"durable":true,"put_count":1,"timestamp":4,"version":4},"effect":{"affected_count":1,"applied":true,"kind":"updated","matched":true},"key":"Y29uZmln"},"type":"write_result"} ``` Two objects matter here: - **`commit`** — the `version` and `timestamp` this write was assigned, plus how many rows it put or deleted and whether it was made `durable`. Versions are a monotonic per-database clock: every commit gets a strictly higher number than the last. - **`effect`** — what the write did to the target: `kind` is `created`, `updated`, or `deleted`; `matched` says whether a prior value existed; `affected_count` is how many rows changed. ## No manual transactions There is no session to open and no transaction to manage. The old `begin`, `commit`, and `rollback` verbs are gone: ```text $ strata ./db begin error: `begin` is recognized from the old CLI, but is not available in the V1 CLI surface yet ``` Each write is its own atomic unit. When you need several writes to land together, use a batch (below) rather than a manual transaction. ## Versioned reads Because every commit has a version, you can read the past. History lists a key's retained versions, newest first: ```text $ strata ./db kv history config {"timestamp":4,"tombstone":false,"value":"staging","version":4} {"timestamp":3,"tombstone":false,"value":"prod","version":3} ``` Pass a commit timestamp to `--as-of` to read the value as it stood then — the same flag works on `kv`, `json`, `event`, `vector`, and `graph` reads: ```text $ strata ./db kv get config --as-of 3 prod $ strata ./db kv get config --as-of 4 staging ``` Deletes are commits too. A delete writes a **tombstone** rather than erasing history, so a time-travel read still returns the value that existed before the delete, and `history` shows the tombstone with `"tombstone":true`. ## Batches: itemwise with a shared commit A batch applies many items in one call. Batches are part of the command surface used by the SDKs, the [MCP tools](/docs/agents), and the raw command path — not a bare CLI verb — so the semantics below are what you get from those callers. StrataDB's batches are **itemwise**: you get one positional result per input item, and the outer status summarizes whether all, some, or none succeeded. Valid items that the engine applies together share one commit. Putting two keys in a single batch, both land at the same `version` and `timestamp`: ```text "commit": { "put_count": 2, "version": 3, "timestamp": 3 }, "items": [ { "index": 0, "status": "ok", "result": { "key": "YQ==" } }, { "index": 1, "status": "ok", "result": { "key": "Yg==" } } ], "mode": "itemwise", "status": "ok" ``` (Abbreviated from the real `--json` envelope; every item also repeats the shared `commit`.) Each item reports its own outcome, so a batch where one item fails validation returns an outer `status` of `partial` — the offending item is flagged with its own error while the valid items still commit. See the [CLI reference](/docs/reference/cli) for the full command surface. ## Why this design Auto-commit plus versioning gives you atomic writes, a single canonical write path, and full time travel without the ceremony of transactions. When you need multi-write atomicity, reach for a batch; when you need an isolated line of history, reach for a [branch](/docs/concepts/branches). ## Next - [Durability](/docs/concepts/durability) — when `durable` is true and how recovery works - [Value Types](/docs/concepts/value-types) — what a value is in each capability - [Deterministic Replay](/docs/cookbook/deterministic-replay) — using versions and `--as-of` to reproduce state --- # For AI agents Source: https://stratadb.org/docs/agents Strata is built to be driven by agents. The binary **describes itself** — a version-matched usage guide, machine-readable command and error catalogs, one command to drop onboarding notes into a repo, and an MCP server that exposes the core verbs as tools. Everything an agent needs is generated from the installed binary's own metadata, so it can never drift from what your binary actually does. This page orients you; the rest of the section goes deep. In a hurry? The [agent quickstart](/docs/getting-started/quickstart-agents) is the one-step version: `strata agents skill --write` installs the Claude Code skill into your repo. ## Target a database explicitly Every data command needs a database — including `mcp serve`. Pass a path, set `STRATA_DB`, or use `--cache` for an ephemeral one. **Strata never opens the current directory implicitly.** A bare invocation with no target refuses, and the refusal teaches the fix: ```text $ strata error: [invalid_argument.cli.no_database]: no database specified hint: pass a path (strata ./mydb kv put …), set STRATA_DB, or use --cache for ephemeral ``` That is the `invalid_argument.cli.no_database` code. CLI usage errors like it print a plain `error:` line and exit with status 2 even under `--json`, and their `cli.*` codes are **not** in the `/e/` registry. Errors from data operations are richer: each carries a `..` code, a one-line hint, and a `https://stratadb.org/e/` reference. Recover by code, never by message text. ## The self-describing binary Three commands emit everything an agent needs, generated from the installed binary: ```bash strata agents guide # the complete usage guide, as markdown strata agents commands --json # the machine-readable command catalog strata agents errors --json # the public error-code registry ``` - The guide is the first thing to hand an agent with a shell — see [The agents guide](/docs/agents/agents-guide). - The two catalogs let an agent enumerate every verb and every error rather than guess — see [The command index](/docs/agents/command-index). ## Onboard a repository Drop a short pointer into the current repo so future agent sessions start oriented: ```bash strata agents init ``` ```text { "next": null, "pointer": "absent", "pointer_target": null, "written": [ ".strata/AGENTS.md" ] } ``` That writes `.strata/AGENTS.md`, a pointer block that tells any agent working in the repo how to discover the rest — it points at the live guide and catalogs rather than duplicating them. Add `--apply` to also append the pointer block to the repo's `AGENTS.md` or `CLAUDE.md`, so agents that read those files find Strata without being told. ## Speak MCP The same binary is a Model Context Protocol server over stdio — no separate package to install: ```bash strata ./mydb mcp serve ``` Point an MCP client at it: ```json { "mcpServers": { "strata": { "command": "strata", "args": ["./mydb", "mcp", "serve"] } } } ``` The server exposes a curated set of tools plus `strata_guide` (the guide above) and `strata_command` (any cataloged command as raw wire JSON). Tools return the same envelopes and the same error codes as the CLI. The full tool list and handshake are in [The MCP server](/docs/agents/mcp-server). ## Verify ```bash strata --cache ping ``` This prints `pong` and the installed version. If you see it, the binary runs. ## In this section - **[The agents guide](/docs/agents/agents-guide)** — `strata agents guide`, `stratadb.agents_guide()`, and the `strata_guide` tool: one version-matched guide, three front doors. - **[The command index](/docs/agents/command-index)** — the machine-readable command and error catalogs, and how the generated reference derives from them. - **[The MCP server](/docs/agents/mcp-server)** — running the stdio server, the handshake, and the exact tools it advertises. - **[Machine-readable docs](/docs/agents/machine-docs)** — `llms.txt`, the `.md` mirror of every page, and the `/e/` error registry. ## Related - [Error handling](/docs/guides/error-handling) and the [error reference](/docs/reference/error-reference) — recover by code. - [Your first database](/docs/getting-started/first-database) — the hands-on basics if you want them. --- # Branches Source: https://stratadb.org/docs/concepts/branches A **branch** is an isolated namespace for data. Every value in StrataDB lives inside a branch, and every capability — KV, JSON, event log, vectors, graphs — is branch-aware. Branches are how you keep one agent session, experiment, or tenant from seeing another's data, without copying the whole database. A database always has a `default` branch. You never create it; it is there the moment the database exists. ## Forking a branch `branch fork` creates a new branch from an existing one. The fork starts as a copy-on-write view of its parent — you see the parent's data, but your writes go only to your branch. ```bash strata ./db kv put city london strata ./db branch fork default experiment strata ./db kv put city tokyo --branch experiment ``` Reading each branch shows the isolation: ```text $ strata ./db kv get city --branch experiment tokyo $ strata ./db kv get city london ``` The write on `experiment` never touched `default`. Forking is cheap because nothing is copied up front; the branch records its parent and the commit version it forked from: ```text $ strata ./db branch get experiment { "branch_id": "1a29fdd4-745b-5b66-ad18-75b3cf51cef6", "created_at": 3, "deleted_at": null, "generation": 1, "name": "experiment", "parent": { "branch_id": "00000000-0000-0000-0000-000000000000", "fork_timestamp": null, "fork_version": 3, "generation": 1, "name": "default" }, "state_revision": 0, "status": "active" } ``` The `parent` block names the branch you forked from and the `fork_version` you forked at; `default` always has the all-zero `branch_id`. ## Empty branches `branch create` makes a fresh **root** branch with no parent and no data — useful when you want a clean namespace rather than a fork of existing state. ```text $ strata ./db branch create fresh $ strata ./db kv get city --branch fresh (nil) ``` ## Listing and inspecting ```bash strata ./db branch list # every branch, one per line strata ./db branch get experiment # one branch's metadata strata ./db branch delete fresh # remove a branch and its data ``` Branch generations are monotonic per name: delete a branch and create it again, and the new one has a higher generation, so stale references never silently resolve to fresh data. ## Forking a point in time A fork does not have to start from the tip. Pass `--version` or `--timestamp` to fork from a retained point in the source branch's history: ```bash strata ./db branch fork default older --version 3 ``` The new branch sees the source exactly as it stood at that version, while the source keeps moving forward: ```text $ strata ./db kv get x --branch older v1 $ strata ./db kv get x v2 ``` ## Safety rules - The `default` branch cannot be deleted. Attempting it fails with `invalid_argument.engine.branch_delete`. - Cross-branch references are rejected — you cannot point an operation at data in a branch other than the one it targets. - There is no merge command in this release. Branches diverge freely; to bring work from one branch onto another, re-apply (replay) the writes you want on the target. This release ships forking, isolated writes, and deletion, and leaves merge to a future surface. ## Choosing a branch per command One-shot commands take `--branch `; without it they target `default`. This is the clearest way to script against a specific branch, because each process is independent: ```bash strata ./db kv put status ready --branch session-42 strata ./db kv get status --branch session-42 ``` In the interactive REPL (`strata ./db` with no command), the branch is sticky: `use ` — or passing `--branch` on any line — switches the current branch for the lines that follow, and the prompt reflects it. ```text strata:default/default> use experiment strata:experiment/default> ``` ## When to use branches | Scenario | Pattern | |----------|---------| | Each agent session gets its own state | One branch per session id | | A/B testing two strategies | One branch per variant, compare, keep the winner | | Safe experiments | Fork, try changes, delete the branch if it goes wrong | | Multi-tenant isolation | One branch per tenant | | Reproducible snapshots | Fork at a known point and read it later | ## Next - [Commits](/docs/concepts/commits) — how writes on a branch become versioned and durable - [Branch Management Guide](/docs/guides/branching-workflows) — the full branch API - [A/B Testing with Branches](/docs/cookbook/ab-testing-with-branches) and [Multi-Agent Coordination](/docs/cookbook/multi-agent-coordination) — worked patterns --- # Embedded architecture Source: https://stratadb.org/docs/concepts/embedded-architecture StrataDB is **embedded**: it runs inside your process, against a local directory, in the same spirit as SQLite or DuckDB. There is no daemon to start, no port to open, no connection pool to manage. You point the CLI (or an MCP client, or — later — an SDK) at a directory and it opens the database in-process. This page explains what that model means; the durability mechanics are in [Durability](/docs/concepts/durability). ## In-process, not a server A traditional database is a server you connect to over a socket. StrataDB is a **library plus a binary that embeds it**. The database lives and dies with the process that opens it, and it talks to your code directly rather than over a network. The consequences are the point: - **Zero operational surface.** Nothing to deploy, no health checks on a separate service, no version-skew between client and server. The binary *is* the database. - **One writer per durable database.** A durable database is opened with an exclusive lock, so a second process that tries to open the same directory is refused rather than corrupting it. Reads and writes from within the one process are what you coordinate. - **No network mode.** This line has no server or wire protocol. To expose the database to an agent, the binary itself speaks [MCP over stdio](/docs/agents/mcp-server) — still in-process, not a network service. The closest analogy is SQLite: an application-embedded database that is a file on disk, not a service on a host. StrataDB keeps that shape and layers branches, time travel, and five data primitives on top. ## Two modes: durable and cache An embedded database still has to decide whether data outlives the process. StrataDB has two modes, chosen at open time: - **Durable** — the default for any named path. Writes go through a write-ahead log and survive the process exiting; reopening recovers the last committed state. - **Cache** — opened with `--cache`. Pure in-memory: nothing is written to disk, and the data is gone when the process ends. Ideal for tests, scratch work, and ephemeral MCP servers. Same API, same primitives, same branching — the only difference is whether it persists. [Durability](/docs/concepts/durability) covers the write-ahead log, recovery, and how to choose. ## Where your data lives A durable database is **the directory you name**. That directory holds a write-ahead log, a manifest, and lock files — treat it as a single unit, and do not edit files inside it by hand. Copy or move the whole directory, not its parts. Global CLI configuration (the resolved hub URL, stored provider keys) lives **separately**, under your home config directory — so uninstalling the binary or deleting a config never touches your databases, and vice versa. Because a database is just a directory, sharing a prepared one is a matter of copying it — or, for curated datasets, [cloning from a hub](/docs/concepts/hub-and-clone). ## Next - [Durability](/docs/concepts/durability) — the write-ahead log, recovery, and choosing durable vs cache. - [Branches](/docs/concepts/branches) — the isolation model layered on top. - [When to use StrataDB](/docs/why-strata/when-to-use) — where the embedded model fits and where it does not. --- # Durability Source: https://stratadb.org/docs/concepts/durability StrataDB has two ways to hold data, and you choose between them when you open the database: a **durable** database backed by disk, or a **cache** database that lives entirely in memory. There is no in-between mode to configure and no per-write durability flag — durability is a property of the database you opened. ## Durable databases Point the CLI at a path and you get a durable database. It is created on first use and reopened every time after: ```bash strata ./my-db kv put greeting hello ``` `info` reports what you have: ```text $ strata ./my-db info { "durable": true, "target": "durable_local", "open": true, ... } ``` On disk, a durable database is a directory of a few subdirectories: ```text $ ls ./my-db locks manifest wal ``` - **`wal`** — the write-ahead log. Every commit is written here before it is acknowledged. - **`manifest`** — the record of the database's structure and committed state. - **`locks`** — guards against two processes opening the same database at once. ### Write-ahead log and recovery Durable writes follow a write-ahead protocol: the change is appended to the WAL and made durable, and only then does the write return success. Because the log records committed state before you see an acknowledgement, a durable database can rebuild itself after a crash. Recovery happens automatically the next time you open the path — you do not run a separate repair step: ```text $ strata ./my-db kv put persisted yes created persisted applied=true # a brand-new process, later: $ strata ./my-db kv get persisted yes ``` The value survives because it was in the WAL before the first process exited. ### Halt on fsync failure Durability is only meaningful if a successful write is actually on disk. If the operating system cannot flush the WAL — an `fsync` failure — the writer **halts** rather than acknowledging writes it cannot guarantee. It will not silently continue accepting data it might lose. You recover by resolving the underlying disk problem and reopening the database, which replays the log up to the last write it could prove was durable. This is a deliberate trade: StrataDB would rather stop than lie about durability. ## Cache databases Pass `--cache` and the database lives only in memory. Nothing is ever written to disk — no WAL, no manifest, no lock files: ```text $ strata --cache info { "durable": false, "target": "cache", ... } ``` You can confirm it leaves no trace. Run a cache write in an empty directory and the directory stays empty: ```text $ strata --cache kv put x y created x applied=true $ ls # (nothing) ``` Two consequences follow from being purely in-memory: - **Data does not persist.** Each `--cache` process starts empty and forgets everything when it exits. Two separate `strata --cache` commands do not share state. - **There is nothing to recover.** Cache mode has no WAL, snapshot, or lock objects by design, so there is no crash recovery — the data simply was never on disk. Cache mode is the right choice for tests, one-off experiments, ephemeral agent scratch space, and running in environments where you do not want to touch the filesystem. ## Choosing a mode | You want to… | Use | |--------------|-----| | Keep data across restarts | A durable database (`strata ./path …`) | | Guarantee committed writes survive a crash | A durable database — writes are WAL-backed | | Run a fast, throwaway experiment | A cache database (`strata --cache …`) | | Avoid writing anything to disk | A cache database | When in doubt, use a durable database. The cost of the write-ahead log is small, and you get recovery for free. ## Next - [Commits](/docs/concepts/commits) — the `durable` flag on each write receipt - [Database Configuration](/docs/guides/configuration) — opening, targeting, and inspecting a database - [Observability](/docs/guides/observability) — `info`, `health`, and `doctor` - [Troubleshooting](/docs/troubleshooting) — recovery and lock issues --- # Errors Source: https://stratadb.org/docs/concepts/errors Strata treats errors as part of its contract, not as prose. Every failure carries a **stable, structured code** you can branch on, plus human-readable context for diagnosis. This page is the model; the [error-handling guide](/docs/guides/error-handling) covers parsing and retry, and the [error reference](/docs/reference/error-reference) lists every code. ## Recover by code, never by message The single rule: **branch on the code, not the message text.** The message is for humans and may be reworded between versions; the code is stable and will not change meaning. Anything that reacts programmatically to an error should match on its code or class. The full registry ships in the binary — `strata agents errors --json` (see [the command index](/docs/agents/command-index)) — and online at [`/e/`](/e/), so the set of codes is enumerable, not something you discover by hitting it. ## The shape of a code Codes are three parts, `..`: ```text not_found.engine.branch failed_precondition.engine.space_not_empty invalid_argument.cli.no_database ``` - **class** — the broad kind of failure; branch on this for control flow. - **area** — the subsystem it came from (`engine`, `executor`, `cli`, …). - **detail** — the exact case; log the full code for diagnosis. ## A fixed class taxonomy There is a closed set of **fifteen classes**, each telling you the shape of the problem — for example `not_found` (a named resource is absent), `already_exists`, `invalid_argument` (fix the input), `failed_precondition` (a required condition was not met), `conflict` (reload and retry), `history_unavailable` (outside retained history), `unsupported`, and `internal`. The [error-handling guide](/docs/guides/error-handling#error-classes) has the full table with what each one means and how to react. Because the taxonomy is fixed, you can write recovery once per class rather than per code — handle `not_found` uniformly wherever it appears. ## Diagnostics travel with the error Beyond the code, each error carries the context you need to act and to report: - a one-line **hint** (`suggested_fix`) — the safe next step; - a **docs reference** — the `https://stratadb.org/e/` URL, resolvable to a per-code page; - a per-occurrence **reference id** (`err_local_…`) — unique to that failure; quote it when reporting a problem; - machine fields that say whether retrying helps (`retry_policy`) and, for writes, what happened to your data (`commit_outcome`). ## A miss is not an error Reads distinguish *failure* from *absence*. Reading a key that does not exist is not an error — it returns a null/`(nil)` result and exits zero. Errors are for things that genuinely went wrong; a normal "not there" stays on the success path. An out-of-range historical read is the exception that *is* an error — `history_unavailable`, distinct from `not_found`. ## Secrets are redacted The error path never leaks sensitive material. Provider API keys, signed URLs, prompts, and document contents are redacted by default, so an error is safe to log and to surface to a user without exposing what produced it. ## Next - [Error handling](/docs/guides/error-handling) — the JSON shape, exit codes, retry policy, and commit outcome, with worked examples. - [Error reference](/docs/reference/error-reference) — the full registry, paired with the browsable [`/e/`](/e/) pages. --- # Hub and clone Source: https://stratadb.org/docs/concepts/hub-and-clone A Strata database is a local directory, so the simplest way to share one is to copy it. For *curated* datasets — a prepared corpus, an embeddings set, a demo — Strata adds a lightweight distribution model: a **hub** hosts datasets, and `strata clone` pulls one into a new local database. This page is the concept; the [Cloning datasets guide](/docs/guides/cloning-datasets) has the commands. ## What a hub is A hub is an HTTP endpoint that serves prepared datasets by slug. Strata resolves which hub to use from a layered configuration — a `--hub` flag, the `STRATA_HUB_URL` environment variable, project or global config, and finally a built-in default. `strata config show` prints the resolved hub and names the layer it came from. In this line the hub substrate is **metadata-only**: it is a way to *distribute* prepared databases, not a sync service or a multi-writer backend. ## Cloning a dataset `strata clone [dest]` resolves a hub, requests the dataset, and writes a new local database (defaulting to `./.strata`). A cloned database is an **ordinary database** — it opens, branches, time-travels, and queries exactly like one you created yourself. Cloning is how you go from "a dataset someone prepared" to "a local database I can fork and explore" in one step. ## Clone artifacts, not bundles A clone is delivered as a **clone artifact**: the hub's representation of a dataset that `clone` materializes into a local database. This replaces the older "branch bundle" export files — instead of producing and passing around a bundle, you publish a dataset to a hub and clone it. The unit of sharing is a dataset you clone, not a file you export. ## Provenance: a clone remembers its origin A cloned database records **where it came from**. `strata remote` reports the origin — the hub and dataset a database was pulled from — while a database you created yourself has no origin (`origin: null`). That provenance lets you trace a local copy back to its source, which matters when a dataset is shared, forked locally, and evolved. ## How it composes Clone once, then use every other concept locally: fork [branches](/docs/concepts/branches) off the cloned data, read it as of past [commits](/docs/concepts/time-travel), and partition it with [spaces](/docs/concepts/spaces). The hub gets you a starting database; everything after is ordinary local Strata. ## Next - [Cloning datasets guide](/docs/guides/cloning-datasets) — `clone`, hub resolution, and `remote`, with the exact commands. - [Configuration reference](/docs/reference/configuration-reference) — the hub config keys and resolution layers. - [Embedded architecture](/docs/concepts/embedded-architecture) — why a database is a directory in the first place. --- # Concepts Source: https://stratadb.org/docs/concepts StrataDB is an embedded multi-model database: one binary, one file-backed database, no server, in the same spirit as SQLite or DuckDB. Five data capabilities — key-value, JSON documents, an event log, vectors, and graphs — share a single branch-aware, versioned storage substrate. That shared foundation is what makes the concepts here small in number and consistent across every capability: isolate with a branch, and every capability isolates; version a write, and every read can travel back to it. These pages explain the ideas you need to use it well. Read them in order if you are new, or jump to the one you need. **The model** - **[Embedded architecture](/docs/concepts/embedded-architecture)** — in-process, no server, one directory; durable vs cache mode. - **[Primitives](/docs/concepts/primitives)** — the five capabilities and when to reach for each, all layered over the same storage row. - **[Value Types](/docs/concepts/value-types)** — what a value actually is in each capability, from opaque KV bytes to full JSON documents. **History and isolation** - **[Branches](/docs/concepts/branches)** — the isolation model. Every piece of data lives in a branch, forks are cheap, and writes on one branch are invisible to another. Learn this one first — everything else happens inside a branch. - **[Commits](/docs/concepts/commits)** — how writes happen. Every write auto-commits atomically and returns a version and timestamp. There are no manual `begin`, `commit`, or `rollback` calls. - **[Time travel](/docs/concepts/time-travel)** — reading the past. Any read accepts `--as-of` to see the database as of an earlier commit, and you can fork from a past point. - **[Durability](/docs/concepts/durability)** — where data lives. A durable database is backed by a write-ahead log and recovers on reopen; a cache database is pure in-memory. **Organizing and sharing** - **[Spaces](/docs/concepts/spaces)** — named partitions of data within a branch, the second organizing dimension alongside branches. - **[Hub and clone](/docs/concepts/hub-and-clone)** — how prepared datasets are distributed and cloned into a local database. **The contract** - **[Errors](/docs/concepts/errors)** — the stable `class.area.detail` codes you recover by, and the fixed class taxonomy. ## How they fit together A database holds one or more **branches**. Inside a branch you use the five **primitives**, and each write is a **commit** with a version. Whether those commits survive a restart is a matter of **durability** — durable or cache. And what a stored value means depends on the primitive, which is the subject of **value types**. Learn the five ideas once and they apply the same way everywhere. Once the model makes sense, [Working with Data](/docs/data/key-value) walks through each capability's API, the [cookbook](/docs/cookbook/rag-with-vectors) shows end-to-end patterns, and the [reference](/docs/reference/cli) documents every command and [error code](/docs/reference/error-reference). If you are wiring StrataDB into an agent, the binary also describes itself: `strata agents guide` prints an offline usage guide generated from the installed build, and `strata agents commands --json` emits a machine-readable catalog. Because that surface comes straight from the binary, it always matches the version you have installed. The [For Agents](/docs/agents) page is the fastest way in. Everywhere in these docs, the commands and outputs shown are ones the CLI actually produces — if a page and the binary ever disagree, trust the binary and check whether your installed version matches these docs. --- # Primitives Source: https://stratadb.org/docs/concepts/primitives StrataDB gives you **five data primitives**, each shaped for a different job rather than forcing everything into one generic model. They all live in the same database, in the same branch, and share the same storage substrate underneath. ## The five primitives | Primitive | Shape | Best for | |-----------|-------|----------| | **[KV](/docs/data/key-value)** | key → bytes | Working memory, config, scratchpads | | **[JSON](/docs/data/json)** | key → JSON document with path access | Structured records, conversation state | | **[Event log](/docs/data/events)** | append-only, hash-linked sequence of typed events | Audit trails, tool-call history, decision logs | | **[Vector](/docs/data/vectors)** | collections of keyed embeddings with metadata | Similarity search, RAG context, agent memory | | **[Graph](/docs/data/graph)** | typed nodes and weighted, typed edges | Relationships, knowledge graphs, traversal | A database reports exactly these capabilities. `describe` lists them and their current counts: ```text $ strata ./db describe { "capabilities": { "kv": true, "json": true, "event": true, "vector": true, "graph_core": true, ... }, "primitives": { "kv_count": 1, "json_count": 0, "event_count": 0, "graphs": [], "vector_collections": [] }, ... } ``` ## One substrate underneath The five primitives are not five separate storage engines. Underneath, StrataDB has a single physical primitive: a **branch-aware, versioned (MVCC) key-value row**. JSON documents, events, vectors, and graph nodes and edges are all encoded as rows in that one store. This is why every primitive gets the same properties for free: - **Branch isolation** — every row is scoped to a branch, so a fork isolates all five capabilities at once. See [Branches](/docs/concepts/branches). - **Versioning and time travel** — every write is a [commit](/docs/concepts/commits) with a version and timestamp, so `--as-of` reads and history work the same across KV, JSON, events, vectors, and graphs. - **Uniform durability** — the same [durability](/docs/concepts/durability) guarantees cover every primitive, because they all write to the same log. You never manage the substrate directly. You work through each capability's own commands, and the shared row model is what keeps their semantics consistent. ## Choosing the right primitive **A simple value under a key** → KV. Values are opaque bytes; the store does not interpret them. **A structured record you update in place** → JSON. Read and write at paths like `$.config.temperature` without rewriting the whole document. **An immutable history of what happened** → Event log. Events are append-only and hash-linked, so the sequence can be verified and never rewritten. **Text or data you search by similarity** → Vector. Create a collection with a fixed dimension and distance metric, upsert embeddings with metadata, and query for nearest neighbors. **Entities and the relationships between them** → Graph. Add nodes, connect them with typed edges, and walk neighbors. An edge requires both endpoints to exist first. There is no general-purpose "state cell" primitive — coordination values live in KV or JSON, and history lives in the event log. ## Spaces: organizing within a branch Within a single branch, you can partition primitives into **spaces** — every operation targets the `default` space unless you pass `--space `. Spaces group related data inside a branch; branches are the isolation boundary between unrelated data. See the [Spaces concept](/docs/concepts/spaces) for the model and the [Spaces guide](/docs/guides/spaces) for the verbs. ## Beyond the five Two more capabilities sit alongside the primitives but are not data types of their own: [Arrow](/docs/guides/import-export) import/export moves rows in and out in columnar batches, and [inference](/docs/inference) runs local and cloud models. Both operate on the primitives above rather than storing a distinct shape. ## Next - [Value Types](/docs/concepts/value-types) — what a value actually is in each primitive - [Guides](/docs/data/key-value) — per-primitive API walkthroughs --- # Spaces Source: https://stratadb.org/docs/concepts/spaces A **space** is a named partition of data *inside* a branch. Spaces and [branches](/docs/concepts/branches) are Strata's two organizing dimensions — neither is a data type of its own. Your data always lives in one of the five [primitives](/docs/concepts/primitives); branches isolate *history* across forks, and spaces scope *which slice* of that data you see within a single branch. This page is the mental model; the verbs are in the [Spaces guide](/docs/guides/spaces). ## Two dimensions, not three data types Think of it as a grid. A database has one or more branches. Within each branch, data is partitioned into spaces. Within each space, you use the five primitives. - **Branch** answers *"which line of history?"* — forked, isolated, time-travellable. - **Space** answers *"which partition within this line?"* — tenants, sessions, datasets. - **Primitive** answers *"what shape of data?"* — KV, JSON, vectors, events, graph. Every branch has a `default` space, and you can add more. A command targets a space with `--space `; omit it and you get `default`. ## Spaces scope every primitive Each space holds its own independent instance of every primitive. The **same key in two spaces refers to two different values** — write `report` in an `analytics` space and the `default` space does not see it. This is true for KV, JSON, vectors, events, and graphs alike: a space is a clean partition across the whole data model, not just one primitive. ## Spaces compose with branches A branch *contains* spaces, and forking a branch **carries its spaces along** — the fork starts with the same partitions as its parent, then diverges independently. So the two dimensions stack: fork a branch to get an isolated copy of history, and within it use spaces to keep unrelated data apart. ## Spaces or branches? - Reach for a **space** to keep related data organized inside one line of history that lives and versions together — one space per tenant, per agent session, or per dataset. - Reach for a **branch** when you want an isolated copy of history you can fork, time-travel, and discard. They are complementary, not alternatives: a per-tenant space inside a per-feature branch is a perfectly normal layout. ## Next - [Spaces guide](/docs/guides/spaces) — the `list` / `create` / `exists` / `delete` verbs and their semantics. - [Branches](/docs/concepts/branches) — the other organizing dimension. - [Primitives](/docs/concepts/primitives) — the data shapes a space partitions. --- # Time travel Source: https://stratadb.org/docs/concepts/time-travel Time travel is reading the database as it was at an earlier point, not restoring a backup. Because every write is a [commit](/docs/concepts/commits) with a version and timestamp, the past is still there — and any read can ask for it. This works the same across all five [primitives](/docs/concepts/primitives), because they share one versioned substrate. ## The commit clock Each successful write returns a **commit**: a monotonically increasing version and a small logical timestamp. That timestamp is a *commit clock* — the first user write is a low integer, and it advances by one per commit — not a wall-clock time. You capture it from a write receipt (`data.commit.timestamp` under `--json`) and hand it back to a read to pin that read to that moment. ```bash strata ./mydb json set user:1 '$.plan' '"pro"' # receipt carries commit.timestamp, say 7 strata ./mydb json set user:1 '$.plan' '"free"' # a later commit, say 8 ``` ## Reading the past with `--as-of` Every read verb accepts `--as-of `. The read sees the state as of that commit, ignoring everything written after it: ```bash strata ./mydb json get user:1 '$.plan' # "free" (latest) strata ./mydb --as-of 7 json get user:1 '$.plan' # "pro" (as of commit 7) ``` The same `--as-of` applies to KV, JSON, vectors, events, and the graph — pass one timestamp and you get a **consistent snapshot of the whole database** at that commit, not a per-primitive patchwork. That is the payoff of a shared substrate; [Combining primitives](/docs/data/combining-primitives) shows it across all five at once. Alongside point-in-time reads, most primitives expose a `history` verb that lists a key's prior revisions newest-first, so you can see *what* changed as well as read *as of* a change. ## Two kinds of timestamp Do not confuse the commit clock with data timestamps: - The **commit timestamp** (`--as-of`) is the logical clock above — small integers from a write receipt. It selects a database snapshot. - The [event log](/docs/data/events) additionally stamps each event with a wall-clock microsecond `timestamp`, used by `event range-time` to select events by real time. That is a property of the event payload, not the snapshot clock. When in doubt: `--as-of` travels the database's history; `range-time` filters events by their own recorded time. ## Forking at a point in time Time travel composes with [branches](/docs/concepts/branches). You can not only *read* a past commit — you can *fork* from one, creating a new branch anchored to that moment and then evolving it independently: ```bash strata ./mydb branch fork main investigate --timestamp 7 ``` That gives you a live branch that starts from the state at commit 7, leaving `main` untouched — the basis for "reproduce the bug as of last Tuesday, then poke at it" workflows. ## The retention boundary History is retained, but not unbounded. Asking for a version or timestamp that has aged out of retained history is a distinct, typed error — `history_unavailable` — rather than a silent wrong answer or a not-found. Branch on that class if your workflow reaches far back; see [error handling](/docs/guides/error-handling). ## Next - [Commits](/docs/concepts/commits) — the write side: how versions and timestamps are produced. - [Branches](/docs/concepts/branches) — isolation, and forking from a past point. - [Combining primitives](/docs/data/combining-primitives) — one snapshot across all five primitives. --- # Value Types Source: https://stratadb.org/docs/concepts/value-types StrataDB does not have one universal value type. What counts as a "value" depends on which [primitive](/docs/concepts/primitives) you are using. Knowing the value model of each one saves you from surprises — especially in KV, which is more literal than you might expect. ## KV values are opaque bytes The KV store maps a byte key to a byte value. It does **not** interpret, parse, or type your values. If you put the text `42`, you get back the two bytes `4` and `2` — not an integer. ```text $ strata ./db kv put n 42 created n applied=true $ strata ./db kv get n 42 ``` That last `42` is a string of bytes displayed as text, not a number. You can see this on the `--json` wire, where KV values are base64-encoded because they are raw bytes: ```text $ strata --json ./db kv get n {"data":{"timestamp":3,"value":"NDI=","version":3},"type":"kv_versioned_value"} ``` `NDI=` is base64 for the ASCII characters `42`. In the default human output, byte values are shown as text when they are valid UTF-8. Because values are just bytes, you can store anything — including binary — with `kv put @file` or `--file`. If you want typed, structured data with a key, use the JSON store instead. ## JSON values use the JSON model The JSON store carries the full JSON type model: objects, arrays, strings, numbers, booleans, and null. Types are preserved on read, and you can address any path within a document. ```text $ strata ./db json set doc '$' '{"name":"alice","age":30,"score":3.14,"active":true,"tags":["a","b"],"meta":null}' created doc applied=true $ strata ./db json get doc '$.age' 30 $ strata ./db json get doc '$.score' 3.14 $ strata ./db json get doc '$.active' true $ strata ./db json get doc '$.name' "alice" $ strata ./db json get doc '$.meta' null ``` Notice that `age` reads back as the number `30`, `score` as `3.14`, `active` as the boolean `true`, and `name` as the quoted string `"alice"`. The JSON store knows the difference between these; the KV store would treat all of them as bytes. You can also write to a path in place: ```text $ strata ./db json set doc '$.age' 31 updated doc applied=true ``` ## Vector values are embeddings plus metadata A vector value has two parts: a fixed-length array of 32-bit floats (the embedding) and an optional JSON metadata object. The collection fixes the dimension and distance metric when you create it; every vector in it must match that dimension. ```text $ strata ./db vector collection create docs 3 --metric cosine $ strata ./db vector upsert docs a '[1,0,0]' --metadata '{"lang":"en"}' $ strata ./db vector get docs a { "data": { "embedding": [1.0, 0.0, 0.0], "metadata": { "lang": "en" } }, "key": "a", "timestamp": 5, "vector_revision": 1, "version": 5 } ``` The metadata object uses the JSON model and is what you filter on at query time. ## Event payloads are JSON objects An event carries a type label and a JSON payload. The payload is a JSON value — typically an object — and it is stored exactly as given, alongside a sequence number and a hash that links it to the previous event. ```text $ strata ./db event append audit '{"action":"login","user":"alice"}' created applied=true ``` ## Graph values are nodes and edges A graph node is an id with optional JSON properties. An edge connects two existing nodes, carries a type label and a numeric weight (default `1.0`), and may also hold properties. Endpoints must exist before an edge can be written. ```text $ strata ./db graph add-node social alice $ strata ./db graph add-edge social alice knows bob ``` ## The through-line The rule of thumb: **KV is bytes, everything else is structured.** Reach for KV when you want to store and return exact bytes without interpretation, and for JSON, vectors, events, or graphs when you want the database to understand the shape of your data. All of them are versioned and branch-scoped the same way — the difference is only in what a single value means. ## Next - [Primitives](/docs/concepts/primitives) — the five capabilities in full - [Value Type Reference](/docs/reference/value-type-reference) — the complete specification - [KV Store](/docs/data/key-value) and [JSON Store](/docs/data/json) — the two value models in practice --- # A/B Testing with Branches Source: https://stratadb.org/docs/cookbook/ab-testing-with-branches Goal: run two agent strategies side by side and compare them, with each variant's writes fully isolated from the other and from your baseline. Prerequisites: the `strata` binary on your PATH, and `jq` for the compact fork output. Commands write to a durable directory (`./ab`) that each invocation reopens. ## 1. Seed a shared baseline Anything written before you fork is inherited by every variant. ```bash strata ./ab kv put prompt:system "You are a helpful assistant." ``` ```text created prompt:system applied=true ``` ## 2. Fork one branch per variant A fork is a cheap copy-on-write branch. Both start from the baseline at the same version. ```bash strata ./ab branch fork default variant-a --json | jq -c '{name: .data.name, forked_from: .data.parent.name, at_version: .data.parent.fork_version}' strata ./ab branch fork default variant-b --json | jq -c '{name: .data.name, forked_from: .data.parent.name, at_version: .data.parent.fork_version}' ``` ```text {"name":"variant-a","forked_from":"default","at_version":3} {"name":"variant-b","forked_from":"default","at_version":3} ``` ## 3. Run each variant on its own branch Pass `--branch` to target a variant. Here A runs cooler and produces two answers; B runs hotter and produces three. ```bash strata ./ab kv put config:temperature 0.2 --branch variant-a strata ./ab event append answer '{"variant":"a","tokens":180}' --branch variant-a strata ./ab event append answer '{"variant":"a","tokens":210}' --branch variant-a strata ./ab kv put score 74 --branch variant-a strata ./ab kv put config:temperature 0.9 --branch variant-b strata ./ab event append answer '{"variant":"b","tokens":320}' --branch variant-b strata ./ab event append answer '{"variant":"b","tokens":295}' --branch variant-b strata ./ab event append answer '{"variant":"b","tokens":410}' --branch variant-b strata ./ab kv put score 88 --branch variant-b ``` ```text created config:temperature applied=true created applied=true created applied=true created score applied=true created config:temperature applied=true created applied=true created applied=true created applied=true created score applied=true ``` ## 4. Compare the branches Read each variant's score and answer count directly. ```bash strata ./ab --raw kv get score --branch variant-a strata ./ab event count --branch variant-a strata ./ab --raw kv get score --branch variant-b strata ./ab event count --branch variant-b ``` ```text 74 2 88 3 ``` ## 5. Confirm the baseline is untouched The per-variant config never leaked back to `default`. ```bash strata ./ab kv exists config:temperature ``` ```text false ``` ## 6. Promote the winner There is no branch-merge command. To fold the winning variant into `default`, you replay its writes there — read the winner's values and put them on `default`. Variant B scored higher (88 vs 74), so promote it. ```bash strata ./ab kv put config:temperature "$(strata ./ab --raw kv get config:temperature --branch variant-b)" strata ./ab kv put score "$(strata ./ab --raw kv get score --branch variant-b)" strata ./ab --raw kv get config:temperature strata ./ab --raw kv get score ``` ```text created config:temperature applied=true created score applied=true 0.9 88 ``` ## Why this works Each fork is an isolated [branch](/docs/concepts/branches): writes on `variant-a` and `variant-b` never see each other, and neither disturbs `default`. Because a fork shares the parent's history until it diverges, the baseline you seed in step 1 is visible in both variants for free — no cleanup of half-written state on a shared branch. Promotion is a deliberate replay of the winner's writes onto `default`, not an automatic merge, so you decide exactly what graduates. See the [branch management guide](/docs/guides/branching-workflows) for the full lifecycle, the [KV store guide](/docs/data/key-value) for value reads, and the [event log guide](/docs/data/events) for per-branch action counts. --- # Agent State Management Source: https://stratadb.org/docs/cookbook/agent-state-management Goal: keep an agent's configuration, working memory, and action history in the primitives that fit each best, and use versioned reads to inspect what the agent believed at an earlier point. Prerequisites: the `strata` binary on your PATH. Commands write to a durable directory (`./agent`) that each invocation reopens. ## 1. Pin configuration in KV Flat, rarely-changing settings belong in the key-value store. ```bash strata ./agent kv put config:model tinyllama strata ./agent kv put config:max_steps 8 ``` ```text created config:model applied=true created config:max_steps applied=true ``` ## 2. Initialize working memory as a JSON document Structured, evolving state belongs in a JSON document you can patch by path. ```bash strata ./agent json set agent '$' '{"status":"planning","step":0,"scratchpad":[]}' ``` ```text created agent applied=true ``` ## 3. Advance the run Each step patches memory and appends to the action log. The event log is your append-only audit trail. ```bash strata ./agent event append tool_call '{"step":0,"tool":"web_search","query":"strata database"}' strata ./agent json set agent '$.status' '"acting"' strata ./agent event append tool_result '{"step":0,"status":"ok","hits":3}' strata ./agent json set agent '$.step' '1' strata ./agent event append tool_call '{"step":1,"tool":"summarize"}' strata ./agent json set agent '$.step' '2' strata ./agent json set agent '$.status' '"done"' ``` Each `json set` prints `updated agent applied=true`; each `event append` prints `created applied=true`. ## 4. Read the current state ```bash strata ./agent --raw kv get config:model strata ./agent --raw json get agent '$' strata ./agent event count ``` ```text tinyllama {"scratchpad":[],"status":"done","step":2} 3 ``` ## 5. Inspect an earlier state Every write carries a commit timestamp. List the document's history, then read `--as-of` any of those timestamps to see the exact memory at that point — a rollback-style inspection with no rollback. ```bash strata ./agent json history agent strata ./agent --raw json get agent '$' --as-of 5 strata ./agent --raw json get agent '$' --as-of 9 ``` ```text {"document_version":5,"timestamp":12,"tombstone":false,"value":{"scratchpad":[],"status":"done","step":2},"version":12} {"document_version":4,"timestamp":11,"tombstone":false,"value":{"scratchpad":[],"status":"acting","step":2},"version":11} {"document_version":3,"timestamp":9,"tombstone":false,"value":{"scratchpad":[],"status":"acting","step":1},"version":9} {"document_version":2,"timestamp":7,"tombstone":false,"value":{"scratchpad":[],"status":"acting","step":0},"version":7} {"document_version":1,"timestamp":5,"tombstone":false,"value":{"scratchpad":[],"status":"planning","step":0},"version":5} {"scratchpad":[],"status":"planning","step":0} {"scratchpad":[],"status":"acting","step":1} ``` ## Why this works Each primitive carries its own version history, so you never overwrite the past — you append to it. Config lives in [KV](/docs/data/key-value), evolving memory in a [JSON document](/docs/data/json), and every action in the [event log](/docs/data/events). Because reads accept a [commit](/docs/concepts/commits) timestamp via `--as-of`, "what did the agent know at step 1" is one query, not a reconstruction. When you need to branch from an earlier point rather than just read it, fork the branch at that version — see [A/B Testing with Branches](/docs/cookbook/ab-testing-with-branches). --- # Deterministic Replay Source: https://stratadb.org/docs/cookbook/deterministic-replay Goal: make an agent run reproducible by recording every nondeterministic input in the event log, then reconstruct the exact committed state at any past point. Prerequisites: the `strata` binary on your PATH, and `jq` for readable event output. Commands write to a durable directory (`./replay`) that each invocation reopens. ## 1. Record every external input Before the agent acts on a clock reading, an API response, or a random draw, write it to the event log. The log is append-only and hash-linked, so it is the source of truth for the run. Derived decisions go in KV. ```bash strata ./replay event append input '{"source":"clock","epoch":1706900000}' strata ./replay event append input '{"source":"weather_api","temp_c":12}' strata ./replay event append input '{"source":"rng","value":2}' strata ./replay kv put decision "option 2" ``` ```text created applied=true created applied=true created applied=true created decision applied=true ``` ## 2. Walk the recorded inputs in order Read the log back by sequence. Because the decision was a pure function of these inputs, re-running the same logic over them reproduces the same result. ```bash strata ./replay event range 0 --json | jq -c '.data.items[] | {seq: .event.sequence, type: .event.event_type, payload: .event.payload}' ``` ```text {"seq":0,"type":"input","payload":{"epoch":1706900000,"source":"clock"}} {"seq":1,"type":"input","payload":{"source":"weather_api","temp_c":12}} {"seq":2,"type":"input","payload":{"source":"rng","value":2}} ``` ## 3. Verify the log was not tampered with Every event links to the previous one by hash. `verify-chain` confirms the sequence is dense and the linkage is intact. ```bash strata ./replay event verify-chain ``` ```text { "error": null, "first_invalid": null, "length": 3, "valid": true } ``` ## 4. Reconstruct an exact past state Suppose the agent later overwrites its decision. You can still recover the earlier committed state: fork a branch at the version where `option 2` was written. The `decision` write committed at version 6, so fork there. ```bash strata ./replay kv put decision "option 9" strata ./replay branch fork default replay --version 6 --json | jq -c '{name: .data.name, forked_from: .data.parent.name, at_version: .data.parent.fork_version}' strata ./replay --raw kv get decision --branch replay strata ./replay --raw kv get decision ``` ```text updated decision applied=true {"name":"replay","forked_from":"default","at_version":6} option 2 option 9 ``` The `replay` branch reads the historical `option 2`; `default` keeps the current `option 9`. ## Why this works Nondeterminism only breaks reproducibility if it is thrown away. Recording each input in the [event log](/docs/data/events) turns the run into a replayable transcript, and hash linkage lets you prove it is unaltered. Every write also gets a monotonic [commit](/docs/concepts/commits) version, so forking a [branch](/docs/concepts/branches) at that version rebuilds the exact state the agent saw — no snapshots to manage. See the [branch management guide](/docs/guides/branching-workflows) for the fork variants (at-version and at-timestamp). --- # Cookbook Source: https://stratadb.org/docs/cookbook Task-oriented recipes for building agent systems on Strata. Each one is a short sequence of real commands with the exact output you should see. Follow the steps in order and you land on the same results. Every recipe writes to a durable database directory (for example `./ab`) that each command reopens. The `--cache` flag is single-process only — separate invocations do not share an in-memory database — so multi-step recipes keep the database on disk. - **[A/B Testing with Branches](/docs/cookbook/ab-testing-with-branches)** — fork one branch per variant, run each in isolation, compare the results. - **[Agent State Management](/docs/cookbook/agent-state-management)** — hold config in KV, working memory in a JSON document, and an action log in events; inspect earlier state with versioned reads. - **[Deterministic Replay](/docs/cookbook/deterministic-replay)** — record external inputs in the event log and reconstruct any past state with versioned reads and fork-at-version. - **[Multi-Agent Coordination](/docs/cookbook/multi-agent-coordination)** — give each agent an isolated branch, share an append-only event journal, and separate runs with spaces. - **[RAG with Vectors](/docs/cookbook/rag-with-vectors)** — store embeddings in a vector collection and source text in KV, then query and fetch the matching rows. --- # Multi-Agent Coordination Source: https://stratadb.org/docs/cookbook/multi-agent-coordination Goal: let several agents work in parallel without stepping on each other, then gather their results — using isolated branches for private work and a shared event log as the common journal. Prerequisites: the `strata` binary on your PATH, and `jq` for readable output. Commands write to a durable directory (`./team`) that each invocation reopens. ## 1. Publish the shared task list Work everyone can read starts on the `default` branch. ```bash strata ./team kv put task:1 "summarize the changelog" strata ./team kv put task:2 "draft release notes" ``` ```text created task:1 applied=true created task:2 applied=true ``` ## 2. Give each agent an isolated branch ```bash strata ./team branch fork default agent-a --json | jq -c '{name: .data.name, forked_from: .data.parent.name, at_version: .data.parent.fork_version}' strata ./team branch fork default agent-b --json | jq -c '{name: .data.name, forked_from: .data.parent.name, at_version: .data.parent.fork_version}' ``` ```text {"name":"agent-a","forked_from":"default","at_version":4} {"name":"agent-b","forked_from":"default","at_version":4} ``` ## 3. Each agent works privately Writes on one agent's branch are invisible to the other, so they never collide — even on the same key (`result`). ```bash strata ./team kv put result "changelog summary: 12 fixes, 3 features" --branch agent-a strata ./team kv put result "release notes draft" --branch agent-b ``` ```text created result applied=true created result applied=true ``` ## 4. Report progress to a shared journal Appends to `default` are atomic and auto-commit, so the event log is a safe shared journal that any agent can add to. ```bash strata ./team event append progress '{"agent":"a","task":1,"state":"done"}' strata ./team event append progress '{"agent":"b","task":2,"state":"done"}' ``` ```text created applied=true created applied=true ``` ## 5. Aggregate the results A coordinator reads each agent's branch and the shared journal. ```bash strata ./team --raw kv get result --branch agent-a strata ./team --raw kv get result --branch agent-b strata ./team event count strata ./team event range 0 --json | jq -c '.data.items[] | {seq: .event.sequence, payload: .event.payload}' ``` ```text changelog summary: 12 fixes, 3 features release notes draft 2 {"seq":0,"payload":{"agent":"a","state":"done","task":1}} {"seq":1,"payload":{"agent":"b","state":"done","task":2}} ``` ## 6. Separate whole runs with spaces A space is a second, independent axis of isolation. The same key holds different values in different spaces, so a second team's run never collides with the first. ```bash strata ./team space create team-2 strata ./team kv put task:1 "unrelated task" --space team-2 strata ./team --raw kv get task:1 strata ./team --raw kv get task:1 --space team-2 ``` ```text created team-2 applied=true created task:1 applied=true summarize the changelog unrelated task ``` ## Why this works Coordination here is by isolation and aggregation. Each agent owns a private [branch](/docs/concepts/branches), so concurrent work cannot conflict; you gather outcomes by reading each branch. Strata has no branch-merge step, so the pattern is a shared append-only [event journal](/docs/data/events) plus per-branch reads — and when you want an agent's result to graduate to the shared branch, you replay its writes there, as shown in [A/B Testing with Branches](/docs/cookbook/ab-testing-with-branches). [Spaces](/docs/guides/spaces) add an orthogonal partition for keeping independent runs apart, and the [branch management guide](/docs/guides/branching-workflows) covers forking and deleting agent branches. --- # RAG with Vectors Source: https://stratadb.org/docs/cookbook/rag-with-vectors Goal: build the retrieval half of a RAG pipeline — index document embeddings alongside their source text, then find the nearest documents to a query and pull back the text to feed a model. Prerequisites: the `strata` binary on your PATH, and `jq` to read match metadata. Commands write to a durable directory (`./rag`) that each invocation reopens. The vectors below are tiny and explicit so the recipe is self-contained; see the note at the end on generating real embeddings. ## 1. Create a collection Fix the embedding dimension and distance metric up front. ```bash strata ./rag vector collection create notes 4 --metric cosine ``` ```text {"count":0,"dimension":4,"metric":"cosine","name":"notes"} ``` ## 2. Index documents Upsert one vector per document, tagging each with a `text_key` in metadata that points at the KV row holding its full text. Store that text in KV. ```bash strata ./rag vector upsert notes note-1 '[1,0,0,0]' --metadata '{"text_key":"src:note-1"}' strata ./rag vector upsert notes note-2 '[0,1,0,0]' --metadata '{"text_key":"src:note-2"}' strata ./rag vector upsert notes note-3 '[0,0,1,0]' --metadata '{"text_key":"src:note-3"}' strata ./rag kv put src:note-1 "Branches fork cheaply and isolate writes." strata ./rag kv put src:note-2 "The event log is an append-only journal." strata ./rag kv put src:note-3 "Vectors support cosine, euclidean, and dot-product." ``` ```text created note-1 applied=true created note-2 applied=true created note-3 applied=true created src:note-1 applied=true created src:note-2 applied=true created src:note-3 applied=true ``` ## 3. Query with an embedding Search returns the nearest keys with similarity scores, best first. ```bash strata ./rag vector query notes '[0.9,0.2,0.1,0]' -k 2 ``` ```text note-1 0.9704949259757996 note-2 0.2156655490398407 ``` ## 4. Fetch the source text Read each match's `text_key` from its metadata, then pull the row from KV. This is the context you hand to your generation step. ```bash strata ./rag --json vector query notes '[0.9,0.2,0.1,0]' -k 2 \ | jq -r '.data[].metadata.text_key' \ | while read -r tk; do printf '%s\t%s\n' "$tk" "$(strata ./rag --raw kv get "$tk")"; done ``` ```text src:note-1 Branches fork cheaply and isolate writes. src:note-2 The event log is an append-only journal. ``` ## Generating real embeddings In production you replace the hand-written vectors with model output. The `strata inference embed ` command is the slot for this — its result becomes the vector you pass to `vector upsert` (indexing) and `vector query` (search). Embedding runs where the model does: on a build compiled with the local inference feature, or against a configured cloud provider. A build without local inference refuses with a coded error: ```text inference.unsupported_operation: not supported: local embedding requires the local feature hint: Inspect inference configuration and retry with supported settings. ref: https://stratadb.org/e/inference.unsupported_operation ``` Recover by code and class, never by message text — the bracketed reference id in the full output changes every run. See [/e/inference.unsupported_operation](/e/inference.unsupported_operation). ## Why this works The vector collection and KV store are two [primitives](/docs/concepts/primitives) over one substrate, so an embedding and its source text commit to the same database and stay consistent. Keeping the authoritative text in [KV](/docs/data/key-value) and only the embedding in the [vector store](/docs/data/vectors) means search accelerates retrieval without becoming the system of record. When you add local or cloud inference, the [inference guide](/docs/inference) shows how `embed` output feeds the same upsert and query commands used here. --- # Combining primitives Source: https://stratadb.org/docs/data/combining-primitives Each of the five primitives — [KV](/docs/data/key-value), [JSON](/docs/data/json), [Vectors](/docs/data/vectors), [Events](/docs/data/events), and [Graph](/docs/data/graph) — is useful on its own. The reason they live in **one database** is that most real workloads use several at once, over the same data. A single Strata database holds all five simultaneously; they share one branch-aware, versioned storage substrate, so a branch, a commit, and an `--as-of` snapshot span every primitive together rather than each keeping its own timeline. This page covers the patterns that combine them. Two rules run through all of them: - **Source rows are authoritative.** A vector index or a JSON secondary index *accelerates* retrieval; it never *replaces* the row it points at. You resolve a search hit back to the KV, JSON, or graph row that owns the truth. - **One snapshot spans everything.** Because every primitive rides the same commit clock, a single `--as-of ` gives you a consistent view of the whole database — documents, embeddings, events, and graph as they were at that commit. ## Retrieval-augmented generation RAG needs two stores that stay in sync: the **documents** you retrieve and return, and the **embeddings** you search. Keep the documents in JSON (or KV for opaque blobs) and the embeddings in a vector collection, keyed the same way so a search hit resolves straight back to its source. ```bash # Source of truth: the document, addressable by field. strata ./kb json set doc:42 '$' \ '{"title":"Branching model","body":"Strata forks are copy-on-write…","tags":["branches"]}' # Derived: an embedding for the same key, in a collection sized to your model. strata ./kb vector collection create chunks 384 --metric cosine strata ./kb vector upsert chunks doc:42 "@doc42.vec" --metadata '{"doc":"doc:42"}' ``` At query time you embed the question, search the collection, then read each hit's document back: ```bash strata ./kb vector query chunks "@query.vec" -k 5 # → doc:42, doc:17, … (keys + scores) strata ./kb json get doc:42 '$' # → the authoritative document to feed the model ``` The vector primitive does not create embeddings — you supply the floats (or let [autoembedding](#autoembedding) supply them). For the full worked flow, including generating embeddings and calling a model, see [RAG with vectors](/docs/cookbook/rag-with-vectors). ## Semantic search with structured filters Similarity alone is often too broad. Attach structured metadata to each vector and filter the search so it only considers rows that match — recency, language, tenant, document type — while the authoritative fields still live in the JSON document. ```bash strata ./kb vector upsert chunks doc:42 "@doc42.vec" \ --metadata '{"lang":"en","year":2024,"doc":"doc:42"}' strata ./kb vector query chunks "@query.vec" -k 10 \ --filter '{"conditions":[{"field":"lang","op":"eq","value":{"type":"string","value":"en"}}]}' ``` Conditions are AND-composed, so a filter narrows the candidate set before scoring. Mirror only the fields you filter on into the vector metadata; keep the record of record in JSON, where you can index and update fields independently ([secondary indexes](/docs/data/json#secondary-indexes)). ## Knowledge graphs with embeddings A [graph](/docs/data/graph) node carries JSON properties directly, so entities and their relationships live in one place. Combine that with a vector collection keyed by node id and you get **hybrid retrieval**: find entry points by similarity, then traverse the graph to expand context. ```bash strata ./kg graph create org strata ./kg graph add-node org alice --properties '{"name":"Alice","role":"eng"}' strata ./kg graph add-node org bob --properties '{"name":"Bob","role":"eng"}' strata ./kg graph add-edge org alice reports_to bob # Embeddings keyed by node id, so a similarity hit names a graph node. strata ./kg vector collection create people 384 --metric cosine strata ./kg vector upsert people alice "@alice.vec" ``` Search the collection to find the closest node, then walk its neighbourhood — or run [analytics](/docs/data/graph#analytics) like PageRank or connected components over the same branch-consistent snapshot: ```bash strata ./kg vector query people "@query.vec" -k 1 # → alice strata ./kg graph neighbors org alice --direction both ``` ## Event-sourced state Treat the [event log](/docs/data/events) as the ordered, hash-linked record of *what happened*, and KV or JSON as the *current* materialised state you read from. The log is append-only and tamper-evident; the state store is overwritten in place. Because both are versioned on the same clock, you can always reconcile the two — or rebuild state by replaying the log. ```bash strata ./ledger event append account.credited '{"acct":"A1","amount":100}' strata ./ledger json set account:A1 '$.balance' 100 ``` If the materialised balance is ever in doubt, the events are the authority: read them back in order (or by time window with `event range-time`) and recompute. See [deterministic replay](/docs/cookbook/deterministic-replay) for the full pattern. ## One time-travel snapshot across all five This is the payoff of a shared substrate. Every write advances one commit clock, and every read verb accepts `--as-of ` — the small logical `commit.timestamp` from a write receipt, not a wall-clock time. Passing the same `--as-of` to different primitives gives you a **single consistent view of the entire database** at that commit: ```bash # Whatever the timestamp of an earlier commit was — say 12: strata ./app --as-of 12 json get user:1 '$' strata ./app --as-of 12 vector query chunks "@q.vec" -k 5 strata ./app --as-of 12 event range 0 strata ./app --as-of 12 graph meta org ``` Each command reads the document, the embeddings, the events, and the graph as they existed at commit 12 — no per-primitive snapshotting, no drift between them. [Branches](/docs/concepts/branches) extend the same idea across space instead of time: fork a branch, change documents, embeddings, and graph independently, and the parent keeps its own consistent timeline. [Commits](/docs/concepts/commits) explains the clock in detail. ## Producing embeddings The RAG and semantic-search patterns above have you produce embeddings yourself: call [`inference embed`](/docs/inference#the-operations) (or your own model) and `vector upsert` the result under the same key as the source row. That explicit embed-then-upsert flow is the supported path in this release, and it keeps the boundary clear — the source row is authoritative; the vector only accelerates retrieval. Strata's architecture reserves **autoembedding** — engine-owned derived vectors kept in sync as you write text, so retrieval stays fresh without a manual embed step, with the source row still authoritative. That capability is not yet exposed in this release. See [Inference](/docs/inference) for the model surface today. ## Where next - Each primitive's how-to: [KV](/docs/data/key-value), [JSON](/docs/data/json), [Vectors](/docs/data/vectors), [Events](/docs/data/events), [Graph](/docs/data/graph). - The isolation and time-travel model: [Branches](/docs/concepts/branches), [Commits](/docs/concepts/commits). - Worked, end-to-end recipes: [RAG with vectors](/docs/cookbook/rag-with-vectors), [agent state management](/docs/cookbook/agent-state-management), [deterministic replay](/docs/cookbook/deterministic-replay). - Per-command details for any primitive are in the generated [command reference](/docs/reference/kv). --- # Events Source: https://stratadb.org/docs/data/events The event log is an append-only, ordered sequence of typed events. Each event gets a monotonic sequence number and is hash-linked to the one before it, so the log is tamper-evident. Use it for audit trails, agent action histories, change feeds, or anything where the order and integrity of what happened matters. Like every [primitive](/docs/concepts/primitives), the log is branch-aware and versioned. Examples below were run against the shipped binary. Use a directory path for a durable database or `--cache` for a throwaway run. ## Append events `event append ` adds one event. The payload is parsed as JSON; use `@path` or `-f ` to read it from a file. Appends auto-commit. ```bash strata ./mydb event append order.created '{"id":"A1","total":42}' ``` ```text created applied=true ``` The `--json` envelope shows the assigned sequence. Sequences start at 0: ```bash strata --json ./mydb event append order.paid '{"id":"A1"}' ``` ```text {"data":{"commit":{"delete_count":0,"durable":true,"put_count":3,"timestamp":4,"version":4},"effect":{"affected_count":1,"applied":true,"kind":"created","matched":false},"event_type":"order.paid","sequence":1,"timestamp":4,"version":4},"type":"event_append_result"} ``` ## Read one event `event get ` returns a single event. Alongside the payload and type it carries a `hash`, the `previous_hash` it links to, and an internal wall-clock `timestamp` in microseconds. ```bash strata ./mydb event get 0 ``` ```text { "event": { "event_type": "order.created", "hash": "82e2c6af52801cb5376a91937ddf98f0dddb10bf335b797035308179b0de29f6", "payload": { "id": "A1", "total": 42 }, "previous_hash": "0000000000000000000000000000000000000000000000000000000000000000", "sequence": 0, "timestamp": 1783735254224134 }, "timestamp": 3, "version": 3 } ``` The first event links to an all-zero `previous_hash`. Reading a sequence that does not exist is not an error — it returns null and exits zero. `event exists ` returns `true`/`false`, and `event count` counts visible events. ## List, filter by type `event list` returns events in order; `--limit`, `--event-type`, and `--after-sequence` (an exclusive cursor) page and filter it. `event types` lists the distinct types present, and `event by-type ` returns only that type. ```bash strata ./mydb event types strata ./mydb event by-type order.created --limit 5 ``` ```text order.created order.paid order.shipped {"event":{"event_type":"order.created","hash":"82e2c6af52801cb5376a91937ddf98f0dddb10bf335b797035308179b0de29f6","payload":{"id":"A1","total":42},"previous_hash":"0000000000000000000000000000000000000000000000000000000000000000","sequence":0,"timestamp":1783735254224134},"timestamp":3,"version":3} {"event":{"event_type":"order.created","hash":"3d44143df25625c0833ba804cff9530e502b0fc8bfd4ba2514f64afce1cee341","payload":{"id":"A2","total":17},"previous_hash":"4dc2683aad6b5f2ac92da28bfc738b21bc0d4db3424840abd8de7f4bc46a0c22","sequence":2,"timestamp":1783735254242541},"timestamp":5,"version":5} ``` ## Read ranges by sequence `event range ` reads from a sequence forward; `--end-seq` is an exclusive upper bound, `--limit` caps the page, and `--direction reverse` walks backward from the start. A trailing `-- more:` line carries the next cursor. ```bash strata ./mydb event range 3 --direction reverse --limit 2 ``` ```text {"event":{"event_type":"order.shipped","hash":"ac28ae25f43d627ca1503c3ec49be79930781526e747039283f158a027685387","payload":{"id":"A1"},"previous_hash":"3d44143df25625c0833ba804cff9530e502b0fc8bfd4ba2514f64afce1cee341","sequence":3,"timestamp":1783735254251352},"timestamp":6,"version":6} {"event":{"event_type":"order.created","hash":"3d44143df25625c0833ba804cff9530e502b0fc8bfd4ba2514f64afce1cee341","payload":{"id":"A2","total":17},"previous_hash":"4dc2683aad6b5f2ac92da28bfc738b21bc0d4db3424840abd8de7f4bc46a0c22","sequence":2,"timestamp":1783735254242541},"timestamp":5,"version":5} -- more: 2 ``` ## Read ranges by time `event range-time ` selects events by their wall-clock timestamp (microseconds, as printed in each event). `--end-ts` is an inclusive upper bound; `--direction` and `--event-type` work as with sequence ranges. ```bash strata ./mydb event range-time 1783735254224134 --end-ts 1783735254251352 ``` This returns every event whose internal timestamp falls in that window. Note the distinction from `--as-of`: the internal event `timestamp` is wall-clock, while `--as-of ` on reads uses the commit clock (the small `commit.timestamp` from a write receipt) to view a historical snapshot of the log. ## Verify the chain `event verify-chain` walks the log and confirms both that sequence numbers are dense and that each event's hash links to its predecessor. ```bash strata ./mydb event verify-chain ``` ```text { "error": null, "first_invalid": null, "length": 4, "valid": true } ``` If a link were broken, `valid` would be `false` and `first_invalid` would name the offending sequence. ## Branches and time travel The log is branch-scoped — each branch has its own sequence. Fork a branch to record a separate stream of events without touching the parent, and pass `--as-of` to any read verb (including `event count`) to see the log as of an earlier commit. See [Branches](/docs/concepts/branches) and [Commits](/docs/concepts/commits). ## Error cases worth knowing An invalid event type or an oversized payload is rejected with a coded error — for example [/e/invalid_argument.engine.event_type](/e/invalid_argument.engine.event_type) or [/e/invalid_argument.engine.event_payload_too_large](/e/invalid_argument.engine.event_payload_too_large). A payload that is not valid JSON fails to parse before it reaches the log. Recover by code, never by message — see [error handling](/docs/guides/error-handling). ## When to use the event log vs other primitives - Use the **event log** when order and integrity matter and you only ever append. - Use [KV](/docs/data/key-value) or [JSON](/docs/data/json) for mutable state you overwrite in place. - Use [Vectors](/docs/data/vectors) for similarity search. For a worked pattern, see [deterministic replay](/docs/cookbook/deterministic-replay). The full verb list is in the [CLI reference](/docs/reference/cli). ## From Python The same surface, from the [Python SDK](/docs/python) — note the count method is `len()`: ```python import stratadb db = stratadb.open("./mydb") record = db.events.append("deploy", {"ok": True}) record.sequence # 0 db.events.len() # 1 db.events.verify_chain() db.close() ``` See [namespaces](/docs/python/namespaces) for ranges, type filters, and `as_of` reads. ## Reference Every event command — parameters, returns, errors, and runnable CLI/wire/Python examples — is in the generated [Event command reference](/docs/reference/event). --- # Graph Source: https://stratadb.org/docs/data/graph The graph capability stores directed, typed, optionally weighted edges between property-bearing nodes. It sits on the same branch-aware storage as every other capability, so graphs fork, time-travel, and isolate per branch and [space](/docs/guides/spaces) like the rest. This guide walks the full command surface — structure, traversal, bulk loading, analytics, and the ontology — against one worked example. The examples target a durable database at `./social`. Graph commands emit JSON by default; add `--raw` for one-object-per-line output that is easier to pipe. ## Graphs A database holds many named graphs. Create one, list them, read its metadata, and delete it: ```bash strata ./social graph create social strata ./social graph list strata ./social graph meta social ``` ```text { "created_timestamp": 3, "created_version": 3, "edge_count": 0, "graph": "social", "node_count": 0, "updated_timestamp": 3, "updated_version": 3 } ``` `graph list` prints one name per line. `graph meta` returns live node and edge counts plus the create/update commit coordinates. Reading metadata for a graph that does not exist returns `(nil)`, not an error. Creating a graph that already exists fails with [`already_exists.engine.graph`](/e/already_exists.engine.graph). ## Nodes A node has an id and optional JSON properties. `add-node` inserts or replaces: ```bash strata ./social graph add-node social alice --properties '{"name":"Alice","role":"eng"}' strata ./social graph get-node social alice ``` ```text { "graph": "social", "node_id": "alice", "properties": { "name": "Alice", "role": "eng" }, "timestamp": 4, "version": 4 } ``` Pass `--properties-file ` to read the JSON from a file instead of the command line, and `--type ` to declare the node's object type (validated once you freeze an ontology — see below). List nodes with `graph list-nodes ` (accepts `--prefix`, `--limit`, `--cursor`), and remove one with `graph remove-node `. A removed or never-written node reads back as `(nil)`. ## Edges An edge connects two existing nodes under an edge type, with an optional weight and properties: ```bash strata ./social graph add-edge social alice follows bob --weight 1.0 --properties '{"since":2021}' strata ./social graph get-edge social alice follows bob ``` ```text { "dst": "bob", "edge_type": "follows", "graph": "social", "properties": { "since": 2021 }, "src": "alice", "timestamp": 10, "version": 10, "weight": 1.0 } ``` Both endpoints must already exist; writing an edge to a missing node fails with [`invalid_argument.engine.graph_edge_endpoint`](/e/invalid_argument.engine.graph_edge_endpoint). Remove an edge with `graph remove-edge `. ### Neighbors `graph neighbors` walks a node's edges. `--direction` is `outgoing` (default), `incoming`, or `both`; `--edge-type` filters by type, and `--limit`/`--cursor` paginate: ```bash strata ./social --raw graph neighbors social alice --direction outgoing ``` ```text {"direction":"outgoing","dst":"bob","edge":{"dst":"bob","edge_type":"follows","graph":"social","properties":{"since":2021},"src":"alice","timestamp":10,"version":10,"weight":1.0},"edge_type":"follows","graph":"social","node":{"graph":"social","node_id":"bob","properties":{"name":"Bob","role":"eng"},"timestamp":5,"version":5},"node_id":"bob","src":"alice"} ``` Each row carries the traversed edge and the neighbor node in full, so you rarely need a follow-up read. ## Bulk insert For loading many nodes and edges, `bulk-insert` ingests a JSON payload in chunked commits. Nodes use the key `node_id`; edges use `src`, `edge_type`, `dst`, and optional `weight`/`properties`: ```bash strata ./social graph bulk-insert loaded \ --data '{"nodes":[{"node_id":"n1","properties":{"kind":"a"}},{"node_id":"n2"},{"node_id":"n3"}],"edges":[{"src":"n1","edge_type":"link","dst":"n2","weight":1.0},{"src":"n2","edge_type":"link","dst":"n3"}]}' ``` ```text { "commit": { "delete_count": 0, "durable": true, "put_count": 2, "timestamp": 31, "version": 31 }, "commits": 2, "edges_inserted": 2, "graph": "loaded", "nodes_inserted": 3, "timestamp": 31, "version": 31 } ``` Use `--file ` instead of `--data` for large payloads, and `--chunk-size ` to bound items per commit. ## Analytics The example graph below has two components — a follow cycle among `alice`, `bob`, `carol` (plus `frank` following `alice`) and a mutual pair `dave`/`erin`. Every algorithm reads a consistent snapshot and accepts `--as-of ` for time travel. Weakly connected components (`wcc`) label each node with its component representative: ```bash strata ./social graph wcc social ``` ```text { "component_count": 2, "components": { "alice": "alice", "bob": "alice", "carol": "alice", "dave": "dave", "erin": "dave", "frank": "alice" }, "graph": "social" } ``` Local clustering coefficients (`lcc`), shortest-path distances from a source (`sssp`, with `--direction`), and PageRank (`pagerank`, with `--damping`, `--max-iterations`, `--tolerance`, and `--personalization` seed weights) all return per-node maps: ```bash strata ./social graph pagerank social ``` ```text { "graph": "social", "iterations": 20, "personalized": false, "ranks": { "alice": 0.2579646389410527, "bob": 0.13463229043004, "carol": 0.249069737295574, "dave": 0.16666666666666666, "erin": 0.16666666666666666, "frank": 0.025 } } ``` Community detection by label propagation (`cdlp`, with `--max-iterations` and `--direction`) returns a label per node. A bounded breadth-first traversal (`bfs`) returns visited nodes, per-node depths, and the traversed edges: ```bash strata ./social graph bfs social alice ``` ```text { "depths": { "alice": 0, "bob": 1, "carol": 1 }, "edges": [ { "dst": "bob", "edge_type": "follows", "src": "alice", "weight": 1.0 }, { "dst": "carol", "edge_type": "follows", "src": "alice", "weight": 1.0 } ], "graph": "social", "start": "alice", "visited": [ "alice", "bob", "carol" ] } ``` `bfs` bounds itself with `--max-depth` (default 100), `--max-nodes` (default 10000), `--direction`, and a repeatable `--edge-type` restriction. Running an algorithm from a node that does not exist fails with [`not_found.engine.graph_node`](/e/not_found.engine.graph_node). ## Ontology A graph can carry an ontology: declared object types and link types. While the ontology is a **draft**, you add and redraft types freely; nothing is enforced. When you **freeze** it, subsequent writes validate against it. This section starts a fresh database at `./org` with a graph named `org`, so the typed examples don't collide with the untyped `social` graph above. ```bash strata ./org graph ontology define-object-type org Person \ --properties '{"name":{"value_type":"string","required":true},"level":{"value_type":"integer","required":false}}' strata ./org graph ontology define-object-type org Team \ --properties '{"name":{"value_type":"string","required":true}}' strata ./org graph ontology define-link-type org member_of Person Team --cardinality many-to-one ``` A link type names its source and target object types; `--cardinality` is an optional hint. `graph ontology get ` prints the status and every declared type; `graph ontology delete-object-type` / `delete-link-type` remove draft types. Add typed nodes with `--type`, then freeze: ```bash strata ./org graph add-node org p1 --type Person --properties '{"name":"Alice","level":5}' strata ./org graph add-node org t1 --type Team --properties '{"name":"Platform"}' strata ./org graph ontology freeze org ``` ```text { "commit": { "delete_count": 0, "durable": true, "put_count": 1, "timestamp": 23, "version": 23 }, "graph": "org", "link_types": 1, "object_types": 2, "timestamp": 23, "version": 23 } ``` After freezing, a node declaring an undeclared type is rejected: ```bash strata ./org graph add-node org x1 --type Robot --properties '{"name":"R2"}' ``` ```text failed_precondition.engine.graph_ontology_node_type: node object type `Robot` is not declared in the frozen ontology (err_local_21ffcbc2_000001) hint: Reload the current state and retry the operation against the latest version. ref: https://stratadb.org/e/failed_precondition.engine.graph_ontology_node_type ``` `graph ontology summary ` adds per-type usage counts (nodes per object type, edges per link type), and `graph nodes-by-type ` lists the nodes declaring a given type: ```bash strata ./org graph nodes-by-type org Person ``` ```text {"graph":"org","node_id":"p1","object_type":"Person","properties":{"level":5,"name":"Alice"},"timestamp":21,"version":21} ``` ## Related - [Primitives](/docs/concepts/primitives) — how graphs sit alongside the other capabilities - [Branches](/docs/concepts/branches) and [Commits](/docs/concepts/commits) — the isolation and time-travel model - [Arrow](/docs/guides/import-export) — export a graph's nodes and edges to Parquet, CSV, or JSON lines - [Error Handling](/docs/guides/error-handling) — reading structured error codes ## From Python The same surface, from the [Python SDK](/docs/python) — endpoints must exist before an edge, exactly as on the CLI: ```python import stratadb db = stratadb.open("./social") db.graphs.create("social") db.graphs.add_node("social", "alice") db.graphs.add_node("social", "bob") db.graphs.add_edge("social", "alice", "follows", "bob") db.graphs.neighbors("social", "alice") # Page of GraphNeighborHit rows db.close() ``` See [namespaces](/docs/python/namespaces) for traversal, analytics, and the ontology surface. ## Reference Every graph command — parameters, returns, errors, and runnable CLI/wire/Python examples — is in the generated [Graph command reference](/docs/reference/graph). --- # JSON documents Source: https://stratadb.org/docs/data/json The JSON store keeps a JSON document under a string key and lets you read or write individual values inside it by path. Use it when your data has structure you want to address directly — a user record, a config object, an agent's working state — rather than an opaque blob. Like every [primitive](/docs/concepts/primitives), documents are branch-aware and versioned. Examples below were run against the shipped binary. Use a directory path for a durable database or `--cache` for a throwaway run. ## Set and get by path `json set ` writes a value at a path. The path `$` is the whole document; `$.field` addresses a top-level field, and paths nest with dots. The value is parsed as JSON — text that is not valid JSON is stored as a string; use `@path` or `-f ` to read the value from a file. ```bash strata ./mydb json set user:1 '$' '{"name":"Ada","age":36,"tags":["math","logic"]}' strata ./mydb json get user:1 '$' strata ./mydb json get user:1 '$.name' ``` ```text created user:1 applied=true {"age":36,"name":"Ada","tags":["math","logic"]} "Ada" ``` Update one field without rewriting the document, and add a new field the same way: ```bash strata ./mydb json set user:1 '$.age' 37 strata ./mydb json set user:1 '$.email' '"ada@example.com"' strata ./mydb json get user:1 '$' ``` ```text updated user:1 applied=true updated user:1 applied=true {"age":37,"email":"ada@example.com","name":"Ada","tags":["math","logic"]} ``` Writing `$` again replaces the entire document — JSON merge in this release is document-level, not field-level, so a full-document set overwrites fields you omit. To change one field, target its path. ## Delete a path `json delete ` removes a value. Deleting `$` removes the whole document; deleting `$.email` removes just that field. ```bash strata ./mydb json delete user:1 '$.email' ``` ```text deleted user:1 applied=true ``` Reading a missing path or a missing document is not an error — it reports that nothing was found: ```bash strata --json ./mydb json get user:1 '$.nope' ``` ```text {"data":{"found":false,"value":null},"type":"json_versioned_value"} ``` ## List, count, exists, sample These operate on document keys, mirroring the KV verbs: ```bash strata ./mydb json list strata ./mydb json count strata ./mydb json exists user:2 ``` ```text user:1 user:2 user:3 3 true ``` `json list --prefix

` filters by key prefix and pages via `--cursor`; `json sample --count ` returns an arbitrary handful of documents. ## History and time travel Each write retains prior document versions. `json history` lists them newest-first, and every read verb accepts `--as-of ` (the `commit.timestamp` from a write receipt) to read an earlier snapshot. ```bash strata ./mydb json history user:1 ``` ```text {"document_version":4,"timestamp":6,"tombstone":false,"value":{"age":37,"name":"Ada","tags":["math","logic"]},"version":6} {"document_version":3,"timestamp":5,"tombstone":false,"value":{"age":37,"email":"ada@example.com","name":"Ada","tags":["math","logic"]},"version":5} ``` Documents are branch-scoped. Fork a branch, write there, and the parent branch keeps its own version. See [Branches](/docs/concepts/branches). ## Secondary indexes Index a field to accelerate retrieval over it. `json index create ` supports three index types — `tag` (default, string equality), `numeric`, and `text` (lowercased). ```bash strata ./mydb json index create by_age '$.age' --index-type numeric ``` ```text { "created_timestamp": 9, "created_version": 9, "field_path": "age", "index_type": "numeric", "name": "by_age", "space": "default" } ``` `json index list` then shows the index, one compact record per line: ```bash strata ./mydb json index list ``` ```text {"created_timestamp":9,"created_version":9,"field_path":"age","index_type":"numeric","name":"by_age","space":"default"} ``` `json index drop ` removes it. Creating an index whose name already exists fails: ```bash strata --json ./mydb json index create by_age '$.age' --index-type numeric ``` ```text {"error":{"class":"already_exists","code":"already_exists.engine.json_index","retry_policy":"never","retryable":false,"commit_outcome":"not_started","message":"JSON index already exists","suggested_fix":"Reload the current state and retry the operation against the latest version.","docs_url":"https://stratadb.org/e/already_exists.engine.json_index","reference_id":"err_local_009f7060_000001"}} ``` ## Error cases worth knowing Writing into a path whose parent is the wrong type is rejected — here, setting `$.name.first` when `name` is a string: ```bash strata --json ./mydb json set user:1 '$.name.first' '"x"' ``` ```text {"error":{"class":"invalid_argument","code":"invalid_argument.engine.json_path_type","retry_policy":"never","retryable":false,"commit_outcome":"not_started","message":"JSON path expected object","suggested_fix":"Correct the request input and retry the operation.","docs_url":"https://stratadb.org/e/invalid_argument.engine.json_path_type","reference_id":"err_local_0e8cc4e8_000001"}} ``` Related codes include [/e/invalid_argument.engine.json_document](/e/invalid_argument.engine.json_document) for an invalid document id and [/e/already_exists.engine.json_index](/e/already_exists.engine.json_index). Match on the code, not the message — see [error handling](/docs/guides/error-handling). ## When to use JSON vs other primitives - Use **JSON** when you address fields inside a document by path or index by field. - Use [KV](/docs/data/key-value) for opaque values with no structure to query. - Use [Vectors](/docs/data/vectors) for similarity search. - Use the [Event Log](/docs/data/events) for an append-only, ordered history. See the [CLI reference](/docs/reference/cli) for the full verb list and [value types](/docs/concepts/value-types) for how JSON values are represented. ## From Python The same surface, from the [Python SDK](/docs/python) — documents are Python objects, addressed by path: ```python import stratadb db = stratadb.open("./mydb") db.json.set("user:1", "$", {"name": "Ada", "age": 36}) db.json.get("user:1", "$.name") # "Ada" db.close() ``` See [namespaces](/docs/python/namespaces) for indexes, history, and `as_of` reads. ## Reference Every JSON command — parameters, returns, errors, and runnable CLI/wire/Python examples — is in the generated [JSON command reference](/docs/reference/json). --- # Key-Value Source: https://stratadb.org/docs/data/key-value The KV store maps a byte key to a byte value. It is the simplest of the five [primitives](/docs/concepts/primitives) and the closest to the underlying storage substrate: every other primitive is layered over the same branch-aware, versioned rows. Reach for KV when you want a plain lookup table — session data, feature flags, cached blobs, small config — and you do not need JSON paths, similarity search, or an append-only log. Every example below was run against the shipped binary. Durable databases live in a directory you name; add `--cache` for a throwaway in-memory run. ## Write and read one key `kv put` writes a single key. The value is a positional argument; use `@path` or `-f ` to read bytes from a file instead. ```bash strata ./mydb kv put greeting "hello world" strata ./mydb kv get greeting ``` ```text created greeting applied=true hello world ``` Each write auto-commits — there is no separate transaction step. The `--json` envelope shows the commit that the write produced: ```bash strata --json ./mydb kv put counter 1 ``` ```text {"data":{"commit":{"delete_count":0,"durable":true,"put_count":1,"timestamp":4,"version":4},"effect":{"affected_count":1,"applied":true,"kind":"created","matched":false},"key":"Y291bnRlcg=="},"type":"write_result"} ``` On the JSON wire, keys and values are base64 strings (`Y291bnRlcg==` is `counter`). Note `commit.timestamp` — you pass that value back to read the database as it stood at that point. See [Commits](/docs/concepts/commits). ## Existence, counts, and listing ```bash strata ./mydb kv exists greeting strata ./mydb kv count strata ./mydb kv list --prefix c ``` ```text true 3 counter ``` `exists` returns `true`/`false`, `count` returns the number of visible keys, and `list` returns keys, optionally filtered by `--prefix`. Reading a key that was never written is not an error — `kv get missing` prints `(nil)` and exits zero. ## Scanning rows `kv scan` returns keys with their values and version facts, paged by `--limit`. When more rows remain, the last line is a base64 continuation cursor you pass back verbatim via `--cursor`. ```bash strata ./mydb kv scan --limit 2 ``` ```text {"key":"counter","timestamp":4,"value":"1","version":4} {"key":"doc","timestamp":6,"value":"final","version":6} -- more: Z3JlZXRpbmc= ``` `kv sample --count ` returns an arbitrary handful of rows without paging — useful for a quick peek at a large keyspace. ## Version history and time travel Overwriting a key retains its prior versions. `kv history` lists them newest-first with the commit timestamp that produced each: ```bash strata ./mydb kv history doc ``` ```text {"timestamp":6,"tombstone":false,"value":"final","version":6} {"timestamp":5,"tombstone":false,"value":"draft","version":5} ``` To read the value as of an earlier commit, pass that timestamp with `--as-of`. Capture the timestamp from a write receipt (the `commit.timestamp` field) and reuse it: ```bash strata ./mydb kv get doc --as-of 5 ``` ```text draft ``` Every read command (`get`, `list`, `scan`) accepts `--as-of`, so you can view a consistent historical snapshot of the whole keyspace. ## Branches KV rows are branch-scoped. Fork a branch, write on it, and the parent is untouched — no copy is made until you write. ```bash strata ./mydb branch fork default experiment strata ./mydb kv put doc branched --branch experiment strata ./mydb kv get doc --branch experiment # branched strata ./mydb kv get doc # final ``` Merging a branch back is strict: it refuses when both sides changed concurrently. See [Branches](/docs/concepts/branches) and [Branch Management](/docs/guides/branching-workflows). ## Deleting ```bash strata ./mydb kv delete greeting ``` ```text deleted greeting applied=true ``` Deleting a key that does not exist reports `not_found nope applied=false` and still exits zero — the operation simply had no effect. The delete is recorded as a tombstone, so history and `--as-of` reads before the delete still resolve. ## Error cases worth knowing Errors carry a stable `..` code and a docs ref. An empty key is rejected: ```bash strata --json ./mydb kv put "" x ``` ```text {"error":{"class":"invalid_argument","code":"invalid_argument.engine.kv_key","retry_policy":"never","retryable":false,"commit_outcome":"not_started","message":"KV key must not be empty","suggested_fix":"Correct the request input and retry the operation.","docs_url":"https://stratadb.org/e/invalid_argument.engine.kv_key","reference_id":"err_local_1f01a1d8_000001"}} ``` Recover by code, never by message text. See [/e/invalid_argument.engine.kv_key](/e/invalid_argument.engine.kv_key) and the [error handling guide](/docs/guides/error-handling). ## When to use KV vs other primitives - Use **KV** for opaque values keyed by a string, with no structure to query. - Use [JSON](/docs/data/json) when you need to read or update fields inside a document by path, or index by field. - Use [Vectors](/docs/data/vectors) for similarity search over embeddings. - Use the [Event Log](/docs/data/events) for an ordered, hash-linked, append-only history. The full verb list is in the [CLI reference](/docs/reference/cli). To batch many writes into one shared commit, use the raw `command` path or MCP tools; the CLI `kv` verbs operate on one key at a time. ## From Python The same surface, from the [Python SDK](/docs/python) — values are bytes, a miss returns `None`: ```python import stratadb db = stratadb.open("./mydb") db.kv.put("setting", "v1") db.kv.get("setting") # b"v1" db.kv.exists("setting") # True db.kv.count() # 1 db.close() ``` See [namespaces](/docs/python/namespaces) for scans, history, batches, and `as_of` reads. ## Reference Every key-value command — parameters, returns, errors, and runnable CLI/wire/Python examples — is in the generated [Key-Value command reference](/docs/reference/kv). --- # Vectors Source: https://stratadb.org/docs/data/vectors The vector store holds embeddings — fixed-length float arrays — grouped into named collections, and searches them by similarity. Use it for semantic retrieval: find the stored vectors closest to a query vector, optionally filtered by metadata. Like every [primitive](/docs/concepts/primitives), collections and vectors are branch-aware and versioned. Examples below were run against the shipped binary. Use a directory path for a durable database or `--cache` for a throwaway run. The vectors here are 4 dimensions so the output is readable; real embeddings are hundreds or thousands of dimensions. ## Create a collection A collection fixes a dimension and a distance metric up front. Every vector you upsert into it must match that dimension. The metric is one of `cosine` (default), `euclidean`, or `dot-product`. ```bash strata ./mydb vector collection create docs 4 --metric cosine strata ./mydb vector collection list ``` ```text {"count":0,"dimension":4,"metric":"cosine","name":"docs"} {"count":0,"dimension":4,"metric":"cosine","name":"docs"} ``` Both commands print the same collection record — the first line is `create` echoing the new collection, the second is `list` showing it. `vector collection stats ` reports the same facts for one collection, and `vector collection delete ` removes it. ## Upsert vectors with metadata `vector upsert ` inserts or replaces one vector. The vector is a JSON array, comma-separated floats, or `@path`. Attach a metadata JSON object with `--metadata` (or `--metadata-file`) to filter on later. ```bash strata ./mydb vector upsert docs a "[1,0,0,0]" --metadata '{"lang":"en","year":2020}' strata ./mydb vector upsert docs b "[0.9,0.1,0,0]" --metadata '{"lang":"en","year":2021}' strata ./mydb vector upsert docs c "[0,1,0,0]" --metadata '{"lang":"fr","year":2020}' strata ./mydb vector count docs ``` ```text created a applied=true created b applied=true created c applied=true 3 ``` Read one vector back with `vector get`, list keys with `vector keys`, and check existence with `vector exists`. ## Query by similarity `vector query ` returns the `-k` nearest keys with their scores. For cosine, higher is closer. ```bash strata ./mydb vector query docs "[1,0,0,0]" -k 3 ``` ```text a 1.0 b 0.9938837289810181 c 0.0 ``` The `--json` form includes each match's metadata; add `--diagnostics` to include vector index diagnostics with the results. ## Filter by metadata Restrict a query — or a bulk delete — to vectors whose metadata matches. The filter is a JSON object with a `conditions` array; each condition names a `field`, an `op` of `eq`, and a typed `value` (`{"type":"string","value":...}`, or `type` of `number`, `bool`, or `null`). Conditions are AND-composed. ```bash strata ./mydb vector query docs "[1,0,0,0]" -k 5 \ --filter '{"conditions":[{"field":"lang","op":"eq","value":{"type":"string","value":"en"}}]}' ``` ```text a 1.0 b 0.9938837289810181 ``` The French document is excluded. Use `--filter-file` to read the filter from a file. ## Metadata patch and deletes `vector update-metadata ` merges a top-level patch into a vector's metadata, leaving the embedding untouched: ```bash strata ./mydb vector update-metadata docs a '{"year":2022,"reviewed":true}' ``` ```text updated a applied=true ``` Delete one vector with `vector delete `, every vector with `vector delete-all `, or a matching subset with `vector delete-by-filter` (same filter shape as query): ```bash strata ./mydb vector delete-by-filter docs \ --filter '{"conditions":[{"field":"lang","op":"eq","value":{"type":"string","value":"fr"}}]}' strata ./mydb vector count docs ``` ```text deleted docs applied=true 2 ``` ## History, branches, time travel `vector history ` lists a vector's prior revisions newest-first. Reads accept `--as-of ` for a historical snapshot, and everything is branch-scoped — fork a branch to try a different set of embeddings without touching the parent. See [Branches](/docs/concepts/branches). ## Error cases worth knowing Upserting a vector whose length does not match the collection dimension is rejected: ```bash strata --json ./mydb vector upsert docs z "[1,2,3]" ``` ```text {"error":{"class":"invalid_argument","code":"invalid_argument.engine.vector_dimension","retry_policy":"never","retryable":false,"commit_outcome":"not_started","message":"vector dimension mismatch: expected 4, got 3","suggested_fix":"Correct the request input and retry the operation.","docs_url":"https://stratadb.org/e/invalid_argument.engine.vector_dimension","reference_id":"err_local_1bff3bcc_000001"}} ``` Querying a collection that does not exist returns [/e/not_found.engine.vector_collection](/e/not_found.engine.vector_collection), and creating a collection whose name is taken returns [/e/already_exists.engine.vector_collection](/e/already_exists.engine.vector_collection). Recover by code — see [error handling](/docs/guides/error-handling). ## When to use vectors vs other primitives - Use **vectors** for similarity search over embeddings. - Use [JSON](/docs/data/json) for structured records you query by field. - Use [KV](/docs/data/key-value) for opaque keyed values. - Use the [Event Log](/docs/data/events) for ordered, append-only history. Strata does not generate embeddings inside the vector primitive — you supply the floats. For end-to-end retrieval that embeds text for you, see [RAG with vectors](/docs/cookbook/rag-with-vectors). The full verb list is in the [CLI reference](/docs/reference/cli). ## From Python The same surface, from the [Python SDK](/docs/python): ```python import stratadb db = stratadb.open("./mydb") db.vectors.create_collection("docs", dimension=4) db.vectors.upsert("docs", "a", [1.0, 0.0, 0.0, 0.0], metadata={"tag": "x"}) db.vectors.query("docs", [1.0, 0.0, 0.0, 0.0], k=1) # [VectorMatch(key='a', score=1.0, metadata={'tag': 'x'})] db.close() ``` See [namespaces](/docs/python/namespaces) for metadata filters and patches. ## Reference Every vector command — parameters, returns, errors, and runnable CLI/wire/Python examples — is in the generated [Vector command reference](/docs/reference/vector). --- # Getting Started Source: https://stratadb.org/docs/getting-started New to StrataDB? Take these three steps in order. (Still deciding whether it fits your problem? Start with [Why Strata](/docs/why-strata) — what it is, [when to use it](/docs/why-strata/when-to-use), and [how it compares](/docs/why-strata/comparisons).) 1. **[Installation](/docs/getting-started/installation)** — install the `strata` CLI and confirm it runs. 2. **[Your first database](/docs/getting-started/first-database)** — create a durable database, work in the REPL and one-shot forms, write across the KV and JSON capabilities, fork a branch, and read an earlier version. 3. **[For AI agents](/docs/agents)** — if you are wiring StrataDB into a coding agent or an MCP client, start here for the integration recipe. ## What you are installing StrataDB is embedded: it runs inside your process against a local directory, the way SQLite or DuckDB does. There is no server to start, no port to open, and no daemon to keep alive. You install one binary, `strata`, and point it at a path — that directory is your database. That one binary carries five data capabilities over a single storage substrate — key-value, JSON documents, an event log, vectors, and a graph — plus git-style branches and per-commit time travel. The same binary is also a Model Context Protocol server, so an AI agent can drive it with no extra package. ## What each step gives you The **installation** page covers the installer script, Homebrew, and building from source, and ends with a one-line check that the CLI works. The **first database** tutorial is hands-on against the real binary: you create a database on disk, write and read data, open the interactive REPL, fork a branch to isolate a change, and read a value as it stood at an earlier commit. Every command and output on that page comes from a live run. The **for AI agents** page is the tight integration recipe — how the binary describes its own commands and errors, how to onboard a repository, and how to run the built-in MCP server. ## After the tutorial Once the moves feel familiar, read [Concepts](/docs/concepts/branches) to understand [branches](/docs/concepts/branches), [commits](/docs/concepts/commits), and [durability](/docs/concepts/durability). Then use the [Guides](/docs/data/key-value) to go deep on one capability at a time, and the [Cookbook](/docs/cookbook/agent-state-management) for end-to-end patterns. If something breaks, [Troubleshooting](/docs/troubleshooting) lists real failure modes and the error codes they carry. --- # Installation Source: https://stratadb.org/docs/getting-started/installation ## Install the CLI ### Installer script (recommended) ```bash curl -fsSL https://stratadb.org/install.sh | sh ``` The installer downloads the latest release for your platform, verifies its SHA-256 checksum against the release manifest, installs the binary to `~/.strata/bin`, and adds that directory to your shell's PATH. Two environment variables override the defaults: ```bash # Pin a specific version instead of latest curl -fsSL https://stratadb.org/install.sh | STRATA_VERSION= sh # Install somewhere else curl -fsSL https://stratadb.org/install.sh | STRATA_INSTALL_DIR=$HOME/bin sh ``` ### Homebrew ```bash brew install stratalab/tap/strata ``` ### From source ```bash git clone https://github.com/stratalab/strata-core.git cd strata-core cargo build --release -p strata-cli ``` The binary is located at `target/release/strata`. ### Running Tests (development) ```bash # All tests across the workspace cargo test --workspace # Specific crate cargo test -p strata-executor # With output cargo test --workspace -- --nocapture ``` ## Verify Installation Run a quick command to confirm the CLI is working: ```bash strata --cache ping ``` ```text pong 1.0.0 ``` If something looks off, run the built-in diagnostic: ```bash strata doctor ``` It reports the binary version, platform, Strata home, and PATH visibility — and, when pointed at a database directory, a health summary. Every finding carries an error code and a fix hint, and the command exits non-zero when anything is wrong. [Troubleshooting](/docs/troubleshooting) starts from its output. You can also try a quick interactive session: ``` $ strata --cache strata:default/default> kv put hello world created hello applied=true strata:default/default> kv get hello world strata:default/default> quit ``` If you see the output above, you are ready to go. Continue to [Your First Database](first-database) for a complete tutorial. ## Uninstall If you installed with the installer script, remove the binary directory and the PATH line the installer added: ```bash rm -rf ~/.strata/bin ``` (Use your `STRATA_INSTALL_DIR` if you overrode the default.) Then delete the `# Strata` block from your shell config — `~/.zshrc`, `~/.bashrc`, `~/.config/fish/config.fish`, or `~/.profile`. If you installed with Homebrew: ```bash brew uninstall strata ``` Uninstalling removes only the binary. Your databases stay wherever you created them, and the global config remains at `~/.config/strata/config.toml` — delete those yourself if you want a clean slate. ## Next - [Your First Database](first-database) — hands-on tutorial - [Concepts](/docs/concepts) — understand the mental model --- # Your First Database Source: https://stratadb.org/docs/getting-started/first-database This tutorial creates a real on-disk database and walks through the everyday moves: writing and reading, working in the REPL, forking a branch, and reading an earlier version. Every command and output below comes from a live run. ## Prerequisites - The [CLI installed](/docs/getting-started/installation). ## Create a database A database is a directory. Name a path and StrataDB creates it on first write — no separate "create" step: ```bash strata ./mydb kv put greeting hello ``` ```text created greeting applied=true ``` Read it back: ```bash strata ./mydb kv get greeting ``` ```text hello ``` That directory now holds a write-ahead log and a manifest. It is durable: the data survives the process exiting. For a throwaway database that never touches disk, swap the path for `--cache` (for example `strata --cache kv put a b`). ## Two ways to run Everything above used the **one-shot** form: `strata `, one command per invocation, good for scripts. For an interactive session, pass just the path to open a **REPL**: ```text $ strata ./mydb strata:default/default> kv put agent:model gpt-4 created agent:model applied=true strata:default/default> kv get agent:model gpt-4 strata:default/default> kv list agent:model greeting strata:default/default> quit ``` The prompt shows your current branch and space (`default/default`). Inside the REPL, type commands without the leading `strata`. A few meta-commands help you move around: `use ` (optionally `use /`) switches context, `help` prints the command list, and `quit`, `exit`, or Ctrl-D leaves. Quote rules differ from the shell, so for JSON documents the one-shot form below is easier to get right. ## Write JSON documents The JSON capability stores documents you address by key and mutate at JSON paths. `$` is the document root: ```bash strata ./mydb json set profile '$' '{"name":"Ada","score":95}' ``` ```text created profile applied=true ``` Read the whole document, then a single path: ```bash strata ./mydb json get profile '$' ``` ```text {"name":"Ada","score":95} ``` ```bash strata ./mydb json get profile '$.score' ``` ```text 95 ``` Updating one path leaves the rest of the document untouched: ```bash strata ./mydb json set profile '$.score' 99 ``` ```text updated profile applied=true ``` KV and JSON both live in the same database on the same branch — one store, many shapes of data. ## Fork a branch A branch is an isolated line of data. Fork the current one and writes on the fork stay off the parent. First put a value on `default`: ```bash strata ./mydb kv put city tokyo strata ./mydb branch fork default experiment ``` ```text created city applied=true { "branch_id": "1a29fdd4-745b-5b66-ad18-75b3cf51cef6", "created_at": 6, "deleted_at": null, "generation": 1, "name": "experiment", "parent": { "branch_id": "00000000-0000-0000-0000-000000000000", "fork_timestamp": null, "fork_version": 6, "generation": 1, "name": "default" }, "state_revision": 0, "status": "active" } ``` The fork starts as a copy of its parent, so `city` already reads `tokyo` on `experiment`. Overwrite it there and check both branches: ```bash strata ./mydb kv put city kyoto --branch experiment strata ./mydb kv get city --branch experiment strata ./mydb kv get city ``` ```text updated city applied=true kyoto tokyo ``` `experiment` sees `kyoto`; `default` still reads `tokyo`. The write on the fork was invisible to its parent. (The `created_at` and `fork_version` numbers above track your database's own commit history, so yours will differ.) ## Read an earlier version Every write returns a commit. Ask for the commit's timestamp with `--json`: ```bash strata --json ./mydb kv put note first ``` ```text {"data":{"commit":{"delete_count":0,"durable":true,"put_count":1,"timestamp":11,"version":11},"effect":{"affected_count":1,"applied":true,"kind":"created","matched":false},"key":"bm90ZQ=="},"type":"write_result"} ``` Note `data.commit.timestamp` (here `11`). Overwrite the key, then read it back both live and as of that earlier commit with `--as-of`: ```bash strata ./mydb kv put note second strata ./mydb kv get note strata ./mydb kv get note --as-of 11 ``` ```text updated note applied=true second first ``` The live read returns `second`; the `--as-of` read returns the value as it stood at that commit. Time travel works the same way for JSON, vectors, events, and the graph. ## Look at the whole database `describe` prints a compact summary — branches, capabilities, and per-capability counts (the `version` field is omitted here): ```bash strata ./mydb describe ``` ```text { "branch": "default", "branches": [ "default", "experiment" ], "capabilities": { "arrow": true, "event": true, "graph_core": true, "inference": true, "json": true, "kv": true, "vector": true, "vector_index": true }, "config": { "created": false, "default_branch": "default", "durable": true, "target": "durable_local" }, "default_branch": "default", "primitives": { "event_count": 0, "graphs": [], "json_count": 1, "kv_count": 4, "vector_collections": [] }, "spaces": [ "default" ], "target": "durable_local" } ``` `strata ./mydb info` gives the shorter version — branch count, durability, and target. ## Next - [Concepts: branches](/docs/concepts/branches) and [commits](/docs/concepts/commits) — the model behind fork and `--as-of`. - [Guides](/docs/data/key-value) — each capability in depth: [KV](/docs/data/key-value), [JSON](/docs/data/json), [event log](/docs/data/events), [vectors](/docs/data/vectors), [graph](/docs/data/graph). - [For AI agents](/docs/agents) — wire this into an agent. --- # Quickstart: AI agents Source: https://stratadb.org/docs/getting-started/quickstart-agents StrataDB is built to be learned by agents, not just humans: the wheel and the binary carry their own documentation, errors teach the fix, and one command installs a Claude Code skill into your repo. This page is the shortest path from "use StrataDB for this" to an agent that writes correct code. ## One step: install the skill In any repo an agent works on: ```bash strata agents skill --write ``` ```text { "next": null, "path": ".claude/skills/strata/SKILL.md", "state": "created" } ``` That file is the condensed playbook — opening a database, choosing a primitive, branch isolation, `as_of` reads, the error contract, and inference — version-stamped from the installed binary. Claude Code loads it automatically whenever a session touches Strata. Re-running is idempotent; it refuses to overwrite a file you've edited unless you pass `--force`. ### Cursor and Codex too One flag installs for every major coding agent, each via its native surface: ```bash strata agents skill --write --for all ``` ```text { "written": [ {"agent": "claude", "path": ".claude/skills/strata/SKILL.md", "state": "created", "next": null}, {"agent": "cursor", "path": ".cursor/rules/strata.mdc", "state": "created", "next": null}, {"agent": "codex", "path": "AGENTS.md", "state": "appended", "next": null} ] } ``` Cursor gets an MDC rule with the same trigger description (`alwaysApply: false`, attached when a session touches Strata). Codex reads the repo's `AGENTS.md`, so the playbook lands there between `` markers — Strata owns the marked region, never the rest of your file, and re-runs update it in place. `--for claude`, `--for cursor`, and `--for codex` target one agent at a time. The same text ships inside the Python wheel, so an agent (or a setup script) can install it without the CLI: ```python from pathlib import Path import stratadb path = Path(".claude/skills/strata/SKILL.md") path.parent.mkdir(parents=True, exist_ok=True) path.write_text(stratadb.agents_skill()) ``` ## The self-describing surface Everything an agent needs is one hop from wherever it lands: ```python import stratadb stratadb.agents_guide() # the complete Python guide, offline, in the wheel stratadb.command_index() # the machine-readable command catalog (the IDL) stratadb.mcp_config("./mydb") # {'command': 'strata', 'args': ['./mydb', 'mcp', 'serve']} ``` ```bash strata agents guide # the CLI guide, version-matched strata agents commands --json # command catalog strata agents errors --json # every public error code with hints strata agents init --apply # plants a pointer block in AGENTS.md/CLAUDE.md ``` ## Two rules that prevent most agent mistakes 1. **Always target the database explicitly.** Pass a path (`stratadb.open("./mydb")`, `strata ./mydb …`) or set `STRATA_DB`. Strata never opens the current directory implicitly — the refusal is [`invalid_argument.cli.no_database`](/e/invalid_argument.cli.no_database). 2. **Recover by error code, never by message text.** Failures carry a stable `..` code, a hint, and a per-code URL (`https://stratadb.org/e/`). A missing key/document/path is `None`, not an error. ## MCP, for chat-based agents The binary is also an MCP server — the path for Claude Desktop, claude.ai, and any MCP client: ```bash strata ./mydb mcp serve ``` Client config: `{"command": "strata", "args": ["./mydb", "mcp", "serve"]}`. Roughly 20 curated tools plus `strata_guide` (the usage guide as a tool) and `strata_command` (any cataloged command as raw wire JSON). Same value shapes, same error codes as the CLI and SDK. ## For the agent reading this page Fetch [/llms.txt](/llms.txt) for the curated index, or append `.md` to any docs URL for CommonMark. The full corpus is at [/llms-full.txt](/llms-full.txt). ## Next - [For AI agents](/docs/agents) — the full machine surface, in depth. - [MCP server](/docs/agents/mcp-server) — the handshake and the tool table. - [Python SDK](/docs/python) — the surface the skill teaches. - [Cookbook](/docs/cookbook) — agent-shaped end-to-end recipes. --- # Branching workflows Source: https://stratadb.org/docs/guides/branching-workflows A branch is an isolated line of history. Every primitive is branch-aware, forks are cheap, and writes on one branch are invisible to every other branch until you fork again. For the mental model, see [Concepts: Branches](/docs/concepts/branches). This guide covers the five branch verbs on the CLI: `list`, `get`, `create`, `fork`, and `delete`. Examples use a durable database at `./mydb`. Every branch command also accepts `--branch`, `--space`, and `--json`. ## List branches `branch list` prints one branch record per line. A fresh database has only `default`: ```bash strata ./mydb branch list ``` ```text {"branch_id":"00000000-0000-0000-0000-000000000000","created_at":null,"deleted_at":null,"generation":1,"name":"default","parent":null,"state_revision":0,"status":"active"} ``` ## Read one branch `branch get ` returns the full record. The human form is pretty-printed; add `--json` for a compact envelope: ```bash strata ./mydb branch get default ``` ```text { "branch_id": "00000000-0000-0000-0000-000000000000", "created_at": null, "deleted_at": null, "generation": 1, "name": "default", "parent": null, "state_revision": 0, "status": "active" } ``` ## Create an empty branch `branch create ` makes a new root branch with no data and no parent. It does not switch you onto it — pass `--branch` on later commands to target it: ```bash strata ./mydb branch create scratch strata ./mydb kv count --branch scratch ``` ```text 0 ``` ## Fork a branch `branch fork ` copies a branch's visible history into a new branch. There are three variants, chosen by which flags you pass. To show them, first make three writes to `config` and note the version and timestamp on each receipt (`strata --json ./mydb kv put config v1` prints `"commit":{...,"timestamp":3,"version":3}`, and so on for `v2` at 4 and `v3` at 5). **From the tip** (no flags) forks the source's latest state: ```bash strata ./mydb branch fork default review strata ./mydb kv get config --branch review ``` ```text v3 ``` **At a version** (`--version`) forks from a retained commit version: ```bash strata ./mydb branch fork default rollback --version 3 strata ./mydb kv get config --branch rollback ``` ```text v1 ``` **At a timestamp** (`--timestamp`) forks from a retained commit timestamp: ```bash strata ./mydb branch fork default snapshot --timestamp 4 strata ./mydb kv get config --branch snapshot ``` ```text v2 ``` The fork record records where it split from under `parent`, for example `"parent":{"name":"default","fork_version":5,"fork_timestamp":null,...}`. ## Isolation Writes are scoped to their branch. Writing `config` on `review` leaves `default` untouched: ```bash strata ./mydb kv put config review-only --branch review strata ./mydb kv get config --branch review # review-only strata ./mydb kv get config # v3 ``` ## Delete a branch `branch delete ` removes a branch and its history: ```bash strata ./mydb branch delete scratch ``` ```text deleted applied=true ``` The default branch cannot be deleted: ```text invalid_argument.engine.branch_delete: default branch cannot be deleted (err_local_0b3b7d37_000001) hint: Correct the request input and retry the operation. ref: https://stratadb.org/e/invalid_argument.engine.branch_delete ``` ## Refusals Branch operations fail with stable codes, not prose. Recover by code — see [Error Handling](/docs/guides/error-handling). Common cases: - Reserved names (the `_system_` prefix is engine-owned) → [`invalid_argument.engine.branch_name_reserved`](/e/invalid_argument.engine.branch_name_reserved). - Re-creating an existing branch → [`already_exists.engine.branch`](/e/already_exists.engine.branch). - Reading or forking a missing branch → [`not_found.engine.branch`](/e/not_found.engine.branch). - Forking at a version or timestamp outside retained history → [`history_unavailable.engine.persistence_history`](/e/history_unavailable.engine.persistence_history). ## Merging This release exposes no `branch merge` command. Combine work by forking and re-applying writes on the target branch. When merge does run inside the engine, it strictly refuses branches whose history has diverged rather than guessing a resolution, so there is no silent last-writer-wins. Fork-based workflows — review a change on a fork, then replay it onto `default` — are the supported path today. ## Next - [Spaces](/docs/guides/spaces) — organize data within a branch. - [KV Store](/docs/data/key-value) — versioned reads and `--as-of` time travel. - [Concepts: Branches](/docs/concepts/branches) — the model behind these verbs. --- # Cloning Datasets Source: https://stratadb.org/docs/guides/cloning-datasets `strata clone` pulls a prepared dataset from a hub into a new local database. A cloned database is an ordinary database — it opens, branches, and queries like any other, and it remembers where it came from. ## Cloning Give `clone` a dataset slug and, optionally, a destination directory: ```bash strata clone wikipedia-embeddings ./wiki ``` The destination is optional; without it the clone lands in `./.strata`. `--branch ` fetches a specific branch instead of the dataset's default branch. The clone resolves a hub, requests `/v1/datasets/`, and writes the database locally. ## Choosing a hub The hub URL is resolved from the first source that supplies one, in this order: 1. `--hub ` on the command 2. the `STRATA_HUB_URL` environment variable 3. `hub.url` in the project's `.strata/config.toml` 4. `hub.url` in the global config 5. the built-in default, `https://hub.stratahub.io/` `config show` prints the resolved hub and names the layer it came from. With nothing configured, that is the built-in default: ```bash strata --cache config show ``` ```text { "hub.url": "https://hub.stratahub.io/", "source": "built-in default" } ``` Set `STRATA_HUB_URL` and it wins over both config files: ```bash STRATA_HUB_URL=https://env.example.com strata --cache config show ``` ```text { "hub.url": "https://env.example.com/", "source": "STRATA_HUB_URL" } ``` A project-local `.strata/config.toml` with a `[hub]` section applies when you run from that directory and no environment variable or flag overrides it, with `source` pointing at the file. `--hub` on a `clone` command overrides everything for that one invocation. ## Persisting a hub `config set hub.url ` writes the value into the global config so every command picks it up: ```bash strata --cache config set hub.url https://hub.example.com strata --cache config get-key hub.url ``` ```text { "key": "hub.url", "value": "https://hub.example.com/" } ``` `config get-key hub.url` reads the user-config value (null when unset), `config unset hub.url` removes it, and `config path` prints where the global config lives: ```bash strata --cache config path ``` ```text { "path": "/home/you/.config/strata/config.toml" } ``` ## Error paths An invalid or empty `--hub` value is rejected before any network call: ```bash strata clone demo ./demo --hub not-a-url ``` ```text failed_precondition.executor.hub_url: --hub: not a valid URL: relative URL without a base hint: Provide a valid URL via --hub, STRATA_HUB_URL, or hub.url in a project or global strata config. ref: https://stratadb.org/e/failed_precondition.executor.hub_url ``` A reachable-URL but unreachable host surfaces a transport error, marked retryable: ```bash strata clone demo ./demo --hub http://127.0.0.1:1/ ``` ```text unavailable.executor.hub_transport: hub transport failed: network error (retryable=true): error sending request for url (http://127.0.0.1:1/v1/datasets/demo) hint: Check connectivity and the hub URL, then retry. ref: https://stratadb.org/e/unavailable.executor.hub_transport ``` ## Remote origin `strata remote` reports where a database was cloned from. A database you created yourself has no origin: ```bash strata ./fresh remote ``` ```text { "origin": null } ``` On a cloned database, `remote` reports the origin instead — the hub and dataset it was pulled from — so you can trace a local copy back to its source. ## Related - [Configuration Reference](/docs/reference/configuration-reference) — every config key and resolution layer - [Branches](/docs/concepts/branches) — cloning a specific branch, and branching a clone locally - [Arrow](/docs/guides/import-export) — moving individual primitives as files instead of whole datasets - [Error Handling](/docs/guides/error-handling) — reading structured error codes --- # Configuration Source: https://stratadb.org/docs/guides/configuration The `strata config` command reads and writes configuration. It covers two distinct things: the read-only facts about an open database, and the writable user setting that points Strata at a hub. This guide walks through all six verbs — `get`, `get-key`, `set`, `unset`, `path`, and `show` — and explains how the hub URL is resolved. For every configurable key, see the [Configuration Reference](/docs/reference/configuration-reference). ## Read a database's config `config get` prints the sanitized configuration of an open database. It needs a database target: ```bash strata ./mydb config get ``` ```text { "created": false, "default_branch": "default", "durable": true, "target": "durable_local" } ``` These are facts about how the database was opened — its default branch, whether it is durable, and its storage target. They are read-only; you change them by how you open the database, not by writing config. ## The global hub setting The remaining verbs manage the user config, whose one key in this release is `hub.url` — the hub that [`clone`](/docs/guides/cloning-datasets) fetches from. It lives in a global file. `config path` prints where: ```bash strata config path ``` The path is `~/.config/strata/config.toml`. Read the current key with `config get-key`, which returns `null` when nothing is set: ```bash strata config get-key hub.url ``` ```text { "key": "hub.url", "value": null } ``` Set it with `config set`. The value is normalized (a trailing slash is added) and written to the global file: ```bash strata config set hub.url https://hub.example.com ``` ```text { "key": "hub.url", "path": "/home/you/.config/strata/config.toml", "value": "https://hub.example.com/" } ``` The file now contains a `[hub]` table: ```toml [hub] url = "https://hub.example.com/" ``` Remove the key with `config unset hub.url`, which returns `"unset": true`. Once unset, `config show` falls back to the built-in default again. ## Which hub URL wins `config show` prints the resolved hub URL and the layer that supplied it. With nothing configured, that is the built-in default: ```bash strata config show ``` ```text { "hub.url": "https://hub.stratahub.io/", "source": "built-in default" } ``` Set the global key and the source becomes the config file's path. Export `STRATA_HUB_URL` and it wins over the file: ```bash STRATA_HUB_URL=https://env.example.com strata config show ``` ```text { "hub.url": "https://env.example.com/", "source": "STRATA_HUB_URL" } ``` Run from a directory that has a `.strata/config.toml` with its own `[hub]` table, and that project file wins over the global file — but still loses to the environment variable. The full precedence, highest first: | Layer | Source | Scope | |-------|--------|-------| | `--hub ` flag | this invocation | one hub command, e.g. `clone` | | `STRATA_HUB_URL` | environment | current shell session | | `.strata/config.toml` | project file | the working directory tree | | `~/.config/strata/config.toml` | global file | this user | | built-in default | Strata | fallback | The `--hub` flag sits on commands that reach a hub, such as `clone`, and its help states it overrides both the environment variable and the config files for that single invocation. ## Next - [Cloning Datasets](/docs/guides/cloning-datasets) — put the hub URL to work. - [Observability](/docs/guides/observability) — inspect a database's health and facts. - [Configuration Reference](/docs/reference/configuration-reference) — the full key list. --- # Error Handling Source: https://stratadb.org/docs/guides/error-handling Every failure carries a stable code, a one-line hint, and a link to a per-code doc page. Recover by code and class, never by matching the message text — the message can change, the code will not. The full registry ships in the binary (`strata agents errors --json`, 204 codes today) and online in the [Error Reference](/docs/reference/error-reference). ## Anatomy of a code Codes are `..`. The class is the broad kind of failure, the area is the subsystem, and the detail pins the exact case: ```text not_found.engine.branch failed_precondition.engine.space_not_empty invalid_argument.engine.branch_name_reserved ``` Branch on the class for control flow; log the full code for diagnosis. ## The human-readable shape A failed command prints the code, message, a stable reference id, a hint, and a doc ref, then exits non-zero: ```text not_found.engine.branch: branch `scratch` does not exist (err_local_073b160f_000001) hint: Check that the requested branch, space, collection, graph, document, key, or model exists. ref: https://stratadb.org/e/not_found.engine.branch ``` The `ref` resolves to [`/e/`](/docs/reference/error-reference) — for the example above, [`/e/not_found.engine.branch`](/e/not_found.engine.branch). The `err_local_...` reference id is unique per occurrence; quote it when reporting a problem. ## The JSON shape Add `--json` and an engine error is emitted as one envelope on stderr: ```text {"error":{"class":"not_found","code":"not_found.engine.branch","retry_policy":"never","retryable":false,"commit_outcome":"not_applicable","message":"branch `nope` does not exist","suggested_fix":"Check that the requested branch, space, collection, graph, document, key, or model exists.","docs_url":"https://stratadb.org/e/not_found.engine.branch","reference_id":"err_local_0ac6b2ff_000001"}} ``` The machine fields are `class`, `code`, `retry_policy`, `retryable`, `commit_outcome`, `message`, `suggested_fix`, `docs_url`, and `reference_id`. ## Exit codes - `0` — success. Note that a miss is not always a failure: `kv get` on an absent key prints `(nil)` and exits `0`. - `1` — an engine error, carrying a code as shown above. - `2` — a usage error caught before the database opens, such as a missing argument or `invalid_argument.cli.no_database` when no target is given. These print a plain `error:` line even under `--json`. ## Error classes The fifteen classes and what each tells you: | Class | Meaning | |-------|---------| | `invalid_argument` | Input was malformed; correct it and retry. | | `not_found` | A named resource does not exist. | | `already_exists` | The resource is already present. | | `failed_precondition` | A required condition was not met (for example, a space still holds data). | | `conflict` | The request clashes with current state; reload and retry against the latest version. | | `unavailable` | A required backend or capability is temporarily unavailable. | | `unsupported` | The active backend does not support the requested capability. | | `resource_exhausted` | A budget or limit was reached. | | `access_denied` | Credentials or permissions were rejected. | | `history_unavailable` | The requested version or timestamp is outside retained history. | | `corruption` | Stored data failed validation — stop writing and inspect recovery. | | `serialization` | Serialized data (such as a provider response) was malformed. | | `ambiguous_commit` | The commit outcome could not be proven. | | `internal` | An internal engine fault; capture the reference id and report it. | | `io` | An I/O failure in the local runtime. | ## Retry policy and commit outcome Each error states whether retrying helps, via `retry_policy`: - `never` — the same request will fail again; fix input or state first. - `same_request` — the failure was transient; the identical request is safe to resend. - `after_state_change` — retry only once the underlying state changes, such as a capability becoming available. - `unknown` — the outcome is uncertain; inspect before deciding. For writes, `commit_outcome` tells you what happened to your data: `not_started` (nothing was written), `definitely_not_committed` (the write was attempted and rolled back), `maybe_committed` (unproven — verify state before assuming), or `not_applicable` for reads. When you see `maybe_committed` (paired with `ambiguous_commit`), re-open the database and check before retrying. ## Next - [Error Reference](/docs/reference/error-reference) — the full code registry. - [Observability](/docs/guides/observability) — check health before and after failures. - [Branch Management](/docs/guides/branching-workflows) — the refusals shown here in context. --- # Deploying Source: https://stratadb.org/docs/guides/deploying Because StrataDB is [embedded](/docs/concepts/embedded-architecture), deploying it is unlike deploying a database server — there is no service to run, scale, or secure a network boundary around. A deployment is two pieces: the `strata` binary (or the [Python SDK](/docs/python), which links the engine directly) and a database directory. This guide is the concrete recipes; every command below was run against the shipped binary. One durable database is opened by one process at a time (an exclusive lock enforces it), so the deployment unit is "one process owns one database directory." For throwaway or read-mostly workloads, [cache mode](/docs/concepts/durability) (`--cache`) needs no directory at all. ## Seed a database in your release build A database is created on first write, so "prepare a dataset" is just a script that runs `strata` against the directory your build ships: ```bash strata ./dist/appdb kv put config:mode production strata ./dist/appdb json set catalog:1 '$' '{"name":"Starter dataset","rows":120}' strata ./dist/appdb describe ``` ```text created config:mode applied=true created catalog:1 applied=true { "branch": "default", ... "primitives": { "event_count": 0, "graphs": [], "json_count": 1, "kv_count": 1, "vector_collections": [] }, "target": "durable_local", "version": "1.0.0" } ``` `describe` at the end of the seed step doubles as a build-time sanity check — assert on `kv_count`/`json_count` in CI and the artifact can't ship empty. ## Copy the directory as a unit A database directory moves like any other build artifact — copy the **whole directory**, never individual files inside it: ```bash cp -a ./dist/appdb ./appdb-copy strata ./appdb-copy kv get config:mode ``` ```text production ``` The copy is a fully independent database. Ship it in a tarball, bake it into an image, or sync it to a target host; the app opens it in place. ## Ship it in a container The same two pieces — binary plus directory — in a Dockerfile. This image installs the binary with the official install script, copies the seeded database from the build context, and starts the built-in [MCP server](/docs/agents/mcp-server) as its entrypoint: ```dockerfile FROM debian:bookworm-slim # The strata binary — installed from the official script at build time. RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \ && curl -fsSL https://stratadb.org/install.sh | sh \ && apt-get purge -y curl && rm -rf /var/lib/apt/lists/* ENV PATH="/root/.strata/bin:${PATH}" # The database directory — seeded during the release build, copied as a unit. COPY dist/appdb /data/appdb CMD ["strata", "/data/appdb", "mcp", "serve"] ``` ```bash docker build -t strata-app . docker run --rm strata-app strata /data/appdb kv get config:mode ``` ```text production ``` Pin a release with `STRATA_VERSION=` before the install line if you want builds reproducible against a specific binary version. ## Clone at first run For curated datasets, keep the data out of the artifact entirely and pull it from a hub on startup — the result is an ordinary local database that [remembers its origin](/docs/concepts/hub-and-clone): ```bash [ -d ./appdb ] || strata clone starter-dataset ./appdb ``` The `[ -d ... ]` guard makes startup idempotent: an existing directory is opened as-is, a missing one is cloned. See [Cloning datasets](/docs/guides/cloning-datasets) for hub resolution and the failure modes (bad URL, unreachable host) with their error codes. ## Expose it to an agent To hand a deployed database to an AI agent, run the MCP server as the app's subprocess — it speaks stdio, so there is still no network service to operate: ```bash strata ./dist/appdb mcp serve ``` ```text {"id":1,"jsonrpc":"2.0","result":{"capabilities":{"tools":{"listChanged":false}},"instructions":"Strata is an embedded multi-model database (KV, JSON, vectors, events, graphs) with branches and time travel. ... ``` (The line above is the server's response to an `initialize` request on stdin — the full handshake is on the [MCP server](/docs/agents/mcp-server) page.) ## In the browser StrataDB compiles to **WebAssembly** and runs entirely in the browser in [cache mode](/docs/concepts/durability) — the same engine and the same commands, with nothing written to a server. The [playground](/playground) runs a full database this way, with no installation. Browser deployments are cache-mode: state lives for the life of the page, so persist anything you need to keep through your own application layer. ## Edge and constrained environments The embedded model — one binary, one directory, no server — is a natural fit for local-first apps, CLIs, notebooks, and constrained devices. Tuning StrataDB for very small footprints (single-board computers and smaller) is an active direction rather than a turnkey recipe today; if that is your target, the [embedded architecture](/docs/concepts/embedded-architecture) is the place to start and the shape the roadmap is building toward. ## Related - [Embedded architecture](/docs/concepts/embedded-architecture) — why deployment is this simple. - [Cloning datasets](/docs/guides/cloning-datasets) — hub resolution and clone failure modes. - [Configuration](/docs/guides/configuration) — tuning the database the app opens. - [For AI agents](/docs/agents) — the MCP server and self-describing surface. --- # Import & export Source: https://stratadb.org/docs/guides/import-export The `arrow` commands move data between a database and columnar files. Export snapshots a capability to Parquet, CSV, or JSON lines; import loads a file back into a primitive. Use them for backups, bulk loading, and handing data to analytics tools that read Arrow-compatible formats. ## Exporting `arrow export` takes a `--primitive`, a `--format`, and an output path: ```bash strata ./users arrow export --primitive kv --format csv ./users.csv ``` ```text { "format": "csv", "paths": [ "/path/to/users.csv" ], "primitive": "kv", "row_count": 3, "size_bytes": 135 } ``` `--primitive` accepts `kv`, `json`, `event`, `vector`, and `graph`; `--format` accepts `parquet`, `csv`, and `jsonl`. The file carries the row values plus their commit coordinates. The CSV above looks like this: ```text key,key_encoding,value,value_encoding,version,timestamp user:1,utf8,alice,utf8,3,3 user:2,utf8,bob,utf8,4,4 user:3,utf8,carol,utf8,5,5 ``` Narrow an export with the optional flags: `--prefix` restricts by key, document, vector, or node prefix; `--limit` caps rows; `--collection ` selects the vector collection; `--graph ` selects the graph; and `--event-type ` filters an event export. ### Graph exports A graph has two row shapes, so a graph export treats the path as a stem and writes a nodes file and an edges file: ```bash strata ./social arrow export --primitive graph --graph social --format csv ./social ``` ```text { "format": "csv", "paths": [ "/path/to/social_nodes.csv", "/path/to/social_edges.csv" ], "primitive": "graph", "row_count": 10, "size_bytes": 526 } ``` ## Importing `arrow import` takes a `--target` primitive and an input file: ```bash strata ./restored arrow import --target kv ./users.csv ``` ```text { "batches_processed": 1, "file_path": "/path/to/users.csv", "rows_imported": 3, "rows_skipped": 0, "target": "kv" } ``` `--target` accepts `kv`, `json`, and `vector`. The format is inferred from the file, or state it explicitly with `--format `. The round trip is faithful — the keys and values written above read straight back: ```bash strata ./restored kv get user:2 ``` ```text bob ``` ### Column mapping By default the importer expects the same column layout that export produces. When you load a file from elsewhere, point it at the right columns: - `--key-column ` — the column to use as the key. - `--value-column ` — the column holding the value, document, or embedding. - `--collection ` — the destination collection for a vector import. For example, importing exported JSON-lines documents by naming the key and document columns explicitly: ```bash strata ./docs arrow import --target json --key-column key --value-column document ./docs.jsonl ``` ```text { "batches_processed": 1, "file_path": "/path/to/docs.jsonl", "rows_imported": 2, "rows_skipped": 0, "target": "json" } ``` `rows_skipped` counts rows that could not be mapped, so a nonzero value is worth inspecting. ## Related - [KV Store](/docs/data/key-value), [JSON Store](/docs/data/json), and [Vector Store](/docs/data/vectors) — the import targets - [Graph](/docs/data/graph) — the node and edge model behind a graph export - [Cloning Datasets](/docs/guides/cloning-datasets) — pulling a whole prepared database instead of a file - [Command Reference](/docs/reference/command-reference) — every verb and flag --- # Guides Source: https://stratadb.org/docs/guides These guides are the **cross-cutting** how-to — the surfaces that apply across every capability rather than to one data shape. Each is a hands-on walkthrough you can follow against a running database; every command and output shown was produced by the shipped `strata` binary. Looking for a specific data primitive? Those live in [Working with Data](/docs/data/key-value). Running models is [Inference](/docs/inference); driving Strata from an agent is [For AI agents](/docs/agents). If you are brand new, start with [Your first database](/docs/getting-started/first-database). ## History and isolation - [Branching workflows](/docs/guides/branching-workflows) — list, create empty branches, fork from the tip or a past point, and delete. - [Time travel](/docs/guides/time-travel) — read the past with `--as-of`, list history, and reproduce state at a point in time. - [Spaces](/docs/guides/spaces) — organize data into named product spaces within a branch. ## Operating a database - [Configuration](/docs/guides/configuration) — the `strata config` verbs and hub URL resolution. - [Error handling](/docs/guides/error-handling) — the coded error model, retry policy, and JSON error shape. - [Observability](/docs/guides/observability) — `ping`, `info`, `health`, `metrics`, `describe`, and `doctor`. ## Moving data in and out - [Import & export](/docs/guides/import-export) — move primitives to and from Parquet, CSV, and JSON lines. - [Cloning datasets](/docs/guides/cloning-datasets) — clone a prepared dataset from a hub into a local database. - [Migrating](/docs/guides/migrating) — bring data over from SQLite, DuckDB, or Redis. ## Shipping it - [Deploying](/docs/guides/deploying) — embed in an app, run in the browser, and target the edge. ## Reference When you want the exhaustive surface rather than a walkthrough, see the [CLI reference](/docs/reference/cli), the generated [command reference](/docs/reference/kv), and the [error reference](/docs/reference/error-reference). --- # Observability Source: https://stratadb.org/docs/guides/observability Six read-only commands report on a database and the installation: `ping`, `info`, `health`, `metrics`, `describe`, and `doctor`. Each prints human-readable output by default and a compact envelope with `--json`, so the same command serves both a quick eyeball and a script. None of them writes anything. Examples use a durable database at `./mydb`. ## ping — liveness `ping` confirms the binary responds and reports its version: ```bash strata ./mydb ping ``` ```text pong 1.0.0 ``` ```bash strata --json ./mydb ping ``` ```text {"data":{"version":"1.0.0"},"type":"pong"} ``` ## info — top-line facts `info` prints the essential facts about an open database — branch and space counts, the default branch, whether it is durable and open, and its storage target: ```bash strata ./mydb info ``` ```text { "branch_count": 1, "created": false, "default_branch": "default", "durable": true, "open": true, "space_count": 1, "target": "durable_local", "version": "1.0.0" } ``` ## health — subsystem checks `health` reports the status of each control-plane subsystem and an overall `status`. Everything healthy looks like this: ```bash strata ./mydb health ``` ```text { "branch_catalog": "healthy", "branch_count": 1, "default_branch": "default", "identity": "healthy", "registry": "healthy", "space_catalog": "healthy", "status": "healthy" } ``` Watch the top-level `status`: it is the single field to alert on. ## metrics — operational facts `metrics` reports operational state — control status, durability, open state, target, and the branch and space counts: ```bash strata ./mydb metrics ``` ```text { "branch_count": 1, "control_status": "healthy", "durable": true, "open": true, "space_count": 1, "target": "durable_local" } ``` ## describe — full snapshot `describe` is the widest view: which capabilities are present, the current and available branches and spaces, and per-primitive counts. It is the fastest way to see what a database actually contains: ```bash strata ./mydb describe ``` ```text { "branch": "default", "branches": [ "default" ], "capabilities": { "arrow": true, "event": true, "graph_core": true, "inference": true, "json": true, "kv": true, "vector": true, "vector_index": true }, "config": { "created": false, "default_branch": "default", "durable": true, "target": "durable_local" }, "default_branch": "default", "primitives": { "event_count": 0, "graphs": [], "json_count": 0, "kv_count": 2, "vector_collections": [] }, "spaces": [ "default" ], "target": "durable_local", "version": "1.0.0" } ``` ## doctor — installation and database check `doctor` checks the installation: the binary version, the Strata home directory, whether it is on your `PATH`, the platform, and any `issues`. With no target it checks the install alone and exits zero when clean: ```bash strata doctor ``` ```text { "binary": "1.0.0", "database": null, "home": "~/.strata", "issues": [], "path_ok": true, "platform": "linux-x86_64" } ``` Pass a database as the global target — before the `doctor` verb — to also open it and report its facts under `database`: ```bash strata ./mydb doctor ``` The `database` object then carries `exists`, `open_ok`, `path`, and the same `info` block shown above. `doctor` exits non-zero when anything in `issues` needs attention, which makes it a natural preflight check in scripts and CI. ## Next - [Error Handling](/docs/guides/error-handling) — decode failures when a check goes red. - [Database Configuration](/docs/guides/configuration) — read a database's config. - [Agents and MCP](/docs/agents) — the self-describing surface behind these facts. --- # Spaces Source: https://stratadb.org/docs/guides/spaces A product space is a named partition of data inside a branch. Spaces and branches are Strata's two organizing dimensions, not data types of their own: your data always lives in one of the five capabilities — KV, JSON, events, vectors, and graphs — while branches isolate history across forks and spaces scope which slice of that data you see within a branch. Every branch has a `default` space, and you can add more to keep unrelated data apart — one space per tenant, per agent session, or per dataset. This guide covers the four space verbs: `list`, `create`, `exists`, and `delete`. Examples use a durable database at `./mydb`. Pass `--space ` on any command to target a space; omit it to use `default`. ## The default space A fresh database reports exactly one space: ```bash strata ./mydb space list ``` ```text default ``` With `--json`, the list arrives as an envelope with a continuation cursor: ```bash strata --json ./mydb space list ``` ```text {"data":{"cursor":null,"has_more":false,"items":["default"]},"type":"space_list"} ``` ## Create a space `space create ` registers a new space: ```bash strata ./mydb space create analytics ``` ```text created analytics applied=true ``` ## Check existence `space exists ` prints a bare boolean — handy in scripts: ```bash strata ./mydb space exists analytics # true strata ./mydb space exists ghost # false ``` ## How spaces scope data Each space holds its own independent instance of every primitive. The same key in two spaces refers to two different values. Write `report` in `analytics`, and the `default` space does not see it: ```bash strata ./mydb --space analytics kv put report q3 strata ./mydb --space analytics kv get report # q3 strata ./mydb kv get report # (nil) ``` Counts confirm the isolation — `kv count` returns `1` in `analytics` and `0` in `default`. This applies to every primitive: KV, JSON, vectors, events, and graphs are all space-scoped. ## Delete a space `space delete ` drops a space. By default it refuses to delete a space that still holds visible data: ```bash strata ./mydb space delete analytics ``` ```text failed_precondition.engine.space_not_empty: product space `analytics` contains visible data; retry with force=true to delete it (err_local_33f20156_000001) hint: Reload the current state and retry the operation against the latest version. ref: https://stratadb.org/e/failed_precondition.engine.space_not_empty ``` Pass `--force` to delete the space and its visible data together: ```bash strata ./mydb space delete analytics --force ``` ```text deleted analytics applied=true ``` Deleting an empty space needs no flag. Deleting a space that does not exist is a no-op — it reports `applied=false` and exits zero rather than failing: ```bash strata ./mydb space delete ghost ``` ```text not_found ghost applied=false ``` The default space cannot be deleted: ```bash strata ./mydb space delete default ``` ```text invalid_argument.engine.space_delete_default: default product space cannot be deleted (err_local_35ac8288_000001) hint: Correct the request input and retry the operation. ref: https://stratadb.org/e/invalid_argument.engine.space_delete_default ``` ## Spaces or branches? Reach for a space when you want to keep related data organized inside one line of history — tenants, sessions, or datasets that live and version together. Reach for a [branch](/docs/guides/branching-workflows) when you want an isolated copy of history you can fork, time-travel, and discard. The two compose: a branch contains spaces, and forking a branch carries its spaces along. ## Next - [Branch Management](/docs/guides/branching-workflows) — isolate history with forks. - [KV Store](/docs/data/key-value) — the primitive used in these examples. - [Concepts: Primitives](/docs/concepts/primitives) — how the five data types relate. --- # Time travel Source: https://stratadb.org/docs/guides/time-travel Strata keeps history, so you can read the database as it was at an earlier commit instead of restoring a backup. This guide is the hands-on patterns; for the model behind them see [the time-travel concept](/docs/concepts/time-travel). Examples use a durable database at `./mydb`. ## Capture a commit timestamp Time-travel reads take a **commit timestamp** — the small logical clock value a write returns, not a wall-clock time. Grab it from a write receipt under `--json`: ```bash strata --json ./mydb json set config '$.tier' '"free"' ``` ```text {"data":{"commit":{"delete_count":0,"durable":true,"put_count":1,"timestamp":3,"version":3}, ...},"type":"json_versioned_value"} ``` The `commit.timestamp` (here `3`) names this moment. Do another write and it advances: ```bash strata --json ./mydb json set config '$.tier' '"pro"' # commit.timestamp 4 ``` ## Read as of a past commit Pass `--as-of ` to any read to see the state at that commit, ignoring later writes: ```bash strata ./mydb json get config '$.tier' # "pro" (latest) strata ./mydb --as-of 3 json get config '$.tier' # "free" (as of commit 3) ``` The same flag works on every primitive — KV, JSON, vectors, events, and the graph — so one timestamp gives you a consistent snapshot of the whole database. ## List a key's history Where `--as-of` reads *as of* a moment, the `history` verbs show *what changed*. Each primitive with mutable values exposes one, newest-first: ```bash strata ./mydb json history config ``` ```text {"document_version":4,"timestamp":4,"tombstone":false,"value":{"tier":"pro"},"version":4} {"document_version":3,"timestamp":3,"tombstone":false,"value":{"tier":"free"},"version":3} ``` KV has `kv history `, vectors have `vector history `, and so on. Reach for history to find the commit you want, then read `--as-of` it. ## Reproduce state at a point in time To *work with* a past state rather than just read it, fork a branch anchored to that commit. The fork starts from the old state and evolves independently, leaving the source branch untouched: ```bash strata ./mydb branch fork main investigate --timestamp 3 strata ./mydb --branch investigate json get config '$.tier' # "free" ``` This is the "reproduce the bug as of last Tuesday, then poke at it" workflow — see [branching workflows](/docs/guides/branching-workflows) for the full fork surface. ## Audit what changed Combine the two: `history` tells you the sequence of versions, and `--as-of` reads any of them back in full. To compare two points, read the same key at two timestamps: ```bash strata ./mydb --as-of 3 json get config '$' strata ./mydb --as-of 4 json get config '$' ``` For an append-only audit trail rather than point-in-time diffs, the [event log](/docs/data/events) is hash-linked and verifiable, and `event range-time` selects events by their own wall-clock timestamp. ## When history runs out History is retained but not unbounded. Asking for a timestamp older than retained history returns a typed `history_unavailable` error rather than a wrong answer — branch on that class if you reach far back. See [error handling](/docs/guides/error-handling). ## Related - [Time travel (concept)](/docs/concepts/time-travel) — the commit clock and the model. - [Branching workflows](/docs/guides/branching-workflows) — forking from a past point. - [Combining primitives](/docs/data/combining-primitives) — one snapshot across all five. --- # Inference Source: https://stratadb.org/docs/inference Inference is a **capability**, not a stored primitive: the `inference` commands execute models — text generation, embeddings, ranking, and tokenization — without keeping any model output in the database. Two provider families are available: **local** GGUF models that run in-process, and **cloud** providers reached over the network. The catalog and capability facts are always available offline; running a model needs either a local model on disk ([Local models](/docs/inference/local-models)) or a configured cloud API key ([Providers & API keys](/docs/inference/providers-and-keys)). ## Model specs Every command takes a model spec. A bare name (`miniLM`, `tinyllama`) resolves against the built-in catalog and runs **locally**. A `provider:model` spec routes to a **cloud** provider — the supported providers are `local`, `anthropic`, `openai`, and `google`. An unknown provider prefix fails fast: ```text inference.provider_unavailable: provider error: unknown provider: "voyage" (expected: local, anthropic, openai, google) ref: https://stratadb.org/e/inference.provider_unavailable ``` ## The catalog `inference models list` prints the catalog — name, task, architecture, quantization, availability, and size. `inference models local` narrows it to models already on disk: ```bash strata --cache inference models local ``` ```text miniLM embed bert f16 local 42.9 MB tinyllama generate llama q4_k_m local 638.9 MB ``` `inference capability ` reports what a model can do without running it — useful for routing decisions in a script: ```bash strata --cache inference capability openai:gpt-4o-mini ``` ```text { "can_embed": true, "can_generate": true, "can_rank": false, "can_tokenize": false, "embedding_dim": 0, "model": "gpt-4o-mini", "network_enabled": true, "provider": "openai", "provider_feature_enabled": true, "requires_api_key": true, "requires_network": true } ``` `requires_api_key` and `requires_network` tell you what a call will need; `provider_feature_enabled` tells you whether this binary was built with that provider compiled in. Because the catalog and capability are computed offline, these two commands never touch the network or a key. ## The operations Every operation takes a model spec and routes to local or cloud by the rule above. The flags are the same regardless of provider; what differs is the prerequisite — a cloud spec needs a key, a local spec needs the local build feature and a model on disk. - **`inference generate `** — text generation. Accepts `--max-tokens` (default 256), `--temperature` (default 0.0, greedy), `--top-k`, `--top-p`, `--seed` for deterministic sampling, and a repeatable `--stop `. Chat models expect their chat template verbatim in the prompt. `--stop-token ` and `--grammar ` are local-only refinements. - **`inference embed `** embeds one string; **`inference embed-batch `** embeds several in order. Embedding output feeds the [vector store](/docs/data/vectors) — see [Combining primitives](/docs/data/combining-primitives) for the retrieval flow. - **`inference rank `** scores passages against a query. Ranking is a local-model operation; cloud providers do not expose a reranker, so a cloud spec here returns `inference.unsupported_operation`. - **`inference tokenize `** and **`inference detokenize `** convert between text and token ids for a local model; `--special` adds the model's special tokens. A cloud call refuses before touching the network when its key is unset, and a local call refuses when the binary lacks the local feature — both with a clear code. Those prerequisites, and how to satisfy them, are on the two pages below. ## In this section - **[Providers & API keys](/docs/inference/providers-and-keys)** — the cloud provider families, the environment variables and `strata config` storage for their keys, and where to acquire a key. - **[Local models](/docs/inference/local-models)** — running GGUF models in-process: pulling them, the model directory, the resident-model cache, and the local build feature. ## Related - [Vectors](/docs/data/vectors) — where embeddings are stored and searched - [Agents and MCP](/docs/agents) — exposing the database to model-driven agents - [Error Handling](/docs/guides/error-handling) — reading structured error codes ## Reference Every inference command — parameters, returns, errors, and runnable CLI/wire/Python examples — is in the generated [Inference command reference](/docs/reference/inference). --- # Local models Source: https://stratadb.org/docs/inference/local-models Local inference runs a GGUF model **in-process**, with no network and no API key. Generation, embedding, ranking, and tokenization all work against a local model named by a bare spec (`tinyllama`, `miniLM`). This is the path for offline, private, or air-gapped use — the data and the model never leave the machine. ## The local build feature Local execution paths require a binary **built with the local inference feature**. The default distribution is cloud-first; when the local feature is absent, a local call refuses with a clear code rather than silently doing nothing: ```bash strata --cache inference generate tinyllama "Hello" --max-tokens 5 ``` ```text inference.unsupported_operation: not supported: local generation requires the local feature hint: Inspect inference configuration and retry with supported settings. ref: https://stratadb.org/e/inference.unsupported_operation ``` Check `provider_feature_enabled` in `inference capability ` before relying on a local model in a script. When the feature is present, the operations documented in [Inference](/docs/inference#the-operations) run against local models, and two `generate` refinements become available: `--stop-token ` and `--grammar `. GPU acceleration for local models ships separately from the default CPU build (for example, the `stratadb[cuda]` Python wheel); the base CLI runs local models on CPU. ## Pulling models `inference models pull ` downloads a model into the local model directory. It reads: - `STRATA_MODELS_DIR` — the destination directory for downloaded models. - `STRATA_HF_ENDPOINT` — the Hugging Face endpoint to fetch from. - `STRATA_HF_TOKEN` (or `HF_TOKEN`) — a token for gated repositories. Pulling requires network access. Once pulled, a model appears in `inference models local` and runs offline thereafter. ```bash strata --cache inference models local ``` ```text miniLM embed bert f16 local 42.9 MB tinyllama generate llama q4_k_m local 638.9 MB ``` ## The resident-model cache Local models stay resident after first use, so repeated calls skip the load cost. `inference cache-status` reports what is currently loaded: ```bash strata --cache inference cache-status ``` ```text { "embedding_models": [], "generation_models": [], "ranking_models": [] } ``` `inference unload ` evicts one cached model; `inference unload` with no argument evicts everything. When nothing matches, it reports `no cached entry`. Unloading frees memory without deleting the model from disk — the next call reloads it. ## Related - [Inference](/docs/inference) — the model, catalog, and operations - [Providers & API keys](/docs/inference/providers-and-keys) — the cloud alternative - [Vectors](/docs/data/vectors) — where local embeddings are stored and searched --- # Providers & API keys Source: https://stratadb.org/docs/inference/providers-and-keys Cloud inference routes on the spec prefix: `openai:`, `anthropic:`, or `google:` (the fourth provider, `local:`, runs [on-device](/docs/inference/local-models)). Each cloud provider needs an API key. Strata never bundles one — you bring your own — and reads it from one of two places. ## The providers | Provider | Spec prefix | Key variable | Get a key | |----------|-------------|--------------|-----------| | OpenAI | `openai:` | `OPENAI_API_KEY` | [platform.openai.com/api-keys](https://platform.openai.com/api-keys) | | Anthropic | `anthropic:` | `ANTHROPIC_API_KEY` | [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) | | Google | `google:` | `GOOGLE_API_KEY` | [aistudio.google.com/apikey](https://aistudio.google.com/apikey) | A spec like `openai:gpt-4o-mini` picks the provider and the model in one token. `inference capability ` reports `requires_api_key` and `requires_network` for a spec without calling the provider. ## Supply the key by environment variable The simplest path: export the provider's variable. The inference runtime reads it directly. ```bash export OPENAI_API_KEY="sk-…" strata --cache inference generate openai:gpt-4o-mini "Write a haiku about databases" --max-tokens 40 ``` With the key unset, the call refuses **before** touching the network: ```bash strata --cache inference generate openai:gpt-4o-mini "Write a haiku about databases" --max-tokens 40 ``` ```text inference.missing_api_key: provider error: OPENAI_API_KEY not set (required for openai provider) hint: Set the provider API key and retry. ref: https://stratadb.org/e/inference.missing_api_key ``` ## Store the key in config To avoid exporting a variable in every shell, store the key in the global Strata config with `strata config set .api_key`. The settable keys are `openai.api_key`, `anthropic.api_key`, and `google.api_key` (plus `hub.url`). Keys are written with `0600` permissions and are never echoed back in plaintext. ```bash strata config set openai.api_key "sk-…" strata config get-key openai.api_key ``` ```text {"key":"openai.api_key","set":true,"value":"sk-…"} ``` `config get-key` reports whether a key is set and shows only a redacted preview, never the raw value. Remove one with `strata config unset openai.api_key`, and print the config file's location with `strata config path`. ## Resolution order When both are present, **the environment variable wins.** On startup Strata copies any stored key into its environment variable *only if that variable is not already set*, so an exported `OPENAI_API_KEY` always overrides the stored one. This lets you keep a default key in config and override it per-shell or per-CI-job without editing the file. 1. `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` / `GOOGLE_API_KEY` in the environment. 2. Otherwise, the key stored by `strata config set .api_key`. 3. Otherwise, the call refuses with `inference.missing_api_key`. ## Errors worth knowing - [`inference.missing_api_key`](/e/inference.missing_api_key) — no key for the provider (from either source). - [`inference.provider_auth_failed`](/e/inference.provider_auth_failed) — the provider rejected the key. - [`inference.provider_unavailable`](/e/inference.provider_unavailable) — unknown provider prefix, or the provider could not be reached. - [`inference.provider_rate_limited`](/e/inference.provider_rate_limited) and [`inference.provider_timeout`](/e/inference.provider_timeout) — transient provider conditions; retry per the error's policy. Match on the code, never the message — see [error handling](/docs/guides/error-handling). ## Related - [Inference](/docs/inference) — the model, catalog, and operations - [Local models](/docs/inference/local-models) — the on-device alternative that needs no key --- # Migrating Source: https://stratadb.org/docs/guides/migrating Strata is not a relational database, so migrating into it is a **mapping** exercise, not a schema copy: you decide which [primitive](/docs/concepts/primitives) each source table or keyspace becomes, then move the rows. The mechanism is the same in every case — export the source to Parquet, CSV, or JSON lines, then load it with [`arrow import`](/docs/guides/import-export). This guide shows the path from three common sources. ## The general shape 1. **Choose the target primitive.** A flat key→value table maps to [KV](/docs/data/key-value); a table of structured records maps to [JSON](/docs/data/json); embeddings map to a [vector](/docs/data/vectors) collection. 2. **Export the source** to CSV, Parquet, or JSON lines. 3. **Import** with `strata arrow import --target `, naming the key and value columns. Import targets are `kv`, `json`, and `vector`; the format is inferred from the file or set with `--format`. ## From SQLite Export a table to CSV with the `sqlite3` shell, then import it. A two-column `settings(key, value)` table maps cleanly to KV: ```bash sqlite3 app.db -cmd '.mode csv' -cmd '.headers on' \ '.once settings.csv' 'SELECT key, value FROM settings;' strata ./mydb arrow import --target kv --key-column key --value-column value ./settings.csv ``` For a table of structured rows, serialize each row to JSON and import into the JSON primitive instead — pick a column as the document key and a JSON column as the value, matching the column names with `--key-column` / `--value-column`. ## From DuckDB DuckDB writes Parquet directly, which imports without a format flag: ```sql COPY (SELECT id AS key, to_json(t) AS value FROM records t) TO 'records.parquet' (FORMAT parquet); ``` ```bash strata ./mydb arrow import --target json --key-column key --value-column value ./records.parquet ``` Parquet preserves types and is the most faithful round-trip format. Use it when moving large tables. ## From Redis Dump the keyspace to JSON lines — one `{"key":…,"value":…}` object per line — and import into KV: ```bash redis-cli --scan | while read k; do printf '{"key":%s,"value":%s}\n' "$(jq -Rn --arg v "$k" '$v')" "$(redis-cli GET "$k" | jq -Rs .)" done > redis.jsonl strata ./mydb arrow import --target kv --key-column key --value-column value ./redis.jsonl ``` Structured Redis values (hashes, JSON stored as strings) are a better fit for the JSON primitive — serialize each value to a JSON document and import with `--target json`. ## Embeddings To migrate vectors, create the destination collection first (its dimension and metric are fixed at creation), then import into it with `--target vector --collection `. The exact column mapping for vector imports is in [Import & export](/docs/guides/import-export#column-mapping). ## After the import The import reports `rows_imported`, and the data is immediately branch-aware and versioned like anything else — fork it, read it [`--as-of`](/docs/guides/time-travel), and partition it with [spaces](/docs/guides/spaces). Verify with a `count` on the target primitive, and spot-check a few keys before pointing your application at the new database. ## What does not carry over Strata has no SQL, joins, or foreign keys, so relational structure does not migrate — you re-model it across primitives (a join table might become graph edges, for instance). There is no automated schema translation and no migration tool that runs the source system for you; the export step is yours to run with the source's own tools. ## Related - [Import & export](/docs/guides/import-export) — the full `arrow import`/`export` surface and column mapping. - [Primitives](/docs/concepts/primitives) — choosing the target shape. - [Cloning datasets](/docs/guides/cloning-datasets) — the other way data arrives, for already-prepared Strata datasets. --- # Agent integration Source: https://stratadb.org/docs/python/agents The SDK carries the same self-describing surface as the binary, so an agent working in Python never has to shell out to learn what Strata can do. Everything here is bundled in the wheel — no network call. ## The offline guide `stratadb.agents_guide()` returns the complete usage guide as markdown — identical to `strata agents guide`, matched to the wheel's engine version. Hand it to an agent at the start of a session: ```python import stratadb print(stratadb.agents_guide()) # the full guide, offline ``` See [the agents guide](/docs/agents/agents-guide) for the CLI and MCP forms of the same artifact. ## The command catalog `stratadb.command_index()` returns the full machine-readable command catalog — every command with its access class, batching and commit behavior, and error codes — bundled in the wheel: ```python idx = stratadb.command_index() # the IDL catalog, as a dict ``` This is the same catalog behind [the command reference](/docs/reference/kv) and `strata agents commands --json`. ## MCP client config `stratadb.mcp_config(path)` returns the client-config snippet for pointing an MCP client at a database: ```python stratadb.mcp_config("./app-data") # {"command": "strata", "args": ["./app-data", "mcp", "serve"]} ``` Drop it into your MCP client's `mcpServers` map — see [the MCP server](/docs/agents/mcp-server). ## The escape hatch The typed namespaces cover the common path; for anything else in the catalog, `db.execute()` runs a raw command as a dict and returns the response dict — the same wire the CLI and MCP speak. The namespaces are built on it: ```python db.execute({"type": "kv_scan", "limit": 10}) ``` Reach for `db.execute()` when a command has no curated wrapper yet; reach for the namespaces for everything else. ## Related - [For AI agents](/docs/agents) — the section overview. - [The agents guide](/docs/agents/agents-guide) and [command index](/docs/agents/command-index) — the CLI/MCP forms. --- # Errors Source: https://stratadb.org/docs/python/errors Every failure raises a typed subclass of `stratadb.errors.StrataError`, carrying the same stable `..` [code](/docs/concepts/errors) the CLI and MCP server use. The rule is identical across every Strata channel: > **Match on `code`, never on the message.** The code is stable; the message is > for humans and may change. ```python from stratadb import errors try: db.at(branch="ghost").kv.get("k") except errors.NotFoundError as e: assert e.code == "not_found.engine.branch" print(e.message) # human-readable print(e.hint) # the safe next step print(e.ref) # https://stratadb.org/e/not_found.engine.branch ``` ## The exception hierarchy `StrataError` is the base; each error class in the taxonomy has its own subclass, so you can catch broadly or narrowly: | Exception | Code class | |---|---| | `NotFoundError` | `not_found` | | `AlreadyExistsError` | `already_exists` | | `InvalidArgumentError` | `invalid_argument` | | `FailedPreconditionError` | `failed_precondition` | | `ConflictError` | `conflict` | | `HistoryUnavailableError` | `history_unavailable` | | `UnsupportedError` | `unsupported` | | `ResourceExhaustedError` | `resource_exhausted` | | `AccessDeniedError` | `access_denied` | | `UnavailableError` | `unavailable` | | `AmbiguousCommitError` | `ambiguous_commit` | | `SerializationError` | `serialization` | | `CorruptionError` | `corruption` | | `IoError` | `io` | | `InternalError` | `internal` | Catch `StrataError` to handle anything, or a specific subclass to react to one kind. The enum is open, so an unknown class maps to the base `StrataError` rather than failing. ```python try: db.kv.put(bad_key, value) except errors.InvalidArgumentError: ... # fix the input except errors.StrataError as e: log.error("strata failed", code=e.code, ref=e.ref) ``` ## Misses are not errors A read that finds nothing returns `None` and does **not** raise — a missing key, document, or path is a normal result, not a failure. The one historical exception is a time-travel read outside retained history, which raises `HistoryUnavailableError` (distinct from `NotFoundError`). ```python db.kv.get("missing") # None db.kv.get("k", as_of=0) # raises HistoryUnavailableError if 0 is too old ``` ## What each error tells you Beyond `code`, every `StrataError` carries a `message`, a `hint` (the safe next step), a `ref` (the `/e/` docs URL), and — where relevant — retry and commit-outcome information. For the full model, see the [errors concept](/docs/concepts/errors) and the [error reference](/docs/reference/error-reference). --- # Python SDK Source: https://stratadb.org/docs/python `stratadb` is the Python SDK for Strata: it links the engine **in your process** and opens a file-backed (or in-memory) database directly — SQLite-shaped, not a server. It speaks the exact same command surface, value shapes, and [error codes](/docs/concepts/errors) as the [`strata` CLI](/docs/reference/cli) and the [MCP server](/docs/agents/mcp-server), so learning one channel is learning all of them. > **Availability:** `stratadb` `1.0.0` is the V1 line, and its version tracks the > engine (`stratadb.__version__` equals the engine version). The V1 wheels are > rolling out to PyPI. ## Install ```bash pip install stratadb ``` No Rust toolchain required — wheels are prebuilt (`abi3`, one per platform, Python 3.9+). The base wheel runs cloud inference on CPU; GPU-accelerated local models come from a companion wheel (`stratadb[cuda]`). See [installation](/docs/python/installation) for the extras and platform matrix. ## Quickstart ```python import stratadb db = stratadb.open("./app-data") # durable (creates if absent) # db = stratadb.open(cache=True) # ephemeral, in-memory # Key-value — values are bytes; str is encoded as UTF-8 db.kv.put("greeting", "hello") db.kv.get("greeting") # b"hello" # JSON documents, addressed by path db.json.set("user:1", "$", {"name": "Ada", "roles": ["admin"]}) db.json.get("user:1", "$.name") # "Ada" # Vectors — similarity search with metadata filters from stratadb import filters db.vectors.create_collection("notes", dimension=3) db.vectors.upsert("notes", "n1", [0.1, 0.2, 0.3], metadata={"kind": "note"}) hits = db.vectors.query("notes", [0.1, 0.2, 0.3], k=5, filter=filters.eq("kind", "note")) # Events (append-only, hash-chained) and graph db.events.append("signup", {"user": "ada"}) db.graphs.create("social") db.graphs.add_node("social", "ada") db.graphs.add_node("social", "grace") # both endpoints must exist first db.graphs.add_edge("social", "ada", "follows", "grace") db.close() # or use it as a context manager (below) ``` `stratadb.open()` **never opens the current directory implicitly** — pass a path, set `STRATA_DB` (`stratadb.from_env()`), or use `cache=True`, or it raises `InvalidArgumentError`. It is also a context manager: ```python with stratadb.open("./app-data") as db: db.kv.put("k", "v") ``` ## How it is built Three layers, so the ergonomics are handwritten but the surface can't drift from the engine: 1. **Namespaces** — the handwritten, ergonomic API (`db.kv`, `db.json`, `db.ai`, …). 2. **Generated core** — one typed method and model per command, generated from the engine's IDL and drift-guarded in CI. 3. **PyO3 binding** — a thin native layer that links the engine in process. Because the middle layer is generated from the same IDL that produces the [command reference](/docs/reference/kv), the SDK and the docs describe one surface. ## In this section - **[Installation](/docs/python/installation)** — wheels, the `[cuda]`/`[gpu]` extras, and `py.typed` type checking. - **[Namespaces](/docs/python/namespaces)** — the data-plane API: the ten namespaces, `db.at()` scoping, `as_of`, and filters. - **[Inference (`db.ai`)](/docs/python/inference)** — chat, embeddings, reranking, structured outputs, and tools. - **[Errors](/docs/python/errors)** — the typed exception hierarchy; recover by code. - **[Agent integration](/docs/python/agents)** — `agents_guide()`, `mcp_config()`, and the raw command escape hatch. --- # Inference (db.ai) Source: https://stratadb.org/docs/python/inference `db.ai` runs models: chat generation, embeddings, and reranking, over cloud providers (OpenAI, Anthropic, Google) or local GGUF models — an OpenAI-shaped surface right on the database handle. Strata ships no keys; provide them as described in [providers & API keys](/docs/inference/providers-and-keys) (an environment variable or `strata config set .api_key`). Model specs are the same everywhere: a `provider:model` string routes to a cloud provider; a `local:` prefix (or bare name) runs locally. See [Inference](/docs/inference) for the model surface behind this. ## Chat ```python r = db.ai.chat("Explain embeddings in one sentence.", model="openai:gpt-4o-mini", max_tokens=60) r.content # the first choice's text r.usage # token accounting, OpenAI-shaped ``` `chat` accepts a plain string or a full message list (`[{"role": "user", "content": ...}, ...]`); the result's `.message`, `.content`, `.tool_calls`, and `.finish_reason` read the first choice. ### Structured output Pass a JSON Schema and the model returns conforming JSON: ```python r = db.ai.chat("Capital of France and its population?", model="anthropic:claude-haiku-4-5-20251001", json_schema={"type": "object", "properties": {"capital": {"type": "string"}, "population": {"type": "integer"}}, "required": ["capital", "population"]}) ``` ### Tools / function calling ```python r = db.ai.chat("What's the weather in Paris?", model="google:gemini-2.5-flash", tools=[{"type": "function", "function": {"name": "get_weather", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}}], tool_choice="required") r.tool_calls # [{'id': ..., 'function': {'name': 'get_weather', 'arguments': '{"city":"Paris"}'}}] ``` ## Embeddings ```python e = db.ai.embed(["hello", "world"], model="openai:text-embedding-3-small") e.vectors # all vectors, ordered by input index e.vector # convenience for a single-input call ``` Embedding output feeds the [vector store](/docs/python/namespaces) — embed text, then `db.vectors.upsert` the result under the same key as its source record. ## Reranking `rank` scores candidate passages against a query — the precision pass after a vector search recall pass: ```python scores = db.ai.rank("What is a commit clock?", ["passage one...", "passage two..."], model="local:bge-reranker-v2-m3") ``` Reranking runs on local models; on a build without the local feature it refuses with a coded error (shown below) rather than degrading silently. ## Model handles A model handle sets the spec once and reuses it across calls: ```python qwen = db.ai.model("local:qwen3", n_ctx=8192) qwen.chat("Summarize: ...") qwen.capability() ``` ## Capability, without a call `db.ai.capability(spec)` reports what a model supports — computed offline, with no request to the provider. Real output from the base wheel: ```python db.ai.capability("openai:gpt-4o-mini") ``` ```text {'provider': 'openai', 'model': 'gpt-4o-mini', 'can_generate': True, 'can_tokenize': False, 'can_embed': True, 'can_rank': False, 'requires_network': True, 'requires_api_key': True, 'provider_feature_enabled': True, 'network_enabled': True, 'embedding_dim': 0, 'supports_tools': True, 'supports_json_object': True, 'supports_json_schema': True, 'supports_logprobs': True} ``` Use it to route in a script before spending a call. ## Errors you will actually see Inference failures are [typed and coded](/docs/python/errors) like every other Strata error. The two most common, reproduced verbatim: **Missing provider key** — the call never leaves your process: ```python db.ai.chat("hi", model="openai:gpt-4o-mini") ``` ```text FailedPreconditionError: inference.missing_api_key: provider error: OPENAI_API_KEY is not set: the openai API key is missing. Get a key at https://platform.openai.com/api-keys, then set it with `strata config set openai.api_key ` or by exporting OPENAI_API_KEY. hint: Set the provider API key and retry. ref: https://stratadb.org/e/inference.missing_api_key ``` **Local model on a base build** — local execution is a build-time feature (the base wheel runs cloud providers; see [local models](/docs/inference/local-models)): ```python db.ai.rank("query", ["doc a", "doc b"], model="local:jina-reranker-v1-tiny") ``` ```text UnsupportedError: inference.unsupported_operation: not supported: ranking requires the local feature hint: Inspect inference configuration and retry with supported settings. ref: https://stratadb.org/e/inference.unsupported_operation ``` Catch them like any other typed error: ```python from stratadb import errors try: r = db.ai.chat("hi", model="openai:gpt-4o-mini") except errors.FailedPreconditionError: ... # key missing — configure and retry except errors.UnavailableError: ... # provider unreachable / rate limited — retryable ``` ## Related - [Providers & API keys](/docs/inference/providers-and-keys) — where keys come from. - [Local models](/docs/inference/local-models) — running GGUF models in process. - [Typed errors](/docs/python/errors) — the exception hierarchy. - [Combining primitives](/docs/data/combining-primitives) — the embed-then-upsert retrieval flow. --- # Installation Source: https://stratadb.org/docs/python/installation ```bash pip install stratadb ``` That is the whole install. Wheels are **prebuilt** — there is no Rust toolchain to set up and nothing compiles on your machine. ## Wheels and platforms - **`abi3`** — one wheel per platform works across Python **3.9+**, so upgrades don't need a new download. - Platforms: manylinux and musllinux (x86_64, aarch64), macOS (arm64, x86_64), and Windows x86_64. - The version tracks the engine: `stratadb.__version__` equals the engine version, so the SDK and the database format always match. ## CPU and GPU inference The base wheel runs **cloud inference on CPU** — chat, embeddings, and reranking through cloud providers work out of the box. For **GPU-accelerated local models**, install the companion extra: ```bash pip install "stratadb[cuda]" # GPU-accelerated local model execution ``` Cloud inference needs no extra — only a provider API key (see [`db.ai`](/docs/python/inference)). Local model execution is the piece that benefits from the GPU build. ## Type checking The package ships `py.typed` and generated stubs, so type checkers (mypy, pyright) see the full typed surface — every namespace method, its parameters, and its return model. Editors get autocomplete and inline signatures with no extra setup. ## Verifying ```python import stratadb print(stratadb.__version__) # the installed engine/SDK version with stratadb.open(cache=True) as db: # ephemeral, no files touched db.kv.put("k", "v") assert db.kv.get("k") == b"v" ``` If that runs, the native binding loaded and the engine is live in your process. ## Next - [Namespaces](/docs/python/namespaces) — the data-plane API. - [Inference](/docs/python/inference) — `db.ai` and provider keys. --- # Namespaces Source: https://stratadb.org/docs/python/namespaces A `Strata` handle exposes the whole surface through **namespaces** — one per capability, plus control-plane and integration namespaces. Each method is a lossless wrapper over a single engine command, adding only Python ergonomics. ## The namespaces | Namespace | What it covers | |---|---| | `db.kv` | key → bytes: `put`, `get`, `delete`, `keys`, `scan`, `exists`, `count`, `history`, and `*_many` batch ops | | `db.json` | documents by path: `set`, `get`, `delete`, `keys`, indexes, `history` | | `db.vectors` | collections, `upsert`, similarity `query` with filters, metadata | | `db.events` | append-only log: `append`, `get`, `list`, `range`, `verify_chain` | | `db.graphs` | `create`, `add_node`, `add_edge`, `neighbors`, traversal, analytics, ontology | | `db.branches` | `list`, `create`, `fork` (from tip, version, or time), `delete` | | `db.spaces` | `list`, `create`, `exists`, `delete` — partitions within a branch | | `db.admin` | `ping`, `info`, `health`, `metrics`, `describe`, `config` | | `db.arrow` | `import_` / `export` primitives as Parquet, CSV, or JSON lines | | `db.ai` | chat, embeddings, reranking — [its own page](/docs/python/inference) | Every method maps to a command in the [command reference](/docs/reference/kv), where you'll find the full parameter and return detail for each one. ## Values are bytes KV values are opaque bytes. A `str` you pass is encoded as UTF-8; what you read back is `bytes`: ```python db.kv.put("greeting", "hello") # str → UTF-8 db.kv.get("greeting") # b"hello" db.kv.get("missing") # None — a miss is not an error ``` JSON values are Python objects (dicts, lists, scalars), addressed by path: ```python db.json.set("user:1", "$", {"name": "Ada", "age": 36}) db.json.set("user:1", "$.age", 37) # update one field db.json.get("user:1", "$") # {"name": "Ada", "age": 37} ``` ## Misses return `None` Reads distinguish absence from failure: reading a key, document, or path that does not exist returns `None` and does **not** raise. Errors are reserved for things that actually went wrong — see [errors](/docs/python/errors). ## Time travel: `as_of` Every read accepts `as_of`, a commit timestamp taken from a write receipt. It returns the value as of that commit: ```python receipt = db.kv.put("k", "v1") db.kv.put("k", "v2") db.kv.get("k") # b"v2" (latest) db.kv.get("k", as_of=receipt.commit.timestamp) # b"v1" (historical) ``` The same `as_of` works across every namespace, giving a consistent snapshot of the whole database at that commit. `history` returns the full version trail for a key, newest first — including tombstones for deletes: ```python db.kv.history("k") ``` ```text [HistoryItem(timestamp=7, tombstone=False, version=7, value=b'v2'), HistoryItem(timestamp=6, tombstone=False, version=6, value=b'v1')] ``` ## Scoped views: `db.at()` `db.at(branch=..., space=...)` returns a **cheap scoped view** over the same handle — every call through it targets that branch and space, without changing the base handle: ```python db.branches.fork("default", "experiment") # copy-on-write fork of the default branch exp = db.at(branch="experiment") exp.kv.put("k2", "only-on-experiment") # written on the fork exp.kv.get("k2") # b"only-on-experiment" db.kv.get("k2") # None on default — isolated ``` Views compose with spaces the same way: `db.at(space="analytics")`. ## Filters Vector queries (and filtered deletes) take a `filter` built with the `filters` helper — an AND-of-equality builder that produces the wire filter shape: ```python from stratadb import filters f = filters.eq("lang", "en") & filters.eq("year", 2024) db.vectors.query("notes", query_vec, k=5, filter=f) ``` ## Pagination List and scan methods that page expose `iter_*` helpers that walk the cursor for you, so you rarely handle a cursor by hand: ```python for key in db.kv.iter_keys(prefix="user:"): ... ``` ## Next - [Inference (`db.ai`)](/docs/python/inference) — the model surface. - [Errors](/docs/python/errors) — the typed exception hierarchy. - [Command reference](/docs/reference/kv) — per-command parameters and returns. --- # API Quick Reference Source: https://stratadb.org/docs/reference/api-quick-reference > **Interim page.** Maintained by hand until it is generated from the resolved command index (IDL). Where this page and `strata agents commands --json` disagree, the command index wins. The operations you reach for most, one per capability. Examples assume a durable database at `./my-db`; swap in `--cache` for an ephemeral one. The full surface is in the [Command Reference](/docs/reference/command-reference); how to invoke the binary is in the [CLI Reference](/docs/reference/cli). ## Targeting and output ```bash strata ./my-db kv get k # durable path (or --db ./my-db, or STRATA_DB=./my-db) strata --cache kv get k # ephemeral, nothing persisted strata --json ./my-db kv get k # {"type":…,"data":…} envelope; values base64 strata --raw ./my-db kv get k # bare value, for scripts ``` ## KV ```bash strata ./my-db kv put greeting hello # created greeting applied=true strata ./my-db kv get greeting # hello strata ./my-db kv list --prefix user: # keys with a prefix strata ./my-db kv delete greeting ``` ## JSON ```bash strata ./my-db json set user:1 '$' '{"name":"Ada","age":36}' # $ is the document root strata ./my-db json get user:1 '$.name' # "Ada" strata ./my-db json set user:1 '$.age' 37 # update one path strata ./my-db json list --prefix user: ``` ## Event log ```bash strata ./my-db event append signup '{"user":"ada"}' # created applied=true strata ./my-db event count # 1 strata ./my-db event get 0 # sequences start at 0 strata ./my-db event by-type signup ``` ## Vector ```bash strata ./my-db vector collection create docs 4 --metric cosine strata ./my-db vector upsert docs d1 '[0.1,0.2,0.3,0.4]' --metadata '{"lang":"en"}' strata ./my-db vector query docs '[0.1,0.2,0.3,0.4]' -k 3 # d1 1.0 # metadata filter: AND-composed conditions, each value tagged by type strata ./my-db vector query docs '[0.1,0.2,0.3,0.4]' -k 3 \ --filter '{"conditions":[{"field":"lang","op":"eq","value":{"type":"string","value":"en"}}]}' ``` ## Graph ```bash strata ./my-db graph create social strata ./my-db graph add-node social alice --properties '{"city":"tokyo"}' strata ./my-db graph add-edge social alice follows bob --weight 1.0 strata ./my-db graph neighbors social alice --direction outgoing strata ./my-db graph pagerank social # analytics over the graph ``` ## Branches ```bash strata ./my-db branch fork default experiment # cheap copy-on-write fork strata ./my-db kv put city tokyo --branch experiment strata ./my-db kv get city --branch experiment # tokyo strata ./my-db kv get city # unchanged on default strata ./my-db branch list ``` ## Spaces ```bash strata ./my-db space create staging strata ./my-db kv put k v --space staging # isolated from the default space strata ./my-db space list ``` ## Time travel Every write receipt carries a commit clock value at `data.commit.timestamp` (a small integer, visible with `--json`). Pass it back with `--as-of` on any read. It is the commit clock, not a wall-clock time. ```bash strata --json ./my-db kv put k v1 # data.commit.timestamp: 3 strata ./my-db kv put k v2 # data.commit.timestamp: 4 strata ./my-db kv get k --as-of 3 # v1 ``` ## Inference ```bash strata inference models list strata inference embed "text to embed" strata inference generate "prompt" --max-tokens 128 --temperature 0.7 ``` ## Errors Failures carry a stable code, a hint, and a per-code reference. Recover by code and class, never by message text. ```bash $ strata ./my-db vector get missing k1 not_found.engine.vector_collection: vector collection does not exist (err_local_…) hint: Check that the requested branch, space, collection, graph, document, key, or model exists. ref: https://stratadb.org/e/not_found.engine.vector_collection ``` Full registry: [Error Reference](/docs/reference/error-reference) and [Error Handling](/docs/guides/error-handling). ## For agents ```bash strata agents guide # the full offline usage guide, version-matched strata agents commands --json # the machine-readable command catalog strata agents errors --json # the public error-code registry strata ./my-db mcp serve # Model Context Protocol over stdio ``` See [Agents and MCP](/docs/agents) and the [MCP Server Reference](/docs/agents/mcp-server). --- # CLI Reference Source: https://stratadb.org/docs/reference/cli > **Interim page.** Maintained by hand until it is generated from the resolved command index (IDL). Where this page and `strata agents commands --json` disagree, the command index wins. `strata` is a single binary. It opens one file-backed database — or an in-memory one — and runs commands against it. There is no server and no daemon. For the full list of commands, see the [Command Reference](/docs/reference/command-reference). This page covers how you invoke the binary itself. ## Invocation forms ```bash strata ./my-db kv put greeting hello # one-shot command against a durable database strata ./my-db # open the interactive REPL (on a TTY) strata --cache kv put greeting hello # one-shot against an ephemeral in-memory database strata --cache # REPL against an ephemeral database strata agents guide # a command that needs no database ``` A one-shot invocation runs a single command and exits. Passing a database path with no command opens the [REPL](#interactive-repl) when standard input is a terminal; when input is piped, `strata` reads one command per line instead. ## Targeting a database `strata` never opens the current directory implicitly. A command that touches data must name its target one of three ways, in priority order: 1. **A path** — the positional argument or `--db `. Always wins. A relative or absolute directory; it is created if it does not exist. 2. **`STRATA_DB=`** — an environment variable, used when no path is passed. 3. **`--cache`** — an explicit in-memory database. Nothing is persisted. Cannot be combined with a path or `--db`. A data command with no target refuses: ```bash $ strata ping error: [invalid_argument.cli.no_database]: no database specified hint: pass a path (strata ./mydb kv put …), set STRATA_DB, or use --cache for ephemeral ``` A handful of commands need no database at all — `strata init`, `strata agents guide`, `strata config path`, and the like. See [Database Configuration](/docs/guides/configuration) for what durable and cache mode mean, and [Durability](/docs/concepts/durability) for the underlying model. ## Global options These appear before the command. `--branch` and `--space` are also accepted after any command that operates on data, so either position works. | Option | Description | |--------|-------------| | `[DB]` | Positional durable database path | | `--db ` | Durable database path. Cannot be combined with the positional path | | `--cache` | Use an in-memory cache database for this process | | `--branch ` | Default branch for commands that accept a branch | | `--space ` | Product space for commands that accept a space | | `--json` | Emit compact JSON | | `--raw` | Emit script-friendly raw output where possible | | `-h, --help` | Print help | | `-V, --version` | Print the version | Branches and spaces are the two organizing dimensions of a database. See [Branches](/docs/concepts/branches), [Branch Management](/docs/guides/branching-workflows), and [Spaces](/docs/guides/spaces). ## Output formats Every command emits one of three shapes, chosen by the global flag. ### Human (default) Readable output. Stored bytes are decoded to text when they are valid UTF-8. ```bash $ strata ./my-db kv put greeting hello created greeting applied=true $ strata ./my-db kv get greeting hello ``` ### `--json` One compact envelope per command, shaped `{"type": …, "data": …}`. KV keys and values, and continuation cursors, are base64 strings on the wire. ```bash $ strata --json ./my-db kv get greeting {"data":{"timestamp":3,"value":"aGVsbG8=","version":3},"type":"kv_versioned_value"} ``` Failures are also envelopes, printed on stderr with a non-zero exit: ```bash $ strata --json ./my-db vector get missing k1 {"error":{"class":"not_found","code":"not_found.engine.vector_collection","retryable":false,"message":"vector collection does not exist","docs_url":"https://stratadb.org/e/not_found.engine.vector_collection", …}} ``` ### `--raw` Bare values, for scripts and pipelines. ```bash $ strata --raw ./my-db kv get greeting hello ``` Continuation cursors are opaque base64 tokens. Pass a printed cursor back verbatim through `--cursor` to fetch the next page. Time-travel reads take `--as-of `, where the value is the commit clock from a write receipt (`data.commit.timestamp`, a small integer), not a wall-clock time; see [Commits](/docs/concepts/commits). ## Command families Every command belongs to a family. The [Command Reference](/docs/reference/command-reference) lists them all. | Command | Description | |---------|-------------| | `init` | Prepare the Strata home directory and print next steps | | `doctor` | Check the installation and, when a database is targeted, its health | | `agents` | Self-describing surface for agents: guide, catalogs, repo onboarding | | `mcp` | Model Context Protocol server commands | | `ping` | Lightweight liveness check | | `info` | Print database information | | `health` | Print health facts | | `metrics` | Print metrics facts | | `describe` | Print a compact database description | | `config` | Configuration reads | | `remote` | Show where this database was cloned from (its remote origin) | | `clone` | Clone a dataset from a hub into a new local database | | `branch` | Branch lifecycle commands | | `space` | Product space commands | | `kv` | KV commands | | `json` | JSON document commands | | `vector` | Vector commands | | `event` | Event log commands | | `graph` | Graph core commands | | `arrow` | Arrow import/export commands | | `inference` | Model execution: local GGUF models and cloud providers | | `command` | Raw serialized executor command | ## Interactive REPL Opening a database with no command on a terminal starts the REPL. The prompt shows the current branch and space: ```text strata:default/default> ``` Each line is a command in the same grammar as the one-shot form — `kv put a 1`, `branch list`, `vector query docs "[0.1,0.2]" -k 5`. Lines beginning with `#` are ignored. A few words are handled by the REPL itself rather than as database commands: | Word | Effect | |------|--------| | `use ` | Switch the current branch (validated to exist) | | `use /` or `use ` | Switch branch and space | | `help` | Print the full command help | | `clear` | Clear the screen | | `quit` / `exit` | Leave the REPL | `Ctrl-D` also exits. History is written to `~/.strata_history` (override with `STRATA_HISTORY`). ## Commands from the old CLI Several verbs from the pre-V1 CLI are recognized but not part of the V1 surface. They refuse with a clear message rather than being silently unknown: ```bash $ strata --cache txn error: `txn` is recognized from the old CLI, but is not available in the V1 CLI surface yet ``` The recognized-but-refused verbs are `begin`, `commit`, `rollback`, `txn`, `search`, `recipe`, `flush`, `compact`, `up`, `down`, and `uninstall`. In V1 writes auto-commit, so there are no explicit transaction verbs; there is no state-cell capability. ## See also - [Command Reference](/docs/reference/command-reference) — every command and its syntax. - [API Quick Reference](/docs/reference/api-quick-reference) — the common operation per capability. - [Configuration Reference](/docs/reference/configuration-reference) — database and hub configuration. - [Error Reference](/docs/reference/error-reference) — the error model. - [Agents and MCP](/docs/agents) — the self-describing surface and MCP server. --- # Command Reference Source: https://stratadb.org/docs/reference/command-reference > **Interim page.** Maintained by hand until it is generated from the resolved command index (IDL). Where this page and `strata agents commands --json` disagree, the command index wins. Every command the `strata` CLI accepts, grouped by family. For how to invoke the binary — targeting a database, global options, output formats — see the [CLI Reference](/docs/reference/cli). For the one-per-capability cheat sheet, see the [API Quick Reference](/docs/reference/api-quick-reference). ## Conventions - `` is required; `[ARG]` is optional; `...` takes one or more values. - Every command also accepts the global flags `--branch`, `--space`, `--json`, `--raw`, and `-h/--help`. They are omitted from the tables below. - Reads that support time travel accept `--as-of ` — the commit clock value from a write receipt (`data.commit.timestamp`, a small integer), not a wall-clock time. - Paginated lists accept `--cursor ` and `--limit `; pass a printed cursor back verbatim. - Arguments that take a value can read it from a file: `@path` inline, or `-f/--file `. - Writes auto-commit. There are no transaction verbs and no state-cell capability in this surface. The five data capabilities are KV, JSON, event log, vector, and graph. Branches and product spaces are the organizing dimensions layered over all of them. ## Setup and diagnostics | Syntax | Description | |--------|-------------| | `strata init` | Prepare the Strata home directory and print next steps. Needs no database. | | `strata doctor` | Check the installation and, when a database is targeted, its health. Exits non-zero on issues. | ## Database facts | Syntax | Description | |--------|-------------| | `strata ping` | Lightweight liveness check. Prints `pong` and the version. | | `strata info` | Print database information: branch and space counts, target, durability. | | `strata health` | Print health facts for the branch catalog, space catalog, registry, and identity. | | `strata metrics` | Print metrics facts: control status, counts, durability. | | `strata describe` | Print a compact database description: capabilities, primitive counts, branches, spaces. | ## Configuration | Syntax | Description | |--------|-------------| | `strata config get` | Print sanitized config. | | `strata config get-key ` | Print one sanitized config value (`hub.url` reads the user config). | | `strata config set ` | Set a user-config key (`hub.url`) in the global strata config. | | `strata config unset ` | Remove a user-config key from the global config. | | `strata config path` | Print the global strata config file path. | | `strata config show` | Print the resolved hub configuration and which layer supplied it. | See the [Configuration Reference](/docs/reference/configuration-reference) and [Database Configuration](/docs/guides/configuration). ## Cloning | Syntax | Description | |--------|-------------| | `strata clone [DEST]` | Clone a dataset from a hub into a new local database. `--branch ` selects the branch to fetch; `--hub ` overrides the hub URL. `DEST` defaults to `./.strata`. | | `strata remote` | Show where this database was cloned from. `origin` is null when the database was not cloned. | See [Cloning Datasets](/docs/guides/cloning-datasets). ## Agents | Syntax | Description | |--------|-------------| | `strata agents guide` | Print the complete offline usage guide (markdown, version-matched). | | `strata agents commands` | Print the machine-readable command catalog. | | `strata agents errors` | Print the public error-code registry. | | `strata agents init` | Write repo onboarding files (`.strata/AGENTS.md`); `--apply` appends a pointer block to the repo's `AGENTS.md` or `CLAUDE.md`. | ## MCP | Syntax | Description | |--------|-------------| | `strata mcp serve` | Serve MCP over stdio (newline-delimited JSON-RPC; logs on stderr). | See [Agents and MCP](/docs/agents) and the [MCP Server Reference](/docs/agents/mcp-server). ## Branch | Syntax | Description | |--------|-------------| | `strata branch list` | List branches. | | `strata branch get ` | Read one branch. | | `strata branch create ` | Create an empty root branch. | | `strata branch fork ` | Fork a branch. `--version ` or `--timestamp ` forks from a retained source point. | | `strata branch delete ` | Delete a branch. | See [Branches](/docs/concepts/branches) and [Branch Management](/docs/guides/branching-workflows). ## Space | Syntax | Description | |--------|-------------| | `strata space list` | List spaces. | | `strata space create ` | Create a space. | | `strata space exists ` | Check whether a space exists. | | `strata space delete ` | Delete a space. `--force` deletes visible data in the space first. | See [Spaces](/docs/guides/spaces). ## KV | Syntax | Description | |--------|-------------| | `strata kv put [VALUE]` | Write one key. `-f/--file` or `@path` reads value bytes from a file. | | `strata kv get ` | Read one key. | | `strata kv delete ` | Delete one key. | | `strata kv list` | List keys. `--prefix`. | | `strata kv scan` | Scan rows with values and version facts. `--start`. | | `strata kv exists ` | Check key existence. | | `strata kv history ` | Read version history. | | `strata kv count` | Count keys. `--prefix`. | | `strata kv sample` | Sample rows. `--prefix`, `--count`. | See [KV Store](/docs/data/key-value). ## JSON | Syntax | Description | |--------|-------------| | `strata json set [VALUE]` | Set a JSON path (`$` is the document root). Non-JSON text is stored as a string. `-f/--file` or `@path`. | | `strata json get ` | Read a JSON path. | | `strata json delete ` | Delete a JSON path. | | `strata json list` | List JSON document keys. `--prefix`. | | `strata json exists ` | Check whether a document exists. | | `strata json history ` | Read document history. | | `strata json count` | Count documents. `--prefix`. | | `strata json sample` | Sample documents. `--prefix`, `--count`. | ### JSON secondary indexes | Syntax | Description | |--------|-------------| | `strata json index create ` | Create an index. `--index-type ` (default `tag`). | | `strata json index drop ` | Drop an index. | | `strata json index list` | List indexes. | See [JSON Store](/docs/data/json). ## Vector ### Collections | Syntax | Description | |--------|-------------| | `strata vector collection create ` | Create a collection. `--metric ` (default `cosine`). | | `strata vector collection delete ` | Delete a collection. | | `strata vector collection list` | List collections. | | `strata vector collection stats ` | Read collection stats. | ### Vectors | Syntax | Description | |--------|-------------| | `strata vector upsert [VECTOR]` | Upsert one vector (JSON array, comma-separated floats, or `@path`). `--metadata`/`--metadata-file` attaches metadata. | | `strata vector get ` | Read one vector. | | `strata vector history ` | Read vector history. | | `strata vector exists ` | Check vector existence. | | `strata vector keys ` | List vector keys. `--prefix`. | | `strata vector update-metadata [PATCH]` | Patch vector metadata (top-level patch JSON or `@path`). | | `strata vector delete ` | Delete one vector. | | `strata vector delete-all ` | Delete all vectors in a collection. | | `strata vector delete-by-filter ` | Delete vectors matching a metadata filter. `--filter`/`--filter-file`. | | `strata vector query [QUERY]` | Search vectors. `-k/--k` (default 10), `--filter`/`--filter-file`, `--diagnostics`. | | `strata vector count ` | Count vectors. | See [Vector Store](/docs/data/vectors). ## Event | Syntax | Description | |--------|-------------| | `strata event append [PAYLOAD]` | Append one event (payload JSON or `@path`; `-f/--file`). | | `strata event get ` | Read one event. Sequences start at 0. | | `strata event exists ` | Check event existence. | | `strata event count` | Count visible events. | | `strata event list` | List events. `--event-type`, `--limit`, `--after-sequence`. | | `strata event types` | List event types. | | `strata event by-type ` | List events by type. `--limit`, `--after-sequence`. | | `strata event range ` | Read an event sequence range. `--end-seq`, `--limit`, `--direction `, `--event-type`. | | `strata event range-time ` | Read events by timestamp range. `--end-ts`, `--limit`, `--direction`, `--event-type`. | | `strata event verify-chain` | Verify sequence density and hash linkage. | See [Event Log](/docs/data/events). ## Graph ### Core | Syntax | Description | |--------|-------------| | `strata graph create ` | Create a graph. | | `strata graph delete ` | Delete a graph. | | `strata graph list` | List graphs. | | `strata graph meta ` | Read graph metadata. | | `strata graph add-node ` | Add or replace a node. `--properties`/`--properties-file`, `--type `. | | `strata graph get-node ` | Read a node. | | `strata graph remove-node ` | Remove a node. | | `strata graph list-nodes ` | List nodes. `--prefix`. | | `strata graph add-edge ` | Add or replace an edge. `--weight`, `--properties`/`--properties-file`. | | `strata graph get-edge ` | Read an edge. | | `strata graph remove-edge ` | Remove an edge. | | `strata graph neighbors ` | List neighbors. `--direction `, `--edge-type`. | | `strata graph nodes-by-type ` | List nodes declaring an object type. | ### Ontology | Syntax | Description | |--------|-------------| | `strata graph ontology define-object-type ` | Define (or, while draft, redefine) an object type. `--properties`/`--properties-file`. | | `strata graph ontology define-link-type ` | Define a link type. `--cardinality`, `--properties`/`--properties-file`. | | `strata graph ontology delete-object-type ` | Delete a draft object type. | | `strata graph ontology delete-link-type ` | Delete a draft link type. | | `strata graph ontology freeze ` | Freeze the ontology; writes then validate against it. | | `strata graph ontology get ` | Read the ontology (status plus every declared type). | | `strata graph ontology summary ` | Read the ontology with per-type usage counts. | ### Analytics and traversal | Syntax | Description | |--------|-------------| | `strata graph wcc ` | Compute weakly connected components. | | `strata graph lcc ` | Compute local clustering coefficients. | | `strata graph sssp ` | Compute shortest-path distances from a source node. `--direction`. | | `strata graph pagerank ` | Compute pagerank importance scores. `--damping`, `--max-iterations`, `--tolerance`, `--personalization`. | | `strata graph cdlp ` | Detect communities via label propagation. `--max-iterations`, `--direction`. | | `strata graph bulk-insert ` | Ingest nodes and edges from JSON in chunked commits. `--data`/`--file`, `--chunk-size`. | | `strata graph bfs ` | Run a bounded breadth-first traversal. `--max-depth`, `--max-nodes`, `--edge-type` (repeatable), `--direction`. | See [Graph](/docs/data/graph). ## Arrow | Syntax | Description | |--------|-------------| | `strata arrow import --target ` | Import an Arrow-compatible file. `--format `, `--key-column`, `--value-column`, `--collection`. | | `strata arrow export --primitive --format ` | Export a primitive to a file. `--prefix`, `--limit`, `--collection`, `--graph`, `--event-type`. Graph exports use `` as a stem for node and edge files. | See [Arrow](/docs/guides/import-export). ## Inference ### Models | Syntax | Description | |--------|-------------| | `strata inference models list` | List catalog models. | | `strata inference models local` | List locally available models. | | `strata inference models pull ` | Download a model into the local model directory. Honors `STRATA_MODELS_DIR`, `STRATA_HF_ENDPOINT`, and `STRATA_HF_TOKEN`/`HF_TOKEN`. | ### Execution | Syntax | Description | |--------|-------------| | `strata inference capability ` | Show capability facts for one model spec. | | `strata inference generate ` | Generate text. `--max-tokens`, `--temperature`, `--top-k`, `--top-p`, `--seed`, `--stop` (repeatable), `--stop-token`, `--grammar`. | | `strata inference tokenize ` | Tokenize text with a local model. `--special`. | | `strata inference detokenize ...` | Detokenize token ids with a local model. | | `strata inference embed ` | Embed one text. | | `strata inference embed-batch ...` | Embed multiple texts in order. | | `strata inference rank ...` | Rank passages against a query. | | `strata inference unload [MODEL]` | Unload one cached model, or all cached models when the spec is omitted. | | `strata inference cache-status` | Show runtime model-cache diagnostics. | See [Inference](/docs/inference). ## Raw command escape hatch The programmatic path: build a command as wire JSON and run it. On the wire, keys and values are base64, and command names use the catalog spelling (`strata agents commands --json`), not the CLI verb spelling. | Syntax | Description | |--------|-------------| | `strata command run` | Execute a serialized executor command. `--command-json ` or `--file `. | | `strata command print` | Validate and print a serialized executor command without opening a database. `--command-json` or `--file`. | ```bash strata ./my-db command run --command-json '{"type":"kv_get","key":"a2V5"}' ``` ## Wire-only commands (batches) The command index includes wire-level commands the CLI does not expose as subcommands — the batch operations `kv batch-put`, `kv batch-get`, `kv batch-delete`, `kv batch-exists`, `vector batch-upsert`, `vector batch-get`, `vector batch-delete`, and their peers. There is no `strata kv batch-put` verb: ```bash $ strata ./my-db kv batch-put error: unrecognized subcommand 'batch-put' ``` Run them through the escape hatch above (or over MCP). For example, writing two KV keys (`a`→`1`, `b`→`2`) in one commit: ```bash strata ./my-db command run --command-json \ '{"type":"kv_batch_put","entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}]}' ``` ## Machine catalog coverage `strata agents commands --json` is the authoritative catalog. Today it carries full metadata for 32 commands across the KV and vector families, including the batch operations above. When this page and the catalog disagree, the catalog wins. This page documents 117 CLI commands in total. --- # Comparisons Source: https://stratadb.org/docs/why-strata/comparisons StrataDB borrows its shape — embedded, single-file-ish, zero-config — from SQLite and DuckDB, and its branching model from git. It is not a drop-in replacement for any of the systems below; it occupies a different point in the design space. Here is where it overlaps and where it differs. ## At a glance | System | Shape | Overlap with StrataDB | Where they differ | |--------|-------|---------------------|-------------------| | **SQLite** | Embedded relational | In-process, single-directory, zero-config | SQLite is relational with SQL and joins; StrataDB is multi-model with branches and time travel, and is not a SQL database | | **DuckDB** | Embedded analytical (OLAP) | In-process, embedded, columnar via [Arrow](/docs/guides/import-export) import/export | DuckDB is built for analytical SQL over columnar data; StrataDB is built for branched, versioned operational state across five primitives | | **Redis** | In-memory data structures, networked | KV and structured values, a fast in-memory ([cache](/docs/concepts/durability)) mode | Redis is a networked server shared across processes; StrataDB is embedded with no server, and adds durable branches and history | | **Postgres** | Client-server relational | Durable, structured data; JSON support | Postgres is a full relational server; StrataDB is embedded, non-relational, and branch/versioned. Use Postgres for primary relational data | | **Vector databases** (Pinecone, Chroma, LanceDB, …) | Similarity search | Vector collections with metadata filters and similarity [query](/docs/data/vectors) | Dedicated vector DBs specialize in scale and index tuning; StrataDB puts vectors alongside KV, JSON, events, and graph on one branched substrate | ## The through-line Every other system on that list does one shape well. StrataDB's bet is different: put several shapes on **one branch-aware, versioned substrate**, so isolation and history are properties you get everywhere at once instead of per-integration. That is the trade — you gain branches and time travel across five primitives, and you give up the depth a single-purpose engine has in its niche (a mature SQL planner, a networked cache, a purpose-built vector index at massive scale). ## Choosing in practice - Need **SQL, joins, relational integrity**? Use SQLite (embedded) or Postgres (server). StrataDB complements them for the multi-model, branched slice. - Need **analytical queries over big columnar data**? Use DuckDB. Move data between the two with [Arrow](/docs/guides/import-export). - Need a **shared cache across processes/machines**? Use Redis. StrataDB's [cache mode](/docs/concepts/durability) is in-process, not networked. - Need **billion-scale, heavily-tuned vector search as the whole product**? A dedicated vector database will go deeper. Need vectors *alongside* documents, events, and a graph, branched together? That is StrataDB's lane. - Need **branch-isolated, versioned, multi-model state**? That is what StrataDB is for — see [When to use StrataDB](/docs/why-strata/when-to-use). For the honest boundaries of what StrataDB is *not*, see [When to use StrataDB](/docs/why-strata/when-to-use); for the FAQ versions of these questions, see the [FAQ](/docs/faq). --- # Reference Source: https://stratadb.org/docs/reference Precise, verified specifications for the `strata` binary and the database it opens. These pages describe exactly what the shipping CLI does. ## Pages - **[CLI](/docs/reference/cli)** — invoking `strata`: targeting a database, global options, output formats, and the interactive REPL. - **[Command Reference](/docs/reference/command-reference)** — every command in every family, with its syntax and a one-line description. - **[API Quick Reference](/docs/reference/api-quick-reference)** — a one-page cheat sheet of the most common operation per capability. - **[Configuration Reference](/docs/reference/configuration-reference)** — database options, durability, and the resolved hub configuration. - **[Error Reference](/docs/reference/error-reference)** — the error model and the public error-code registry. - **[Value Type Reference](/docs/reference/value-type-reference)** — the value types stored and returned across capabilities. The Model Context Protocol server now lives in [For AI agents](/docs/agents/mcp-server). The Node and Python SDKs are in progress; their references will be generated from the same command index that will eventually generate these pages. --- # What is StrataDB Source: https://stratadb.org/docs/why-strata StrataDB is an **embedded, multi-model database**. It runs inside your process against a local directory — one binary, one database directory, no server, in the same spirit as SQLite or DuckDB. What makes it different is what sits on top of that embedded core: **five data primitives on one versioned substrate, with git-style branches and time travel.** ## The one-screen version - **Five primitives, one database.** Key-value, JSON documents, an event log, vectors, and a graph — each a [primitive](/docs/concepts/primitives) you reach for by shape of data, all sharing a single branch-aware, versioned storage row. You do not stand up five systems; you open one directory. - **Git-style branches.** [Fork a branch](/docs/concepts/branches) and get an isolated line of data. Forks are zero-copy and O(1) — a fork shares its parent's data until you change something (copy-on-write) — so branching is cheap enough to do per experiment, per tenant, or per agent session. - **Time travel.** Every write is a [commit](/docs/concepts/commits) with a version and timestamp, and any read can travel back to an earlier commit with `--as-of`. History is a first-class read, not a backup you restore. - **Embedded, not a server.** No daemon, no port, no connection pool. Point the CLI (or an MCP client) at a directory and it opens in-process. See [the embedded architecture](/docs/concepts/embedded-architecture). - **Built for agents.** The binary describes itself and ships a Model Context Protocol server — an agent can enumerate every command and error, and drive the database over MCP, with no extra package. See [For AI agents](/docs/agents). StrataDB is written in Rust and licensed Apache-2.0. ## Why it exists Agent memory, experiment isolation, and replayable history all want the same three things: several data shapes in one place, cheap isolation you can throw away, and the ability to read the past exactly. Assembling that from a relational database, a cache, a vector store, and a bespoke audit log means four systems and the glue between them. StrataDB puts the four shapes on one substrate and makes isolation and history properties of the substrate itself — so branching a whole database, or reading every primitive as of a past commit, is one concept applied everywhere rather than four integrations. ## Is it for you? StrataDB is a complement to your primary datastore, not a replacement for it — keep Postgres for relational application data and Redis for a shared cache. Reach for StrataDB when branch-isolated, versioned, multi-model state is the point. The next two pages are the honest version of that fit: - **[When to use StrataDB](/docs/why-strata/when-to-use)** — the sweet spots and the boundaries, stated plainly. - **[Comparisons](/docs/why-strata/comparisons)** — how it sits next to SQLite, DuckDB, Redis, Postgres, and vector databases. Ready to try it? [Install](/docs/getting-started/installation) and open [your first database](/docs/getting-started/first-database). --- # When to use StrataDB Source: https://stratadb.org/docs/why-strata/when-to-use StrataDB is opinionated about what it is good at. This page is the honest version: where it fits, and where it does not. ## Good fits - **Agent memory and state.** An agent needs durable, structured memory it can branch per session and roll back when a path fails. KV and JSON for working state, an event log for the action history, vectors for recall, a graph for relationships — one database, isolated per session with a [branch](/docs/concepts/branches). - **Experiment isolation.** Fork the whole database, try a change, and discard the fork if it goes wrong — without copying data up front or touching the parent. Cheap [branches](/docs/concepts/branches) make "try it on a copy" the default, not a chore. - **Replayable history.** When you need to answer "what did this look like last Tuesday?" or replay an event stream deterministically, per-commit [time travel](/docs/concepts/time-travel) and a hash-linked [event log](/docs/data/events) give you the past as a first-class read. - **Multi-model in one place.** When a single workload genuinely spans key-value, documents, vectors, events, and relationships, keeping them on one substrate — branched and versioned together — beats gluing four systems together. - **Embedded and edge.** In-process, single-directory, no server to operate — a fit for local-first apps, CLIs, notebooks, and constrained environments where running a database daemon is not an option. ## Poor fits (use something else) - **Primary relational application data.** If your data is fundamentally relational and you need SQL, joins, and a mature query planner, use Postgres or SQLite. StrataDB complements a relational store; it does not replace one. - **A shared network cache.** StrataDB is embedded and in-process — there is **no server or network mode** in this line. For a cache shared across many processes or machines, use Redis. - **Cross-machine sync or fleet coordination.** A StrataDB database is a local directory. Sharing prepared datasets is done by [cloning from a hub](/docs/concepts/hub-and-clone); live multi-writer sync across machines is out of scope for this line. - **Merging divergent branches.** Branching is fork-and-replay, not fork-and-merge — there is no merge command. If your workflow depends on merging two independently-edited branches back together, StrataDB does not do that today. ## The honest boundaries A few capabilities are deliberately out of this line, so you are not surprised: - **No local model execution in the released binary.** Inference runs through cloud providers by default; local GGUF execution is a build-time feature. See [Inference](/docs/inference). - **No Node SDK yet.** The supported surfaces today are the `strata` CLI, its [MCP server](/docs/agents/mcp-server), and the [Python SDK](/docs/python) (`stratadb` on PyPI); a Node SDK is post-V1. - **No standalone search surface.** Vector similarity search is here; the broader search product and its optimizer are deferred. When a fit is marginal, the deciding question is usually: *do you need branch-isolated, versioned, multi-model state?* If yes, StrataDB earns its place alongside your primary store. If no, a single-purpose tool is probably simpler. See [Comparisons](/docs/why-strata/comparisons) for the head-to-head. --- # Read sanitized config Source: https://stratadb.org/docs/reference/admin/config Returns sanitized configuration facts: the open target, whether this open created the database, durability, and the default branch. Only allowlisted, non-sensitive facts are exposed; no filesystem paths, credentials, or provider keys are ever returned. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Read sanitized configuration facts. ### CLI ```console $ strata config get ``` ### Wire ```json {"type":"config_get"} ``` ## Parameters _No parameters._ ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) ## Invocation - CLI: `strata config get` - Wire type: `config_get` --- # Read one config value Source: https://stratadb.org/docs/reference/admin/config_key Returns one sanitized configuration value from the allowlist by key, or a null value when the key is not recognized. Only allowlisted, non-sensitive keys are served; an empty key is rejected with `invalid_argument.engine.config_key`. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read one configuration value by key, or nothing if unknown. ### CLI ```console $ strata config get-key missing ``` ### Wire ```json {"key":"missing","type":"configure_get_key"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `string` | yes | Config key. | ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`invalid_argument.engine.config_key`](https://stratadb.org/e/invalid_argument.engine.config_key) ## Invocation - CLI: `strata config get-key` - Wire type: `configure_get_key` --- # Describe database Source: https://stratadb.org/docs/reference/admin/describe Returns a compact description of the database for one branch: engine version, open target, the default and described branches, all active branches, the registered product spaces, per-primitive counts (KV, JSON, event, plus vector-collection and graph summaries), the sanitized config, and the available capabilities. The branch defaults to the handle branch when omitted. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Describe the database. ### CLI ```console $ strata describe ``` ### Wire ```json {"type":"describe"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) ## Invocation - CLI: `strata describe` - Wire type: `describe` --- # Error Reference Source: https://stratadb.org/docs/reference/error-reference > **Interim page.** Maintained by hand until it is generated from the resolved command index (IDL). Where this page and `strata agents commands --json` disagree, the command index wins. Strata errors are structured, not prose. Every failure carries a machine-readable **class**, a stable **code**, a **retry policy**, and a **commit outcome**. Match on those. The human-readable `message` is for logs and can change between builds — never assert on it. The complete registry of every code lives at [`/e/`](/e/). Each code has its own page at `https://stratadb.org/e/`. There are 204 codes. ## The two artifacts There are two places a code appears, with slightly different field names: - **The catalog** — `strata agents errors --json` lists every code with its documentation. Fields: `class`, `code`, `commit_outcome`, `retry_policy`, `message`, `hint`, `ref`. - **The runtime envelope** — a real failure emitted under `--json`. Fields: `class`, `code`, `retry_policy`, `retryable`, `commit_outcome`, `message`, `suggested_fix`, `docs_url`, `reference_id`. A real failing invocation: ```console $ strata --cache --json kv get missing-key --branch no-such-branch ``` ```json {"error":{ "class":"not_found", "code":"not_found.engine.branch", "retry_policy":"never", "retryable":false, "commit_outcome":"not_applicable", "message":"branch `no-such-branch` does not exist", "suggested_fix":"Check that the requested branch, space, collection, graph, document, key, or model exists.", "docs_url":"https://stratadb.org/e/not_found.engine.branch", "reference_id":"err_local_2d588bba_000001" }} ``` The process exits non-zero. The `reference_id` is unique per occurrence — quote it in bug reports; it is not a code. ### Envelope fields | Field | Meaning | |-------|---------| | `class` | The category to switch on. One of the 15 classes below. | | `code` | Stable identifier. Switch on this for exact handling; link users to its `/e/` page. | | `retry_policy` | Whether and how a retry could succeed. See below. | | `retryable` | Boolean convenience: `false` when `retry_policy` is `never`. | | `commit_outcome` | What happened to any pending write. See below. | | `message` | Human-readable summary. Not stable — do not parse. | | `suggested_fix` / `hint` | Actionable next step (runtime / catalog field name). | | `docs_url` / `ref` | The code's page under `/e/` (runtime / catalog field name). | | `reference_id` | Unique per occurrence, for correlating logs and reports. | ## Code shape Codes read left to right as `..`, where `area` is `engine` or `executor`: ```text not_found . engine . branch invalid_argument . engine . vector_dimension ``` Two families deviate, so **treat the `class` field as authoritative**, not the code's first segment: - **`data_loss.*` codes** report `class` `corruption` — the leading segment is the error family, not the class. - **Inference codes** are two-segment, `inference.` (for example `inference.provider_timeout`), and each maps to a general class such as `unavailable` or `access_denied`. ## Classes Every class present in `strata agents errors --json`, with its code count: | Class | Codes | Meaning | |-------|------:|---------| | `invalid_argument` | 96 | Request input is malformed or violates a field rule. | | `corruption` | 41 | Stored data failed an integrity or validation check. Includes the `data_loss.*` family. | | `failed_precondition` | 27 | The database or environment is not in a state where the operation can proceed (layout version, embedding-model mismatch, missing model or API key). | | `unavailable` | 10 | A dependency is temporarily unreachable (control plane, model provider, artifact download). | | `not_found` | 7 | A named branch, space, collection, graph, document, key, or model does not exist. | | `already_exists` | 6 | Creating a resource whose name is already taken. | | `unsupported` | 4 | The operation or a parameter is not supported. | | `conflict` | 3 | A concurrent modification or branch-generation conflict. | | `internal` | 3 | An engine invariant broke — likely a bug. | | `resource_exhausted` | 2 | A budget or limit was reached (persistence budget, graph-analytics budget). | | `history_unavailable` | 1 | A requested historical version has been trimmed. | | `ambiguous_commit` | 1 | A write's outcome is indeterminate — see `commit_outcome`. | | `io` | 1 | An I/O operation failed. | | `access_denied` | 1 | Authentication or authorization failed (model provider). | | `serialization` | 1 | A provider response could not be deserialized. | ## Retry policy `retry_policy` says whether repeating the operation could help: | Value | Codes | Meaning | |-------|------:|---------| | `never` | 172 | Do not retry as sent. Fix the request or accept the failure. | | `after_state_change` | 20 | Retry only after changing something first — re-read the current version, supply a missing key, wait for a resource, correct a precondition. | | `same_request` | 5 | The failure is transient; the identical request may succeed on a later attempt (provider timeout, control-plane blip). | | `unknown` | 7 | The outcome is indeterminate; a retry may or may not help. Reconcile before assuming either way. | ## Commit outcome `commit_outcome` says what happened to any write the failed call was attempting: | Value | Codes | Meaning | |-------|------:|---------| | `not_started` | 115 | The write never began; nothing changed. Safe to retry from scratch. | | `not_applicable` | 84 | The operation has no commit (reads, catalog lookups, validation). | | `definitely_not_committed` | 4 | A write was attempted and definitively did not apply. Carried by branch-generation and persistence conflicts, persistence-budget exhaustion, and persistence preconditions. | | `maybe_committed` | 1 | The write may or may not have applied. You must reconcile state before assuming success. Carried only by `ambiguous_commit.engine.persistence`. | ## Reads: absence is not an error A read for something that does not exist returns an empty result with a zero exit code — it is not a failure. This holds across capabilities: ```console $ strata --cache --json kv get missing-key {"data":null,"type":"kv_versioned_value"} $ strata --db ./db --json json get user:1 '$.missing' {"data":{"found":false,"value":null},"type":"json_versioned_value"} $ strata --db ./db --json event get 999 {"data":null,"type":"event_record"} ``` Errors are reserved for invalid requests and genuine faults. A missing branch, collection, or graph named as the *target* of an operation does raise `not_found`. ## How to handle errors in code 1. Switch on `class` for broad handling (retry, surface, abort). 2. Switch on `code` when you need exact behavior, and link users to `docs_url`. 3. Consult `retry_policy` and `commit_outcome` before retrying a write. 4. Log `reference_id` and `message`; never branch on `message` text. For patterns and worked examples, see the [Error Handling guide](/docs/guides/error-handling). For the complete code registry, see [`/e/`](/e/). --- # Configuration Reference Source: https://stratadb.org/docs/reference/configuration-reference > **Interim page.** Maintained by hand until it is generated from the resolved command index (IDL). Where this page and `strata agents commands --json` disagree, the command index wins. Strata's configurable surface is deliberately small. There is one global config file with one user key, a handful of environment variables, and per-invocation flags. Everything below is verified against the binary. ## `strata config` verbs ```console $ strata config --help ``` | Verb | Purpose | |------|---------| | `strata config path` | Print the global config file path. | | `strata config show` | Print the resolved hub configuration and which layer supplied it. | | `strata config get` | Print the sanitized config. | | `strata config get-key ` | Print one sanitized value (`hub.url` reads the user config). | | `strata config set ` | Set a user-config key in the global config. | | `strata config unset ` | Remove a user-config key from the global config. | ## Config file `strata config path` reports the file location, which honors `XDG_CONFIG_HOME`: ```console $ strata config path {"path":"/home/you/.config/strata/config.toml"} ``` `strata config set` writes TOML. After setting `hub.url` the file contains: ```toml [hub] url = "https://your-hub.example/" ``` The file is created on first `set`; `unset` removes the key. ## Known keys The only user-config key in this release is `hub.url` — the address of the dataset hub used by `strata clone`. `strata config show` reports the resolved value and its source: ```console $ strata config show {"hub.url":"https://hub.stratahub.io/","source":"built-in default"} ``` No other user-writable config keys are exposed by the binary. Durability, cache sizing, and similar engine behavior are not surfaced as config-file keys on the CLI in this release — if you need them, drive the database through the SDK. ## Hub URL resolution The hub address is resolved from four layers, highest precedence first. `strata config show` names the winning layer in its `source` field. | Precedence | Layer | `source` shown | Notes | |-----------:|-------|----------------|-------| | 1 | `--hub ` flag | (per invocation) | On `strata clone`; overrides env and config files for that call. | | 2 | `STRATA_HUB_URL` env | `STRATA_HUB_URL` | Overrides the config file. | | 3 | Config file `hub.url` | the config file path | Set with `strata config set hub.url …`. | | 4 | Built-in default | `built-in default` | `https://hub.stratahub.io/`. | Observed precedence — the environment variable wins over the file: ```console $ STRATA_HUB_URL=https://env.example/ strata config show {"hub.url":"https://env.example/","source":"STRATA_HUB_URL"} ``` ## Environment variables Honored by the **binary**: | Variable | Effect | |----------|--------| | `STRATA_DB` | Default database path when no `[DB]` argument, `--db`, or `--cache` is given. The no-database error explicitly suggests it. | | `STRATA_HOME` | Overrides the Strata home directory that `strata init` prepares. | | `STRATA_HUB_URL` | Overrides the config-file hub address (layer 2 above). | | `XDG_CONFIG_HOME` | Relocates the config file (`$XDG_CONFIG_HOME/strata/config.toml`). | Honored by the **install script only** (not the binary): | Variable | Effect | |----------|--------| | `STRATA_VERSION` | Pin the version the installer downloads. | | `STRATA_INSTALL_DIR` | Choose where the installer places the binary. | ## Database open options (CLI) Every command opens a database through the top-level options: | Option | Meaning | |--------|---------| | `[DB]` (positional) | Durable database path. | | `--db ` | Durable database path. Cannot be combined with the positional form. | | `--cache` | Open an in-memory (non-durable) database for this process. | | `--branch ` | Default branch for commands that accept one. | | `--space ` | Product space for commands that accept one. | | `--json` | Emit compact JSON. | | `--raw` | Emit script-friendly raw output where possible. | A command with no durable path, no `--db`, no `--cache`, and no `STRATA_DB` refuses: ```console $ strata info error: [invalid_argument.cli.no_database]: no database specified hint: pass a path (strata ./mydb kv put …), set STRATA_DB, or use --cache for ephemeral ``` ## Could not verify - No config-file keys other than `hub.url` are exposed by the binary; durability mode is not a CLI config key in this release. - `STRATA_VERSION` and `STRATA_INSTALL_DIR` are installer variables and were not exercised here beyond their presence in the install script. ## See also - [Database Configuration guide](/docs/guides/configuration) — choosing durable vs. cache, and open options. - [Cloning Datasets guide](/docs/guides/cloning-datasets) — where `hub.url` and `--hub` are used. - [CLI Reference](/docs/reference/cli) and [Command Reference](/docs/reference/command-reference). - [Error Reference](/docs/reference/error-reference) — the structured error model. --- # Value Type Reference Source: https://stratadb.org/docs/reference/value-type-reference > **Interim page.** Maintained by hand until it is generated from the resolved command index (IDL). Where this page and `strata agents commands --json` disagree, the command index wins. Strata has five capabilities — **kv**, **json**, **event**, **vector**, and **graph** — over one branch-aware versioned store. This page shows what each one accepts and returns, verified by writing and reading each value. For the conceptual model see [Primitives](/docs/concepts/primitives) and [Value Types](/docs/concepts/value-types). Every write returns a commit receipt (`version`, `timestamp`, put/delete counts, `durable`, and an `effect`); reads return the value plus its `version` and `timestamp`. The `version`/`timestamp` pair is a logical commit clock, distinct from any wall-clock time stored inside a value. ## KV — opaque bytes KV values are opaque byte strings. Text from the CLI is stored as its UTF-8 bytes; arbitrary bytes come from a file (`--file` or `@path`). ```console $ strata --db ./db kv put greeting "hello world" created greeting applied=true $ strata --db ./db kv get greeting # plain: UTF-8 decoded hello world $ strata --db ./db --json kv get greeting # --json: value is base64 {"data":{"timestamp":3,"value":"aGVsbG8gd29ybGQ=","version":3},"type":"kv_versioned_value"} ``` Binary values round-trip byte-for-byte: ```console $ strata --db ./db kv put blob --file ./payload.bin created blob applied=true $ strata --db ./db --json kv get blob {"data":{"timestamp":4,"value":"AAEC/2Jpbg==","version":4},"type":"kv_versioned_value"} ``` Rules of thumb: - Under `--json`, both the key and the value are **base64** (they are bytes on the wire). - Plain and `--raw` output decode UTF-8 for display; non-text bytes are best read via `--json` and decoded by the caller. - A read of a missing key returns `{"data":null,...}` with exit 0 — absence is not an error. ## JSON — documents addressed by path JSON values are real JSON documents. Paths use `$` for the whole document and `$.field` for a member. Writing `$` replaces the document; a subpath read returns just that value. ```console $ strata --db ./db json set user:1 '$' '{"name":"Ada","age":36,"tags":["a","b"]}' created user:1 applied=true $ strata --db ./db json get user:1 '$' {"age":36,"name":"Ada","tags":["a","b"]} $ strata --db ./db --json json get user:1 '$.name' {"data":{"found":true,"value":{"document_version":1,"timestamp":3,"value":"Ada","version":3}},"type":"json_versioned_value"} ``` Documents carry a `document_version` (per-document revision) alongside the commit `version`/`timestamp`. Values may be any JSON type: object, array, string, number, boolean, or null. Non-JSON text passed to `json set` is stored as a JSON string. ## Event — immutable, hash-chained log Events are append-only. Each event has a string `event_type`, a JSON `payload`, a dense `sequence` starting at 0, a microsecond wall-clock `timestamp`, and a SHA-256 `hash` chained to the `previous_hash` of the prior event. ```console $ strata --db ./db event append user.created '{"id":1,"email":"a@b.co"}' created applied=true $ strata --db ./db --json event list ``` ```json {"data":{"items":[ {"event":{"event_type":"user.created","sequence":0, "payload":{"email":"a@b.co","id":1}, "hash":"1d2616c3…","previous_hash":"0000000000…", "timestamp":1783735353572894}, "version":3,"timestamp":3}, {"event":{"event_type":"user.updated","sequence":1, "payload":{"id":1}, "hash":"f331b047…","previous_hash":"1d2616c3…", "timestamp":1783735353581986}, "version":4,"timestamp":4} ],"has_more":false,"cursor":null},"type":"event_records"} ``` The genesis `previous_hash` is all zeros. Sequences are contiguous; `strata event verify-chain` checks density and hash linkage. Note the two clocks: the event's own `timestamp` is microsecond wall-clock; the outer `version`/`timestamp` is the logical commit clock. ## Vector — embeddings with a metric A collection fixes a `dimension` and a distance `metric`. Metrics accepted at create time: | Metric | Value | |--------|-------| | Cosine similarity (default) | `cosine` | | Euclidean | `euclidean` | | Dot product | `dot-product` | Vector components are 32-bit floats — values are stored and returned at `f32` precision (note the rounding below). Each vector may carry a metadata object. ```console $ strata --db ./db vector collection create docs 4 {"count":0,"dimension":4,"metric":"cosine","name":"docs"} $ strata --db ./db vector upsert docs a '[0.1,0.2,0.3,0.4]' --metadata '{"kind":"note"}' created a applied=true $ strata --db ./db --json vector get docs a {"data":{"data":{"embedding":[0.10000000149011612,0.20000000298023224,0.30000001192092896,0.4000000059604645], "metadata":{"kind":"note"}},"key":"a","vector_revision":1,"timestamp":5,"version":5},"type":"vector_data"} $ strata --db ./db --json vector query docs '[0.1,0.2,0.3,0.4]' --k 3 {"data":[{"key":"a","metadata":{"kind":"note"},"score":1.0}],"type":"vector_matches"} ``` Components can be a JSON array, comma-separated floats, or `@path`. A dimension mismatch is rejected: ```console $ strata --db ./db --json vector upsert docs b '[1,2]' {"error":{"class":"invalid_argument","code":"invalid_argument.engine.vector_dimension", "message":"vector dimension mismatch: expected 4, got 2", …}} ``` The collection create surface exposes `dimension` and `metric` only; there is no per-collection storage-dtype selection on the CLI in this release. Search filters are explicit and AND-composed, and **only equality is supported**. Each condition names a `field`, the op `eq`, and an adjacently-tagged scalar `value` (tag `string`, `number`, or `bool`): ```console $ strata --db ./db --json vector query docs '[0.1,0.9]' \ --filter '{"conditions":[{"field":"lang","op":"eq","value":{"type":"string","value":"en"}}]}' {"data":[{"key":"a","metadata":{"lang":"en"},"score":1.0}],"type":"vector_matches"} ``` A bare `{"lang":"en"}` is rejected (`missing field conditions`), and any op other than `eq` is rejected (`unknown variant …, expected eq`). ## Graph — nodes and typed edges A graph holds nodes (an id plus an optional properties object) and edges (a source, an `edge_type`, a destination, an optional `weight`, and optional properties). ```console $ strata --db ./db graph create deps $ strata --db ./db graph add-node deps core --properties '{"lang":"rust"}' $ strata --db ./db graph add-node deps cli $ strata --db ./db graph add-edge deps cli depends_on core --weight 2.5 $ strata --db ./db --json graph get-node deps core {"data":{"graph":"deps","node_id":"core","properties":{"lang":"rust"},"version":4,"timestamp":4},"type":"graph_node_result"} $ strata --db ./db --json graph get-edge deps cli depends_on core {"data":{"graph":"deps","src":"cli","edge_type":"depends_on","dst":"core","weight":2.5,"version":6,"timestamp":6},"type":"graph_edge_result"} ``` `graph neighbors` walks a node's edges with `direction` `outgoing` (default), `incoming`, or `both`, and returns each neighbor's edge and node together. Edge weight is optional; omit it for an unweighted edge. ## Write receipts Every mutating command returns the same receipt shape. A representative write under `--json`: ```json {"data":{ "commit":{"version":3,"timestamp":3,"put_count":1,"delete_count":0,"durable":false}, "effect":{"applied":true,"kind":"created","matched":false,"affected_count":1}, "key":"Z3JlZXRpbmc=" },"type":"write_result"} ``` `durable` reflects whether the commit reached disk (`false` in cache mode). `effect.kind` reports `created`, updated, or deleted; `applied` says whether the write changed anything. ## See also - Store guides: [KV](/docs/data/key-value), [JSON](/docs/data/json), [Vector](/docs/data/vectors), [Event Log](/docs/data/events). - [API Quick Reference](/docs/reference/api-quick-reference) and [CLI Reference](/docs/reference/cli). - [Error Reference](/docs/reference/error-reference) — the structured error model. --- # Read database health Source: https://stratadb.org/docs/reference/admin/health Returns control-plane health facts: the worst overall status plus per-subsystem status for identity, registry, branch catalog, and the optional branch-local space catalog. Also reports the default branch and active branch count. A healthy result means every required control-plane fact is present and readable. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Read control-plane health. ### CLI ```console $ strata health ``` ### Wire ```json {"type":"health"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) ## Invocation - CLI: `strata health` - Wire type: `health` --- # Clone hub dataset Source: https://stratadb.org/docs/reference/admin/hub_clone Clones a dataset from a hub into a new local database directory. Resolution, download, verification, reconstitution, and origin recording run once behind this command; the session database is not touched. The destination directory must not exist or must be empty. When the hub URL is not given, the layered resolver selects it from the flag, environment, and config layers. Status commands return a scalar or compact status payload and do not mutate database state. ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `dataset` | `string` | yes | Dataset to clone. | | `dest` | `string` | yes | Destination directory (must not exist, or be empty). | | `hub_url` | `string` | no | Explicit hub URL; when absent the 5-layer resolver runs (flag, `STRATA_HUB_URL`, project config, global config). | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`invalid_argument.executor.hub_dataset`](https://stratadb.org/e/invalid_argument.executor.hub_dataset) - [`invalid_argument.executor.hub_branch`](https://stratadb.org/e/invalid_argument.executor.hub_branch) - [`invalid_argument.executor.hub_feature_disabled`](https://stratadb.org/e/invalid_argument.executor.hub_feature_disabled) - [`invalid_argument.executor.hub_url`](https://stratadb.org/e/invalid_argument.executor.hub_url) - [`failed_precondition.executor.hub_clone`](https://stratadb.org/e/failed_precondition.executor.hub_clone) - [`unavailable.executor.hub_transport`](https://stratadb.org/e/unavailable.executor.hub_transport) ## Invocation - CLI: `strata clone` - Wire type: `hub_clone` --- # Read database info Source: https://stratadb.org/docs/reference/admin/info Returns database identity and a catalog summary for one branch: engine version, open target, whether this open created the database, durability, the default branch, the active branch count, and the registered space count for the selected branch. The branch defaults to the handle branch when omitted. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Read database identity and catalog counts. ### CLI ```console $ strata info ``` ### Wire ```json {"type":"info"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) ## Invocation - CLI: `strata info` - Wire type: `info` --- # admin commands Source: https://stratadb.org/docs/reference/admin # `admin` — command reference | Command | Summary | |---|---| | [Read sanitized config](/docs/reference/admin/config) | Read sanitized configuration facts. | | [Read one config value](/docs/reference/admin/config_key) | Read one sanitized configuration value by key. | | [Describe database](/docs/reference/admin/describe) | Read a compact description of the database. | | [Read database health](/docs/reference/admin/health) | Read control-plane health facts. | | [Clone hub dataset](/docs/reference/admin/hub_clone) | Clone a dataset from a hub into a new local database. | | [Read database info](/docs/reference/admin/info) | Read database identity and a catalog summary. | | [Read database metrics](/docs/reference/admin/metrics) | Read lightweight database metrics. | | [Ping database](/docs/reference/admin/ping) | Check that the database handle is live. | | [Read remote origin](/docs/reference/admin/remote) | Read where this database was cloned from. | --- # Read database metrics Source: https://stratadb.org/docs/reference/admin/metrics Returns lightweight database metrics: the open target, durability, whether the handle is open, the active branch count, the registered space count for the selected branch, and the control-plane health status. The branch defaults to the handle branch when omitted. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Read lightweight database metrics. ### CLI ```console $ strata metrics ``` ### Wire ```json {"type":"metrics"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) ## Invocation - CLI: `strata metrics` - Wire type: `metrics` --- # Ping database Source: https://stratadb.org/docs/reference/admin/ping Lightweight liveness check. Returns the engine package version without touching branches, spaces, or primitive data. Use it to confirm the handle is open and responsive before issuing heavier commands. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Check the database handle is live. ### CLI ```console $ strata ping ``` ### Wire ```json {"type":"ping"} ``` ## Parameters _No parameters._ ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) ## Invocation - CLI: `strata ping` - Wire type: `ping` --- # Export Arrow file Source: https://stratadb.org/docs/reference/arrow/export Exports a product primitive from the selected branch and space to an Arrow-compatible file (Parquet, CSV, or JSONL). Graph exports treat the path as a stem and write separate node and edge files. Returns a summary of the exported primitive, the concrete output paths, the row count, and the total output size. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Export a primitive to a Parquet file, then import it back. ### CLI ```console $ strata kv put greeting hello $ strata arrow export kv parquet /tmp/exports/kv.parquet # One file per primitive; Parquet by default. $ strata kv delete greeting $ strata arrow import /tmp/exports/kv.parquet kv $ strata kv get greeting ``` ### Wire ```json {"key":"Z3JlZXRpbmc=","type":"kv_put","value":"aGVsbG8="} {"format":"parquet","path":"/tmp/exports/kv.parquet","primitive":"kv","type":"arrow_export"} {"key":"Z3JlZXRpbmc=","type":"kv_delete"} {"file_path":"/tmp/exports/kv.parquet","target":"kv","type":"arrow_import"} {"key":"Z3JlZXRpbmc=","type":"kv_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | no | Target vector collection for vector exports. | | `event_type` | `string` | no | Optional event type filter for event exports. | | `format` | `ArrowFileFormat` | yes | Output file format. | | `graph` | `string` | no | Target graph for graph exports. | | `limit` | `integer` | no | Optional row limit. | | `path` | `string` | yes | Output file path. Graph exports treat this as a stem and return concrete node and edge paths. | | `prefix` | `string` | no | Optional key, document, vector-key, or node-id prefix. | | `primitive` | `ArrowExportPrimitive` | yes | Product primitive to export. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.executor.arrow_feature_disabled`](https://stratadb.org/e/invalid_argument.executor.arrow_feature_disabled) - [`invalid_argument.executor.arrow_format`](https://stratadb.org/e/invalid_argument.executor.arrow_format) - [`invalid_argument.executor.arrow_empty_export`](https://stratadb.org/e/invalid_argument.executor.arrow_empty_export) - [`invalid_argument.executor.arrow_value_column`](https://stratadb.org/e/invalid_argument.executor.arrow_value_column) - [`invalid_argument.executor.arrow_vector_key`](https://stratadb.org/e/invalid_argument.executor.arrow_vector_key) - [`invalid_argument.executor.arrow_graph`](https://stratadb.org/e/invalid_argument.executor.arrow_graph) - [`invalid_argument.executor.arrow_collection`](https://stratadb.org/e/invalid_argument.executor.arrow_collection) - [`unavailable.executor.arrow_io`](https://stratadb.org/e/unavailable.executor.arrow_io) - [`internal.executor.arrow`](https://stratadb.org/e/internal.executor.arrow) ## Invocation - CLI: `strata arrow export` - Wire type: `arrow_export` --- # Read remote origin Source: https://stratadb.org/docs/reference/admin/remote Reads the remote origin recorded when this database was cloned from a hub: the remote URL, dataset, branch, manifest hash, fetch time, and per-branch base frontier. Returns a null origin when the database was created locally and never cloned. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read where this database was cloned from (a local database has no origin). ### CLI ```console $ strata remote ``` ### Wire ```json {"type":"remote_get"} ``` ## Parameters _No parameters._ ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) ## Invocation - CLI: `strata remote` - Wire type: `remote_get` --- # Import Arrow file Source: https://stratadb.org/docs/reference/arrow/import Imports an Arrow-compatible file (Parquet, CSV, or JSONL) into a product primitive on the selected branch and space. Rows are written through the standard batch commands, so the import commits like any other write. Returns a summary of the target primitive, the input file, and the imported, skipped, and batch counts. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Import a primitive's rows from a Parquet file written by export. ### CLI ```console $ strata kv put greeting hello $ strata arrow export kv parquet /tmp/exports/kv.parquet $ strata kv delete greeting $ strata arrow import /tmp/exports/kv.parquet kv # Rows are keyed by their source column; kv restores greeting=hello. $ strata kv get greeting ``` ### Wire ```json {"key":"Z3JlZXRpbmc=","type":"kv_put","value":"aGVsbG8="} {"format":"parquet","path":"/tmp/exports/kv.parquet","primitive":"kv","type":"arrow_export"} {"key":"Z3JlZXRpbmc=","type":"kv_delete"} {"file_path":"/tmp/exports/kv.parquet","target":"kv","type":"arrow_import"} {"key":"Z3JlZXRpbmc=","type":"kv_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | no | Target vector collection for vector imports. | | `file_path` | `string` | yes | Input file path. | | `format` | `ArrowFileFormat` | no | Input file format. Defaults to extension detection. | | `key_column` | `string` | no | Optional key column override. | | `target` | `ArrowImportTarget` | yes | Product primitive to import into. | | `value_column` | `string` | no | Optional value, document, or embedding column override. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.executor.arrow_feature_disabled`](https://stratadb.org/e/invalid_argument.executor.arrow_feature_disabled) - [`invalid_argument.executor.arrow_format`](https://stratadb.org/e/invalid_argument.executor.arrow_format) - [`invalid_argument.executor.arrow_input_missing`](https://stratadb.org/e/invalid_argument.executor.arrow_input_missing) - [`invalid_argument.executor.arrow_key_column`](https://stratadb.org/e/invalid_argument.executor.arrow_key_column) - [`invalid_argument.executor.arrow_value_column`](https://stratadb.org/e/invalid_argument.executor.arrow_value_column) - [`invalid_argument.executor.arrow_collection`](https://stratadb.org/e/invalid_argument.executor.arrow_collection) - [`invalid_argument.executor.arrow_embedding_type`](https://stratadb.org/e/invalid_argument.executor.arrow_embedding_type) - [`invalid_argument.executor.arrow_vector_dimension`](https://stratadb.org/e/invalid_argument.executor.arrow_vector_dimension) - [`invalid_argument.executor.arrow_json_key`](https://stratadb.org/e/invalid_argument.executor.arrow_json_key) - [`invalid_argument.executor.arrow_base64`](https://stratadb.org/e/invalid_argument.executor.arrow_base64) - [`unavailable.executor.arrow_io`](https://stratadb.org/e/unavailable.executor.arrow_io) - [`internal.executor.arrow`](https://stratadb.org/e/internal.executor.arrow) ## Invocation - CLI: `strata arrow import` - Wire type: `arrow_import` --- # arrow commands Source: https://stratadb.org/docs/reference/arrow # `arrow` — command reference | Command | Summary | |---|---| | [Export Arrow file](/docs/reference/arrow/export) | Export a product primitive to an Arrow-compatible file. | | [Import Arrow file](/docs/reference/arrow/import) | Import an Arrow-compatible file into a product primitive. | --- # Delete branch Source: https://stratadb.org/docs/reference/branch/delete Deletes an active branch and reports the deleted branch summary, generation facts, and storage cleanup counts. The `default` branch refuses deletion with `invalid_argument.engine.branch_delete`. There is no merge in V1: work on a fork is either kept by continuing on that branch or discarded by deleting it. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete a branch. ### CLI ```console $ strata branch create temp $ strata branch delete temp $ strata branch list ``` ### Wire ```json {"branch":"temp","type":"branch_create"} {"branch":"temp","type":"branch_delete"} {"type":"branch_list"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) - [`invalid_argument.engine.branch_name_reserved`](https://stratadb.org/e/invalid_argument.engine.branch_name_reserved) - [`invalid_argument.engine.branch_delete`](https://stratadb.org/e/invalid_argument.engine.branch_delete) ## Invocation - CLI: `strata branch delete` - Wire type: `branch_delete` --- # Fork branch from current head Source: https://stratadb.org/docs/reference/branch/fork Forks a new branch from the source branch's current head. The new branch sees all data visible on the source at fork time; later writes on either branch stay isolated. The returned branch summary records the parent name, fork version, and generation. On the CLI, all three fork commands share the single verb `strata branch fork `: with no flags it runs this command, while `--version` routes to `branch.fork_at_version` and `--timestamp` routes to `branch.fork_at_timestamp` (both wire-surface commands). Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Fork a branch from another branch's head. ### CLI ```console $ strata branch fork default experiment $ strata branch list ``` ### Wire ```json {"branch":"experiment","source":"default","type":"branch_fork_current"} {"type":"branch_list"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `source` | `string` | yes | Source branch name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) - [`invalid_argument.engine.branch_name_reserved`](https://stratadb.org/e/invalid_argument.engine.branch_name_reserved) - [`already_exists.engine.branch`](https://stratadb.org/e/already_exists.engine.branch) ## Invocation - CLI: `strata branch fork` - Wire type: `branch_fork_current` --- # Create empty branch Source: https://stratadb.org/docs/reference/branch/create Creates an empty root branch with no parent and no data. This is not a fork: the new branch starts from nothing, and its `parent` is null. Use `branch.fork` to start from an existing branch's data. Creating a name that already exists fails with `already_exists.engine.branch`; names reserved for engine control data are rejected. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Create a new empty branch. ### CLI ```console $ strata branch create feature $ strata branch list ``` ### Wire ```json {"branch":"feature","type":"branch_create"} {"type":"branch_list"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) - [`invalid_argument.engine.branch_name_reserved`](https://stratadb.org/e/invalid_argument.engine.branch_name_reserved) - [`already_exists.engine.branch`](https://stratadb.org/e/already_exists.engine.branch) ## Invocation - CLI: `strata branch create` - Wire type: `branch_create` --- # Fork branch at timestamp Source: https://stratadb.org/docs/reference/branch/fork_at_timestamp Forks a new branch anchored at a retained source timestamp (microseconds, on Strata's logical commit clock). The engine resolves the timestamp to the covering retained commit; the returned parent lineage records both the fork timestamp and the resolved fork version. A timestamp outside retained history fails with `history_unavailable.engine.persistence_history`. This command has no dedicated CLI verb: the CLI expresses it as `strata branch fork --timestamp ` (one shared `branch fork` verb routes to all three fork commands, so only `branch.fork` owns the CLI path). It remains fully reachable through the generic wire surface — `strata command run`, MCP, and SDKs. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Fork a branch at an earlier commit timestamp — time-travel into a branch. ### CLI ```console $ strata kv put greeting original # The receipt carries this commit's timestamp (microseconds). $ strata kv put greeting updated $ strata command run --command-json '{"branch":"snapshot","source":"default","timestamp":3,"type":"branch_fork_at_timestamp"}' # snapshot forks default's history as of that instant. $ strata kv get greeting --branch snapshot ``` ### Wire ```json {"key":"Z3JlZXRpbmc=","type":"kv_put","value":"b3JpZ2luYWw="} {"key":"Z3JlZXRpbmc=","type":"kv_put","value":"dXBkYXRlZA=="} {"branch":"snapshot","source":"default","timestamp":3,"type":"branch_fork_at_timestamp"} {"branch":"snapshot","key":"Z3JlZXRpbmc=","type":"kv_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `source` | `string` | yes | Source branch name. | | `timestamp` | `integer` | yes | Source timestamp in microseconds. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) - [`invalid_argument.engine.branch_name_reserved`](https://stratadb.org/e/invalid_argument.engine.branch_name_reserved) - [`already_exists.engine.branch`](https://stratadb.org/e/already_exists.engine.branch) - [`history_unavailable.engine.persistence_history`](https://stratadb.org/e/history_unavailable.engine.persistence_history) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `branch_fork_at_timestamp` --- # Fork branch at version Source: https://stratadb.org/docs/reference/branch/fork_at_version Forks a new branch anchored at a retained commit version of the source branch, giving time-travel semantics: the new branch sees exactly the data visible at that version. A version outside retained history fails with `history_unavailable.engine.persistence_history`. This command has no dedicated CLI verb: the CLI expresses it as `strata branch fork --version ` (one shared `branch fork` verb routes to all three fork commands, so only `branch.fork` owns the CLI path). It remains fully reachable through the generic wire surface — `strata command run`, MCP, and SDKs. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Fork a branch at an earlier commit version — a snapshot of history. ### CLI ```console $ strata kv put greeting original # The receipt carries this commit's version. $ strata kv put greeting updated $ strata command run --command-json '{"branch":"snapshot","source":"default","type":"branch_fork_at_version","version":3}' # snapshot forks default's history at that version. $ strata kv get greeting --branch snapshot ``` ### Wire ```json {"key":"Z3JlZXRpbmc=","type":"kv_put","value":"b3JpZ2luYWw="} {"key":"Z3JlZXRpbmc=","type":"kv_put","value":"dXBkYXRlZA=="} {"branch":"snapshot","source":"default","type":"branch_fork_at_version","version":3} {"branch":"snapshot","key":"Z3JlZXRpbmc=","type":"kv_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `source` | `string` | yes | Source branch name. | | `version` | `integer` | yes | Source version. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) - [`invalid_argument.engine.branch_name_reserved`](https://stratadb.org/e/invalid_argument.engine.branch_name_reserved) - [`already_exists.engine.branch`](https://stratadb.org/e/already_exists.engine.branch) - [`history_unavailable.engine.persistence_history`](https://stratadb.org/e/history_unavailable.engine.persistence_history) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `branch_fork_at_version` --- # Read one branch Source: https://stratadb.org/docs/reference/branch/get Reads the summary for one branch: name, deterministic branch id, generation, status, parent lineage, and logical creation version. A branch that does not exist is a `not_found.engine.branch` error, not an empty result. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Read one branch by name. ### CLI ```console $ strata branch create feature $ strata branch get feature ``` ### Wire ```json {"branch":"feature","type":"branch_create"} {"branch":"feature","type":"branch_get"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.branch_name`](https://stratadb.org/e/invalid_argument.engine.branch_name) - [`invalid_argument.engine.branch_name_reserved`](https://stratadb.org/e/invalid_argument.engine.branch_name_reserved) ## Invocation - CLI: `strata branch get` - Wire type: `branch_get` --- # branch commands Source: https://stratadb.org/docs/reference/branch # `branch` — command reference | Command | Summary | |---|---| | [Create empty branch](/docs/reference/branch/create) | Create a new empty root branch. | | [Delete branch](/docs/reference/branch/delete) | Delete an active branch and release its storage claims. | | [Fork branch from current head](/docs/reference/branch/fork) | Fork a new branch from the current head of a source branch. | | [Fork branch at timestamp](/docs/reference/branch/fork_at_timestamp) | Fork a new branch from a retained source timestamp. | | [Fork branch at version](/docs/reference/branch/fork_at_version) | Fork a new branch from a retained source commit version. | | [Read one branch](/docs/reference/branch/get) | Read one branch summary by name. | | [List branches](/docs/reference/branch/list) | List active branches with their lineage facts. | --- # List branches Source: https://stratadb.org/docs/reference/branch/list Lists every active branch as a terminal page. Each item carries the branch name, deterministic branch id, generation, status, parent lineage (fork version and timestamp when forked), and logical creation version. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List branches. ### CLI ```console $ strata branch create feature $ strata branch list ``` ### Wire ```json {"branch":"feature","type":"branch_create"} {"type":"branch_list"} ``` ## Parameters _No parameters._ ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) ## Invocation - CLI: `strata branch list` - Wire type: `branch_list` --- # Append event Source: https://stratadb.org/docs/reference/event/append Appends one event to the selected branch and space. Strata assigns the next sequence number, stamps the event with its append timestamp, and links it into the tamper-evident hash chain. Events are immutable once appended. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Append an event to the log. ### CLI ```console $ strata event append user.created {"id":1} $ strata event count ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"type":"event_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `event_type` | `string` | yes | Event type. | | `payload` | `any` | yes | Event payload. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.event_type`](https://stratadb.org/e/invalid_argument.engine.event_type) - [`invalid_argument.engine.event_payload`](https://stratadb.org/e/invalid_argument.engine.event_payload) - [`invalid_argument.engine.event_payload_too_large`](https://stratadb.org/e/invalid_argument.engine.event_payload_too_large) ## Invocation - CLI: `strata event append` - Wire type: `event_append` --- # Batch append events Source: https://stratadb.org/docs/reference/event/batch_append Appends multiple events to the selected branch and space in one engine commit. Sequences are assigned in entry order. Entries that fail validation report a positional item error while valid entries still append. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Append many events in one commit. ### CLI ```console $ strata command run --command-json '{"entries":[{"event_type":"user.created","payload":{"id":1}},{"event_type":"user.updated","payload":{"id":2}}],"type":"event_batch_append"}' $ strata event count ``` ### Wire ```json {"entries":[{"event_type":"user.created","payload":{"id":1}},{"event_type":"user.updated","payload":{"id":2}}],"type":"event_batch_append"} {"type":"event_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `entries` | `BatchEventEntry[]` | yes | Events to append. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.event_batch`](https://stratadb.org/e/invalid_argument.engine.event_batch) - [`invalid_argument.engine.event_type`](https://stratadb.org/e/invalid_argument.engine.event_type) - [`invalid_argument.engine.event_payload`](https://stratadb.org/e/invalid_argument.engine.event_payload) - [`invalid_argument.engine.event_payload_too_large`](https://stratadb.org/e/invalid_argument.engine.event_payload_too_large) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `event_batch_append` --- # Count events Source: https://stratadb.org/docs/reference/event/count Counts events visible in the selected branch and space. The optional timestamp counts the events visible at that commit time. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Count the events in the log. ### CLI ```console $ strata event append user.created {"id":1} $ strata event append user.updated {"id":2} $ strata event count ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"event_type":"user.updated","payload":{"id":2},"type":"event_append"} {"type":"event_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) ## Invocation - CLI: `strata event count` - Wire type: `event_count` --- # Check event existence Source: https://stratadb.org/docs/reference/event/exists Checks whether one event sequence exists in the selected branch and space without returning the record. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Check whether an event sequence exists. ### CLI ```console $ strata event append user.created {"id":1} $ strata event exists 0 $ strata event exists 999 ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"sequence":0,"type":"event_exists"} {"sequence":999,"type":"event_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `sequence` | `integer` | yes | Event sequence. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) ## Invocation - CLI: `strata event exists` - Wire type: `event_exists` --- # event commands Source: https://stratadb.org/docs/reference/event # `event` — command reference | Command | Summary | |---|---| | [Append event](/docs/reference/event/append) | Append one event to the branch event log. | | [Batch append events](/docs/reference/event/batch_append) | Append multiple events in one commit. | | [Count events](/docs/reference/event/count) | Count visible events in the log. | | [Check event existence](/docs/reference/event/exists) | Check whether an event sequence exists. | | [Get event](/docs/reference/event/get) | Read one event by sequence number. | | [List events](/docs/reference/event/list) | List events with optional type filter and cursor. | | [Read event sequence range](/docs/reference/event/range) | Read a range of events by sequence number. | | [Read event time range](/docs/reference/event/range_time) | Read a range of events by occurrence time. | | [List event types](/docs/reference/event/types) | List distinct event types in the log. | | [Verify event chain](/docs/reference/event/verify_chain) | Verify event log density and hash linkage. | --- # Get event Source: https://stratadb.org/docs/reference/event/get Reads one event from the selected branch and space by sequence number. The optional timestamp reads the record visible at that commit time. The record carries its payload, append timestamp, and hash-chain facts. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read an event by its sequence number. ### CLI ```console $ strata event append user.created {"id":1} $ strata event get 0 $ strata event get 999 ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"sequence":0,"type":"event_get"} {"sequence":999,"type":"event_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `sequence` | `integer` | yes | Event sequence. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) ## Invocation - CLI: `strata event get` - Wire type: `event_get` --- # List events Source: https://stratadb.org/docs/reference/event/list Lists events from the selected branch and space in sequence order. An optional event type narrows the results, the sequence cursor continues a previous page, and the optional timestamp reads the log visible at that commit time. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List events in sequence order. ### CLI ```console $ strata event append user.created {"id":1} $ strata event append user.updated {"id":2} $ strata event list ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"event_type":"user.updated","payload":{"id":2},"type":"event_append"} {"type":"event_list"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `after_sequence` | `integer` | no | Optional exclusive sequence cursor. | | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `event_type` | `string` | no | Optional event type filter. | | `limit` | `integer` | no | Optional item limit. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.event_type`](https://stratadb.org/e/invalid_argument.engine.event_type) - [`invalid_argument.executor.limit`](https://stratadb.org/e/invalid_argument.executor.limit) ## Invocation - CLI: `strata event list` - Wire type: `event_list` --- # Read event sequence range Source: https://stratadb.org/docs/reference/event/range Reads events from the selected branch and space by sequence range. The start sequence is inclusive and the optional end sequence is exclusive; reverse direction walks backward from the start sequence. An optional event type narrows the results. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples Read a range of events by sequence. ### CLI ```console $ strata event append user.created {"id":1} $ strata event append user.updated {"id":2} $ strata event range 0 forward ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"event_type":"user.updated","payload":{"id":2},"type":"event_append"} {"direction":"forward","start_seq":0,"type":"event_range"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `direction` | `EventRangeDirection` | yes | Result ordering. | | `end_seq` | `integer` | no | Optional exclusive end sequence; with reverse direction, exclusive lower bound. | | `event_type` | `string` | no | Optional event type filter. | | `limit` | `integer` | no | Optional item limit. | | `start_seq` | `integer` | yes | Inclusive start sequence; with reverse direction, walk backward from this sequence. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.event_type`](https://stratadb.org/e/invalid_argument.engine.event_type) - [`invalid_argument.executor.limit`](https://stratadb.org/e/invalid_argument.executor.limit) ## Invocation - CLI: `strata event range` - Wire type: `event_range` --- # Read event time range Source: https://stratadb.org/docs/reference/event/range_time Reads events from the selected branch and space whose append timestamps fall inside an inclusive microsecond window. This queries when events occurred; historical log states are the timestamped read commands' job. An optional event type narrows the results. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples Read a range of events by timestamp. ### CLI ```console $ strata event append user.created {"id":1} $ strata event append user.updated {"id":2} $ strata event range-time 0 forward ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"event_type":"user.updated","payload":{"id":2},"type":"event_append"} {"direction":"forward","start_ts":0,"type":"event_range_by_time"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `direction` | `EventRangeDirection` | yes | Result ordering. | | `end_ts` | `integer` | no | Optional inclusive end timestamp in microseconds. | | `event_type` | `string` | no | Optional event type filter. | | `limit` | `integer` | no | Optional item limit. | | `start_ts` | `integer` | yes | Inclusive start timestamp in microseconds. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.event_type`](https://stratadb.org/e/invalid_argument.engine.event_type) - [`invalid_argument.executor.limit`](https://stratadb.org/e/invalid_argument.executor.limit) ## Invocation - CLI: `strata event range-time` - Wire type: `event_range_by_time` --- # List event types Source: https://stratadb.org/docs/reference/event/types Lists the distinct event types visible in the selected branch and space in sorted order. The optional timestamp lists the types visible at that commit time. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List the distinct event types seen in the log. ### CLI ```console $ strata event append user.created {"id":1} $ strata event append user.updated {"id":2} $ strata event types ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"event_type":"user.updated","payload":{"id":2},"type":"event_append"} {"type":"event_list_types"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) ## Invocation - CLI: `strata event types` - Wire type: `event_list_types` --- # Apply graph delete policy Source: https://stratadb.org/docs/reference/graph/apply_delete_policy Applies an explicit policy to every graph node bound to the given entity target: `cascade` deletes the bound nodes and their incident edges, `detach` keeps the nodes but removes their bindings, and `keep_dangling` preserves the bindings so traversal can report the target's status. The acknowledgement reports how many bound nodes the policy covered. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Cascade-delete graph facts bound to an entity. ### CLI ```console $ strata graph create kb $ strata graph add-node kb ada --binding {"target":{"key":"user:1","primitive":"kv","space":"default"}} $ strata command run --command-json '{"policy":"cascade","target":{"key":"user:1","primitive":"kv","space":"default"},"type":"graph_apply_delete_policy"}' # cascade removes the bound node and its incident edges. $ strata graph get-node kb ada ``` ### Wire ```json {"graph":"kb","type":"graph_create"} {"binding":{"target":{"key":"user:1","primitive":"kv","space":"default"}},"graph":"kb","node_id":"ada","type":"graph_add_node"} {"policy":"cascade","target":{"key":"user:1","primitive":"kv","space":"default"},"type":"graph_apply_delete_policy"} {"graph":"kb","node_id":"ada","type":"graph_get_node"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `policy` | `GraphDeletePolicy` | yes | Policy to apply: `cascade`, `detach`, or `keep_dangling`. | | `target` | `GraphBindingTarget` | yes | The bound entity target. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_binding`](https://stratadb.org/e/invalid_argument.engine.graph_binding) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `graph_apply_delete_policy` --- # Verify event chain Source: https://stratadb.org/docs/reference/event/verify_chain Verifies that the visible event log in the selected branch and space is dense and hash-linked: sequences are contiguous from zero, the genesis record links to the all-zeros hash, and every record's hash matches its content and predecessor. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Verify the integrity of the event hash chain. ### CLI ```console $ strata event append user.created {"id":1} $ strata event verify-chain ``` ### Wire ```json {"event_type":"user.created","payload":{"id":1},"type":"event_append"} {"type":"event_verify_chain"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) ## Invocation - CLI: `strata event verify-chain` - Wire type: `event_verify_chain` --- # Batch write graph Source: https://stratadb.org/docs/reference/graph/batch_write Applies a list of graph operations - `upsert_node`, `delete_node`, `upsert_edge`, `delete_edge` - in one engine commit. Validation failures (bad ids, missing edge endpoints, frozen-ontology violations) reject the whole batch; nothing is partially applied. The response reports one positional item result per operation, all sharing the same commit receipt. Atomic batches validate every operation up front and apply all of them in one engine commit, or none at all. The response still reports one positional item result per operation; all item results share the same commit receipt. ## Examples Apply several node and edge mutations in one atomic commit. ### CLI ```console $ strata graph create g $ strata command run --command-json '{"graph":"g","operations":[{"data":{"object_type":"person"},"node_id":"a","type":"upsert_node"},{"data":{"object_type":"person"},"node_id":"b","type":"upsert_node"},{"data":{},"dst":"b","edge_type":"knows","src":"a","type":"upsert_edge"}],"type":"graph_batch_write"}' # All operations land in one engine commit, or none do. $ strata graph meta g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","operations":[{"data":{"object_type":"person"},"node_id":"a","type":"upsert_node"},{"data":{"object_type":"person"},"node_id":"b","type":"upsert_node"},{"data":{},"dst":"b","edge_type":"knows","src":"a","type":"upsert_edge"}],"type":"graph_batch_write"} {"graph":"g","type":"graph_get_meta"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | | `operations` | `GraphBatchOperation[]` | yes | Batch operations. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_batch`](https://stratadb.org/e/invalid_argument.engine.graph_batch) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_edge_type`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type) - [`invalid_argument.engine.graph_edge_endpoint`](https://stratadb.org/e/invalid_argument.engine.graph_edge_endpoint) - [`failed_precondition.engine.graph_ontology_node_type`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_node_type) - [`failed_precondition.engine.graph_ontology_edge_type`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_edge_type) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `graph_batch_write` --- # List graph bindings for entity Source: https://stratadb.org/docs/reference/graph/bindings Searches every graph in the selected branch and space for nodes whose entity binding matches the given target (primitive, space, key). This is the reverse index of node bindings: given an entity, find the graph facts attached to it. Results paginate by an opaque cursor. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List graph nodes bound to a product entity. ### CLI ```console $ strata graph create kb $ strata graph add-node kb ada --binding {"target":{"key":"user:1","primitive":"kv","space":"default"}} # Bind the node to a KV entity so retrieval can cross primitives. $ strata command run --command-json '{"target":{"key":"user:1","primitive":"kv","space":"default"},"type":"graph_bindings_for_entity"}' ``` ### Wire ```json {"graph":"kb","type":"graph_create"} {"binding":{"target":{"key":"user:1","primitive":"kv","space":"default"}},"graph":"kb","node_id":"ada","type":"graph_add_node"} {"target":{"key":"user:1","primitive":"kv","space":"default"},"type":"graph_bindings_for_entity"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `cursor` | `string` | no | Optional exclusive cursor. | | `limit` | `integer` | no | Optional item limit. Defaults to 100. | | `target` | `GraphBindingTarget` | yes | Entity target to search for. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_binding`](https://stratadb.org/e/invalid_argument.engine.graph_binding) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `graph_bindings_for_entity` --- # Create graph Source: https://stratadb.org/docs/reference/graph/create Creates an empty named graph in the selected space and returns its metadata, including node and edge counts (zero at creation) and the create commit coordinates. A database can hold many graphs; graph names are unique per branch and space. Creating a name that already exists fails with `already_exists.engine.graph`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Create a named graph. ### CLI ```console $ strata graph create social $ strata graph list ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"type":"graph_list"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`already_exists.engine.graph`](https://stratadb.org/e/already_exists.engine.graph) - [`invalid_argument.engine.graph_name_reserved`](https://stratadb.org/e/invalid_argument.engine.graph_name_reserved) ## Invocation - CLI: `strata graph create` - Wire type: `graph_create` --- # Bulk insert graph data Source: https://stratadb.org/docs/reference/graph/bulk_insert Ingests a payload of nodes and edges in chunked commits: nodes first, then edges, so edges may reference nodes from the same payload. Node objects use the key `node_id`; edges use `src`, `edge_type`, `dst`, and optional `weight` (default 1.0) and `properties`. `chunk_size` bounds items per commit (default 512, clamped at 800). The acknowledgement reports inserted counts, the number of chunk commits, and the final chunk's commit receipt. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Insert many nodes and edges in one commit. ### CLI ```console $ strata graph create g $ strata graph bulk-insert g --edges [{"dst":"b","edge_type":"knows","src":"a"}] --nodes [{"node_id":"a","object_type":"person"},{"node_id":"b","object_type":"person"}] $ strata graph meta g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"edges":[{"dst":"b","edge_type":"knows","src":"a"}],"graph":"g","nodes":[{"node_id":"a","object_type":"person"},{"node_id":"b","object_type":"person"}],"type":"graph_bulk_insert"} {"graph":"g","type":"graph_get_meta"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `chunk_size` | `integer` | no | Optional items-per-commit chunk size. Defaults to 512; values above 800 clamp so one chunk fits one storage commit. | | `edges` | `GraphBulkEdge[]` | no | Edges to upsert; endpoints must exist or arrive in `nodes`. | | `graph` | `string` | yes | Graph name. | | `nodes` | `GraphBulkNode[]` | no | Nodes to upsert (committed before edges). | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_edge_type`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type) - [`invalid_argument.engine.graph_edge_weight`](https://stratadb.org/e/invalid_argument.engine.graph_edge_weight) - [`invalid_argument.engine.graph_edge_endpoint`](https://stratadb.org/e/invalid_argument.engine.graph_edge_endpoint) - [`invalid_argument.engine.graph_properties`](https://stratadb.org/e/invalid_argument.engine.graph_properties) - [`invalid_argument.engine.graph_properties_too_large`](https://stratadb.org/e/invalid_argument.engine.graph_properties_too_large) - [`failed_precondition.engine.graph_negative_weight`](https://stratadb.org/e/failed_precondition.engine.graph_negative_weight) - [`failed_precondition.engine.graph_ontology_node_type`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_node_type) - [`failed_precondition.engine.graph_ontology_edge_type`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_edge_type) ## Invocation - CLI: `strata graph bulk-insert` - Wire type: `graph_bulk_insert` --- # Delete graph Source: https://stratadb.org/docs/reference/graph/delete Deletes a named graph and every visible node, edge, binding, and ontology row it owns. Deleting a graph that does not exist is not an error: the acknowledgement reports `deleted: false` with a `not_found` effect. Earlier states remain readable through time travel on other commands. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete a graph. ### CLI ```console $ strata graph create temp $ strata graph delete temp $ strata graph list ``` ### Wire ```json {"graph":"temp","type":"graph_create"} {"graph":"temp","type":"graph_delete"} {"type":"graph_list"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) ## Invocation - CLI: `strata graph delete` - Wire type: `graph_delete` --- # List graphs Source: https://stratadb.org/docs/reference/graph/list Lists graph names in lexicographic order. Accepts an optional item limit (default 100), an exclusive name cursor for continuation, and an `as_of` timestamp to list the graphs visible at an earlier instant. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List graphs. ### CLI ```console $ strata graph create social $ strata graph list ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"type":"graph_list"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `cursor` | `string` | no | Optional exclusive graph cursor. | | `limit` | `integer` | no | Optional item limit. Defaults to 100. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) ## Invocation - CLI: `strata graph list` - Wire type: `graph_list` --- # graph commands Source: https://stratadb.org/docs/reference/graph # `graph` — command reference | Command | Summary | |---|---| | [Traverse graph breadth-first](/docs/reference/graph/analytics/bfs) | Run a bounded breadth-first traversal. | | [Detect graph communities](/docs/reference/graph/analytics/cdlp) | Detect communities via label propagation. | | [Compute graph clustering coefficients](/docs/reference/graph/analytics/lcc) | Compute local clustering coefficients. | | [Compute graph pagerank](/docs/reference/graph/analytics/pagerank) | Compute PageRank importance scores. | | [Compute graph shortest paths](/docs/reference/graph/analytics/sssp) | Compute shortest-path distances from a source. | | [Compute graph connected components](/docs/reference/graph/analytics/wcc) | Compute weakly connected components. | | [Apply graph delete policy](/docs/reference/graph/apply_delete_policy) | Apply a delete policy to bound graph facts. | | [Batch write graph](/docs/reference/graph/batch_write) | Apply graph mutations atomically. | | [List graph bindings for entity](/docs/reference/graph/bindings) | Find graph nodes bound to an entity. | | [Bulk insert graph data](/docs/reference/graph/bulk_insert) | Bulk-load nodes and edges in chunks. | | [Create graph](/docs/reference/graph/create) | Create a named graph. | | [Delete graph](/docs/reference/graph/delete) | Delete a graph and its visible data. | | [Add graph edge](/docs/reference/graph/edge/add) | Add or replace a graph edge. | | [Get graph edge](/docs/reference/graph/edge/get) | Read one graph edge. | | [Remove graph edge](/docs/reference/graph/edge/remove) | Remove a graph edge. | | [List graphs](/docs/reference/graph/list) | List graph names. | | [Read graph metadata](/docs/reference/graph/meta) | Read graph metadata and counts. | | [List graph neighbors](/docs/reference/graph/neighbors) | List a node's neighbors. | | [Add graph node](/docs/reference/graph/node/add) | Add or replace a graph node. | | [Get graph node](/docs/reference/graph/node/get) | Read one graph node. | | [List graph nodes](/docs/reference/graph/node/list) | List graph nodes. | | [Remove graph node](/docs/reference/graph/node/remove) | Remove a graph node and its edges. | | [List graph nodes by type](/docs/reference/graph/nodes_by_type) | List nodes declaring an object type. | | [Define graph link type](/docs/reference/graph/ontology/define_link_type) | Define a graph link type. | | [Define graph object type](/docs/reference/graph/ontology/define_object_type) | Define a graph object type. | | [Delete graph link type](/docs/reference/graph/ontology/delete_link_type) | Delete a draft link type. | | [Delete graph object type](/docs/reference/graph/ontology/delete_object_type) | Delete a draft object type. | | [Freeze graph ontology](/docs/reference/graph/ontology/freeze) | Freeze the graph ontology. | | [Read graph ontology](/docs/reference/graph/ontology/get) | Read the graph ontology. | | [Read graph ontology summary](/docs/reference/graph/ontology/summary) | Read the ontology with usage counts. | | [Sample graph nodes](/docs/reference/graph/sample) | Sample graph nodes. | --- # Read graph metadata Source: https://stratadb.org/docs/reference/graph/meta Reads a graph's metadata: live node and edge counts plus the create and last-update commit versions and timestamps. Reading a graph that does not exist returns no data rather than an error. Accepts `as_of` for time travel. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read a graph's node and edge counts. ### CLI ```console $ strata graph create social $ strata graph add-node social alice $ strata graph add-node social bob $ strata graph meta social ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","type":"graph_add_node"} {"graph":"social","node_id":"bob","type":"graph_add_node"} {"graph":"social","type":"graph_get_meta"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) ## Invocation - CLI: `strata graph meta` - Wire type: `graph_get_meta` --- # List graph neighbors Source: https://stratadb.org/docs/reference/graph/neighbors Walks a node's edges and returns one hit per traversed edge. Direction is `outgoing`, `incoming`, or `both`; an optional edge-type filter restricts the walk. Each hit embeds both the traversed edge and the neighbor node in full, so a follow-up read is rarely needed. A missing node yields an empty page. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples Find a node's neighbors along outgoing edges. ### CLI ```console $ strata graph create social $ strata graph add-node social alice $ strata graph add-node social bob $ strata graph add-edge social alice knows bob $ strata graph neighbors social alice outgoing ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","type":"graph_add_node"} {"graph":"social","node_id":"bob","type":"graph_add_node"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_add_edge"} {"direction":"outgoing","graph":"social","node_id":"alice","type":"graph_neighbors"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `cursor` | `string` | no | Optional exclusive cursor. | | `direction` | `GraphDirection` | yes | Traversal direction. | | `edge_type` | `string` | no | Optional edge type filter. | | `graph` | `string` | yes | Graph name. | | `limit` | `integer` | no | Optional item limit. Defaults to 100. | | `node_id` | `string` | yes | Node id. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_edge_type`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type) ## Invocation - CLI: `strata graph neighbors` - Wire type: `graph_neighbors` --- # List graph nodes by type Source: https://stratadb.org/docs/reference/graph/nodes_by_type Lists the nodes that declare a given object type, in node-id order. The type index is maintained from each node's declared `object_type`, so this works whether the ontology is draft or frozen. Accepts a limit, an exclusive cursor, and `as_of` for time travel. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List nodes of a given object type. ### CLI ```console $ strata graph create g $ strata graph add-node g a --object-type person $ strata graph add-node g b --object-type person $ strata graph nodes-by-type g person ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","object_type":"person","type":"graph_add_node"} {"graph":"g","node_id":"b","object_type":"person","type":"graph_add_node"} {"graph":"g","object_type":"person","type":"graph_nodes_by_type"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `cursor` | `string` | no | Optional exclusive node id cursor. | | `graph` | `string` | yes | Graph name. | | `limit` | `integer` | no | Optional item limit. Defaults to 100. | | `object_type` | `string` | yes | Object type name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_type_name`](https://stratadb.org/e/invalid_argument.engine.graph_type_name) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) ## Invocation - CLI: `strata graph nodes-by-type` - Wire type: `graph_nodes_by_type` --- # Sample graph nodes Source: https://stratadb.org/docs/reference/graph/sample Returns a deterministic representative sample of nodes from a graph: the total live node count and up to `count` nodes (default 10), evenly strided over the ordered node ids. Latest state only. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples A representative sample of nodes plus the total count. ### CLI ```console $ strata graph create g $ strata graph add-node g a $ strata graph add-node g b $ strata graph sample g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","type":"graph_add_node"} {"graph":"g","node_id":"b","type":"graph_add_node"} {"graph":"g","type":"graph_sample"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `count` | `integer` | no | Optional sample count. Defaults to 10. | | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `SamplePage`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) ## Invocation - CLI: `strata graph sample` - Wire type: `graph_sample` --- # Detokenize token ids Source: https://stratadb.org/docs/reference/inference/detokenize Decodes an ordered list of token ids back into text using a local model's vocabulary, returning the reconstructed string. Detokenization is a local-only operation: it requires a build with the local execution feature and returns `inference.unsupported_operation` for cloud provider specs. ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `ids` | `integer[]` | yes | Token ids. | | `model` | `string` | yes | Model spec. | ## Returns `DetokenizedText`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`inference.unsupported_operation`](https://stratadb.org/e/inference.unsupported_operation) - [`inference.missing_model`](https://stratadb.org/e/inference.missing_model) - [`inference.model_load_failed`](https://stratadb.org/e/inference.model_load_failed) - [`inference.local_runtime_failed`](https://stratadb.org/e/inference.local_runtime_failed) - [`inference.registry_corrupt`](https://stratadb.org/e/inference.registry_corrupt) ## Invocation - CLI: `strata inference detokenize` - Wire type: `inference_detokenize` --- # Report model capabilities Source: https://stratadb.org/docs/reference/inference/capability Parses a model spec into a provider and model name and reports what that combination supports without running the model. The result states whether generation, tokenization, embedding, and ranking are available, whether the operation requires network access or an API key, whether this binary was compiled with the provider feature needed to execute, whether the runtime currently permits network calls, and the known embedding dimension. Model specs are catalog names (`tinyllama`), catalog `name:quant` pairs (`tinyllama:q8_0`), local GGUF paths, or provider specs (`anthropic:claude-...`). ## Examples Report a model's capabilities without a network call. ### CLI ```console $ strata inference capability openai:gpt-4o-mini # Pure metadata — no request is sent to the provider. ``` ### Wire ```json {"model":"openai:gpt-4o-mini","type":"inference_model_capability"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `model` | `string` | yes | Model spec. | ## Returns `InferenceCapability`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`inference.invalid_request`](https://stratadb.org/e/inference.invalid_request) ## Invocation - CLI: `strata inference capability` - Wire type: `inference_model_capability` --- # Report model cache Source: https://stratadb.org/docs/reference/inference/cache_status Reports the runtime model cache as three lists of specs: the generation, embedding, and ranking models currently loaded in memory. Use it to check what is resident before generating, or to confirm that `inference unload` freed the models you expected. The lists reflect only in-memory engines, not models available on disk. ## Examples Inspect which models are currently loaded in the runtime cache. ### CLI ```console $ strata inference cache-status ``` ### Wire ```json {"type":"inference_cache_status"} ``` ## Parameters _No parameters._ ## Returns `ModelCacheStatus`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) ## Invocation - CLI: `strata inference cache-status` - Wire type: `inference_cache_status` --- # Embed one or more texts Source: https://stratadb.org/docs/reference/inference/embed Embeds text with an embedding-capable model and returns one vector per input, in order. The `input` field takes either a single string or an array of strings, so single and batch embedding share one command. The vector dimension is fixed by the model. Local embedding models require a build with the local execution feature; cloud embedding providers (OpenAI, Google) require the matching provider feature and an API key. ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `model` | `string` | yes | Model spec. | | `dimensions` | `integer` | no | Truncate to this many dimensions (matryoshka), then renormalize. | | `input` | `EmbedInput` | yes | Text(s) to embed. | | `input_type` | `InputType` | no | Query vs document role for instruction-tuned embedders. | | `instruction` | `string` | no | Explicit instruction prefix override. | | `normalize` | `boolean` | no | Force L2 normalization on/off (default per-model). | ## Returns `EmbeddingsResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`inference.unsupported_operation`](https://stratadb.org/e/inference.unsupported_operation) - [`inference.missing_model`](https://stratadb.org/e/inference.missing_model) - [`inference.model_load_failed`](https://stratadb.org/e/inference.model_load_failed) - [`inference.local_runtime_failed`](https://stratadb.org/e/inference.local_runtime_failed) - [`inference.missing_api_key`](https://stratadb.org/e/inference.missing_api_key) - [`inference.provider_unavailable`](https://stratadb.org/e/inference.provider_unavailable) - [`inference.provider_malformed_response`](https://stratadb.org/e/inference.provider_malformed_response) - [`inference.unsupported_provider`](https://stratadb.org/e/inference.unsupported_provider) - [`inference.unsupported_parameter`](https://stratadb.org/e/inference.unsupported_parameter) - [`inference.registry_corrupt`](https://stratadb.org/e/inference.registry_corrupt) ## Invocation - CLI: `strata inference embed` - Wire type: `inference_embed` --- # Generate text Source: https://stratadb.org/docs/reference/inference/generate Runs a text-generation request against a local or cloud model and returns the completion, the reason generation stopped, and the provider-reported prompt and completion token counts. The request controls the maximum completion tokens, sampling temperature, top-k and top-p cutoffs, an optional deterministic seed, string and token-id stop sequences, and an optional GBNF grammar for constrained generation. Chat models expect their chat template already applied in the prompt. Local models require a build with the local execution feature; cloud providers require the matching provider feature and an API key. ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `model` | `string` | yes | Model spec. | | `frequency_penalty` | `number` | no | Frequency penalty. | | `grammar` | `string` | no | GBNF grammar for constrained generation (local). | | `logit_bias` | `object` | no | Per-token logit bias (token id → bias). | | `logprobs` | `boolean` | no | Whether to return log-probabilities. | | `max_tokens` | `integer` | no | Maximum completion tokens. | | `messages` | `ChatMessage[]` | no | Chat messages (system/user/assistant/tool). | | `min_p` | `number` | no | Min-p sampling cutoff. | | `mirostat` | `Mirostat` | no | Mirostat sampling. | | `model_config` | `ModelConfig` | no | Per-model load/context configuration. | | `presence_penalty` | `number` | no | Presence penalty. | | `prompt` | `string` | no | Raw completion prompt (base models / full control). | | `repeat_last_n` | `integer` | no | Repetition penalty look-back window. | | `repeat_penalty` | `number` | no | Repetition penalty. | | `response_format` | `ResponseFormat` | no | Output format constraint. | | `seed` | `integer` | no | Deterministic sampling seed. | | `stop` | `string[]` | no | Stop sequences. | | `stop_token_ids` | `integer[]` | no | Token-id stop sequences (local). | | `temperature` | `number` | no | Sampling temperature. | | `tfs_z` | `number` | no | Tail-free sampling z. | | `tool_choice` | `ToolChoice` | no | How the model should choose among `tools`. | | `tools` | `Tool[]` | no | Tools (functions) the model may call. | | `top_k` | `integer` | no | Top-k sampling cutoff. | | `top_logprobs` | `integer` | no | Number of top log-probabilities to return per token. | | `top_p` | `number` | no | Nucleus sampling cutoff. | | `typical_p` | `number` | no | Typical-p (locally typical) sampling. | ## Returns `ChatResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`inference.unsupported_operation`](https://stratadb.org/e/inference.unsupported_operation) - [`inference.missing_model`](https://stratadb.org/e/inference.missing_model) - [`inference.model_load_failed`](https://stratadb.org/e/inference.model_load_failed) - [`inference.local_runtime_failed`](https://stratadb.org/e/inference.local_runtime_failed) - [`inference.missing_api_key`](https://stratadb.org/e/inference.missing_api_key) - [`inference.provider_auth_failed`](https://stratadb.org/e/inference.provider_auth_failed) - [`inference.provider_unavailable`](https://stratadb.org/e/inference.provider_unavailable) - [`inference.provider_timeout`](https://stratadb.org/e/inference.provider_timeout) - [`inference.provider_rate_limited`](https://stratadb.org/e/inference.provider_rate_limited) - [`inference.invalid_request`](https://stratadb.org/e/inference.invalid_request) - [`inference.provider_malformed_response`](https://stratadb.org/e/inference.provider_malformed_response) - [`inference.unsupported_provider`](https://stratadb.org/e/inference.unsupported_provider) - [`inference.unsupported_parameter`](https://stratadb.org/e/inference.unsupported_parameter) - [`inference.registry_corrupt`](https://stratadb.org/e/inference.registry_corrupt) ## Invocation - CLI: `strata inference generate` - Wire type: `inference_generate` --- # Rank passages Source: https://stratadb.org/docs/reference/inference/rank Scores each candidate passage against a query with a ranking model and returns one outcome per passage. Each item carries the passage's original index and either a relevance score or a per-item error with a stable code and a redacted message, so callers can reorder passages by score while keeping them tied to their inputs. Ranking is a local-only operation: it requires a build with the local execution feature and a ranking-capable model. ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `model` | `string` | yes | Model spec. | | `passages` | `string[]` | yes | Candidate passages. | | `query` | `string` | yes | Query text. | ## Returns `RankResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`inference.unsupported_operation`](https://stratadb.org/e/inference.unsupported_operation) - [`inference.missing_model`](https://stratadb.org/e/inference.missing_model) - [`inference.model_load_failed`](https://stratadb.org/e/inference.model_load_failed) - [`inference.local_runtime_failed`](https://stratadb.org/e/inference.local_runtime_failed) - [`inference.registry_corrupt`](https://stratadb.org/e/inference.registry_corrupt) ## Invocation - CLI: `strata inference rank` - Wire type: `inference_rank` --- # Unload cached models Source: https://stratadb.org/docs/reference/inference/unload Removes cached model engines from the runtime to free memory. Pass a model spec to unload one entry, or omit it to unload every cached generation, embedding, and ranking model. The result reports whether any cached entry was actually removed. This affects only the in-memory runtime cache; it never deletes downloaded model files from disk. ## Examples Evict cached models from the runtime (a no-op when nothing is loaded). ### CLI ```console $ strata inference unload ``` ### Wire ```json {"type":"inference_unload"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `model` | `string` | no | Optional model spec. | ## Returns `UnloadResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) ## Invocation - CLI: `strata inference unload` - Wire type: `inference_unload` --- # Tokenize text Source: https://stratadb.org/docs/reference/inference/tokenize Encodes text into the token id sequence a local model would see and returns the ids in order. Set `add_special` to include the model's special tokens (such as beginning-of-sequence markers). Tokenization is a local-only operation: it requires a build with the local execution feature and returns `inference.unsupported_operation` for cloud provider specs. ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `add_special` | `boolean` | no | Whether to add special tokens. | | `model` | `string` | yes | Model spec. | | `text` | `string` | yes | Text to tokenize. | ## Returns `TokenIds`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`inference.unsupported_operation`](https://stratadb.org/e/inference.unsupported_operation) - [`inference.missing_model`](https://stratadb.org/e/inference.missing_model) - [`inference.model_load_failed`](https://stratadb.org/e/inference.model_load_failed) - [`inference.local_runtime_failed`](https://stratadb.org/e/inference.local_runtime_failed) - [`inference.registry_corrupt`](https://stratadb.org/e/inference.registry_corrupt) ## Invocation - CLI: `strata inference tokenize` - Wire type: `inference_tokenize` --- # inference commands Source: https://stratadb.org/docs/reference/inference # `inference` — command reference | Command | Summary | |---|---| | [Report model cache](/docs/reference/inference/cache_status) | Report loaded model cache state. | | [Report model capabilities](/docs/reference/inference/capability) | Report capabilities for a model spec. | | [Detokenize token ids](/docs/reference/inference/detokenize) | Detokenize token ids with a local model. | | [Embed one or more texts](/docs/reference/inference/embed) | Embed one or more texts into vectors. | | [Generate text](/docs/reference/inference/generate) | Generate text with an inference model. | | [List catalog models](/docs/reference/inference/models/list) | List catalog inference models. | | [List local models](/docs/reference/inference/models/local) | List locally downloaded inference models. | | [Download a model](/docs/reference/inference/models/pull) | Download an inference model locally. | | [Rank passages](/docs/reference/inference/rank) | Rank passages against a query. | | [Tokenize text](/docs/reference/inference/tokenize) | Tokenize text with a local model. | | [Unload cached models](/docs/reference/inference/unload) | Unload cached inference models. | --- # Batch delete JSON values Source: https://stratadb.org/docs/reference/json/batch_delete Deletes multiple document/path entries and returns one positional mutation result per entry. Missing documents and paths are represented as no-op item results; applied items share one engine commit. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Delete many documents in one commit. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"a","path":"$","value":{"v":1}}],"type":"json_batch_set"}' $ strata command run --command-json '{"entries":[{"key":"a","path":"$"}],"type":"json_batch_delete"}' $ strata json exists a ``` ### Wire ```json {"entries":[{"key":"a","path":"$","value":{"v":1}}],"type":"json_batch_set"} {"entries":[{"key":"a","path":"$"}],"type":"json_batch_delete"} {"key":"a","type":"json_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `entries` | `BatchJsonDeleteEntry[]` | yes | Entries to delete. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) - [`invalid_argument.engine.json_path`](https://stratadb.org/e/invalid_argument.engine.json_path) - [`invalid_argument.engine.json_path_too_long`](https://stratadb.org/e/invalid_argument.engine.json_path_too_long) - [`invalid_argument.engine.json_path_type`](https://stratadb.org/e/invalid_argument.engine.json_path_type) - [`invalid_argument.executor.json_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.executor.json_batch_duplicate_key) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `json_batch_delete` --- # Batch check JSON document existence Source: https://stratadb.org/docs/reference/json/batch_exists Checks several JSON documents and returns positional boolean status values. The response preserves the input order. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Check existence for many document keys at once. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"a","path":"$","value":{"v":1}}],"type":"json_batch_set"}' $ strata command run --command-json '{"keys":["a","missing"],"type":"json_batch_exists"}' ``` ### Wire ```json {"entries":[{"key":"a","path":"$","value":{"v":1}}],"type":"json_batch_set"} {"keys":["a","missing"],"type":"json_batch_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `keys` | `string[]` | yes | Document keys to check. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `json_batch_exists` --- # Batch get JSON values Source: https://stratadb.org/docs/reference/json/batch_get Reads several document/path entries and returns positional item results. Each item records whether the value was found and includes version metadata when present. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Read many documents at once. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}}],"type":"json_batch_set"}' $ strata command run --command-json '{"entries":[{"key":"a","path":"$"},{"key":"b","path":"$"}],"type":"json_batch_get"}' ``` ### Wire ```json {"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}}],"type":"json_batch_set"} {"entries":[{"key":"a","path":"$"},{"key":"b","path":"$"}],"type":"json_batch_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `entries` | `BatchJsonGetEntry[]` | yes | Entries to read. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult>`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) - [`invalid_argument.engine.json_path`](https://stratadb.org/e/invalid_argument.engine.json_path) - [`invalid_argument.engine.json_path_too_long`](https://stratadb.org/e/invalid_argument.engine.json_path_too_long) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `json_batch_get` --- # Batch set JSON values Source: https://stratadb.org/docs/reference/json/batch_set Writes multiple document/path/value entries using the executor batch contract. Valid items share one engine commit; entries targeting the same document are merged in order into a single new document version. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Write many documents in one commit. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}}],"type":"json_batch_set"}' $ strata command run --command-json '{"entries":[{"key":"a","path":"$"},{"key":"b","path":"$"}],"type":"json_batch_get"}' ``` ### Wire ```json {"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}}],"type":"json_batch_set"} {"entries":[{"key":"a","path":"$"},{"key":"b","path":"$"}],"type":"json_batch_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `entries` | `BatchJsonEntry[]` | yes | Entries to set. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) - [`invalid_argument.engine.json_path`](https://stratadb.org/e/invalid_argument.engine.json_path) - [`invalid_argument.engine.json_path_too_long`](https://stratadb.org/e/invalid_argument.engine.json_path_too_long) - [`invalid_argument.engine.json_path_not_found`](https://stratadb.org/e/invalid_argument.engine.json_path_not_found) - [`invalid_argument.engine.json_path_type`](https://stratadb.org/e/invalid_argument.engine.json_path_type) - [`invalid_argument.engine.json_value`](https://stratadb.org/e/invalid_argument.engine.json_value) - [`invalid_argument.engine.json_document_too_large`](https://stratadb.org/e/invalid_argument.engine.json_document_too_large) - [`invalid_argument.engine.json_document_too_deep`](https://stratadb.org/e/invalid_argument.engine.json_document_too_deep) - [`invalid_argument.engine.json_array_too_large`](https://stratadb.org/e/invalid_argument.engine.json_array_too_large) - [`invalid_argument.executor.json_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.executor.json_batch_duplicate_key) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `json_batch_set` --- # Count JSON documents Source: https://stratadb.org/docs/reference/json/count Counts visible JSON documents in the selected branch and space, optionally constrained by a document key prefix. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Count stored documents. ### CLI ```console $ strata json set a $ {"v":1} $ strata json set b $ {"v":2} $ strata json count ``` ### Wire ```json {"key":"a","path":"$","type":"json_set","value":{"v":1}} {"key":"b","path":"$","type":"json_set","value":{"v":2}} {"type":"json_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `prefix` | `string` | no | Optional document key prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) ## Invocation - CLI: `strata json count` - Wire type: `json_count` --- # Delete JSON value Source: https://stratadb.org/docs/reference/json/delete Deletes the root path `$` to remove the whole document, or a nested path to remove one field or array element. Missing documents and paths produce a no-op delete acknowledgement rather than an error. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete a document. ### CLI ```console $ strata json set temp $ {"x":1} $ strata json delete temp $ $ strata json exists temp ``` ### Wire ```json {"key":"temp","path":"$","type":"json_set","value":{"x":1}} {"key":"temp","path":"$","type":"json_delete"} {"key":"temp","type":"json_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `string` | yes | Document key. | | `path` | `string` | yes | JSON path. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) - [`invalid_argument.engine.json_path`](https://stratadb.org/e/invalid_argument.engine.json_path) - [`invalid_argument.engine.json_path_too_long`](https://stratadb.org/e/invalid_argument.engine.json_path_too_long) - [`invalid_argument.engine.json_path_type`](https://stratadb.org/e/invalid_argument.engine.json_path_type) ## Invocation - CLI: `strata json delete` - Wire type: `json_delete` --- # Check JSON document existence Source: https://stratadb.org/docs/reference/json/exists Returns a boolean status for one JSON document key without loading the stored document. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Check whether a document exists. ### CLI ```console $ strata json set user $ {"name":"alice"} $ strata json exists user $ strata json exists absent ``` ### Wire ```json {"key":"user","path":"$","type":"json_set","value":{"name":"alice"}} {"key":"user","type":"json_exists"} {"key":"absent","type":"json_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `string` | yes | Document key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) ## Invocation - CLI: `strata json exists` - Wire type: `json_exists` --- # Get JSON value Source: https://stratadb.org/docs/reference/json/get Reads the JSON value at a path inside a document. Current reads return the value with commit metadata; passing a timestamp returns the bare value visible at that point in time. A missing document or path is a found-false result, distinct from a stored JSON null. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read a whole document, a value at a JSON path, or nothing. ### CLI ```console $ strata json set user $ {"age":30,"name":"alice"} $ strata json get user $ $ strata json get user $.name $ strata json get absent $ ``` ### Wire ```json {"key":"user","path":"$","type":"json_set","value":{"age":30,"name":"alice"}} {"key":"user","path":"$","type":"json_get"} {"key":"user","path":"$.name","type":"json_get"} {"key":"absent","path":"$","type":"json_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `key` | `string` | yes | Document key. | | `path` | `string` | yes | JSON path. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) - [`invalid_argument.engine.json_path`](https://stratadb.org/e/invalid_argument.engine.json_path) - [`invalid_argument.engine.json_path_too_long`](https://stratadb.org/e/invalid_argument.engine.json_path_too_long) ## Invocation - CLI: `strata json get` - Wire type: `json_get` --- # Read JSON document history Source: https://stratadb.org/docs/reference/json/history Returns retained full-document history rows for a JSON document, newest first, including delete tombstones. A document with no retained history maps to an optional-read result. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples A document that never existed has no history. ### CLI ```console $ strata json history absent ``` ### Wire ```json {"key":"absent","type":"json_history"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `string` | yes | Document key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe>` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) ## Invocation - CLI: `strata json history` - Wire type: `json_history` --- # json commands Source: https://stratadb.org/docs/reference/json # `json` — command reference | Command | Summary | |---|---| | [Batch delete JSON values](/docs/reference/json/batch_delete) | Delete multiple JSON documents or paths in one itemwise batch. | | [Batch check JSON document existence](/docs/reference/json/batch_exists) | Check existence for multiple JSON documents. | | [Batch get JSON values](/docs/reference/json/batch_get) | Read multiple JSON values by document and path. | | [Batch set JSON values](/docs/reference/json/batch_set) | Set multiple JSON values in one itemwise batch. | | [Count JSON documents](/docs/reference/json/count) | Count visible JSON documents. | | [Delete JSON value](/docs/reference/json/delete) | Delete a whole JSON document or one path inside it. | | [Check JSON document existence](/docs/reference/json/exists) | Check whether one JSON document exists. | | [Get JSON value](/docs/reference/json/get) | Read the current or historical JSON value at a document path. | | [Read JSON document history](/docs/reference/json/history) | Read retained version history for one JSON document. | | [Create JSON index](/docs/reference/json/index/create) | Create a JSON secondary index on a field path. | | [Drop JSON index](/docs/reference/json/index/drop) | Drop a JSON secondary index by name. | | [List JSON indexes](/docs/reference/json/index/list) | List JSON secondary indexes. | | [List JSON document keys](/docs/reference/json/list) | List JSON document keys with optional prefix filtering. | | [Sample JSON documents](/docs/reference/json/sample) | Sample visible JSON documents. | | [Scan JSON documents](/docs/reference/json/scan) | Scan JSON documents with values and version facts. | | [Set JSON value](/docs/reference/json/set) | Set a JSON value at a document path, creating the document when missing. | --- # List JSON document keys Source: https://stratadb.org/docs/reference/json/list Lists visible JSON document keys in byte order. Prefix, cursor, limit, and timestamp parameters constrain the page returned by the executor. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List document keys under a prefix, in key order. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"user:1","path":"$","value":{"v":1}},{"key":"user:2","path":"$","value":{"v":2}},{"key":"other","path":"$","value":{"v":3}}],"type":"json_batch_set"}' $ strata json list --prefix user: ``` ### Wire ```json {"entries":[{"key":"user:1","path":"$","value":{"v":1}},{"key":"user:2","path":"$","value":{"v":2}},{"key":"other","path":"$","value":{"v":3}}],"type":"json_batch_set"} {"prefix":"user:","type":"json_list"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `cursor` | `string` | no | Optional document key cursor. | | `limit` | `integer` | no | Optional item limit. | | `prefix` | `string` | no | Optional document key prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) ## Invocation - CLI: `strata json list` - Wire type: `json_list` --- # Sample JSON documents Source: https://stratadb.org/docs/reference/json/sample Returns a bounded sample of visible JSON documents plus the total matching count. Useful for inspecting document shape before writing queries or indexes. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples A representative sample plus the total population size. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}},{"key":"c","path":"$","value":{"v":3}}],"type":"json_batch_set"}' $ strata json sample ``` ### Wire ```json {"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}},{"key":"c","path":"$","value":{"v":3}}],"type":"json_batch_set"} {"type":"json_sample"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `count` | `integer` | no | Optional sample count. Defaults to 10. | | `prefix` | `string` | no | Optional document key prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `SamplePage`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) ## Invocation - CLI: `strata json sample` - Wire type: `json_sample` --- # Set JSON value Source: https://stratadb.org/docs/reference/json/set Writes a JSON value at a path inside a document, creating the document and any missing intermediate objects when needed. Setting the root path `$` replaces the whole document; setting a nested path like `$.profile.name` updates one field and records a new document version. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Store a JSON document, then read it back. ### CLI ```console $ strata json set user $ {"age":30,"name":"alice"} $ strata json get user $ ``` ### Wire ```json {"key":"user","path":"$","type":"json_set","value":{"age":30,"name":"alice"}} {"key":"user","path":"$","type":"json_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `string` | yes | Document key. | | `path` | `string` | yes | JSON path. | | `value` | `any` | yes | JSON value. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) - [`invalid_argument.engine.json_path`](https://stratadb.org/e/invalid_argument.engine.json_path) - [`invalid_argument.engine.json_path_too_long`](https://stratadb.org/e/invalid_argument.engine.json_path_too_long) - [`invalid_argument.engine.json_path_not_found`](https://stratadb.org/e/invalid_argument.engine.json_path_not_found) - [`invalid_argument.engine.json_path_type`](https://stratadb.org/e/invalid_argument.engine.json_path_type) - [`invalid_argument.engine.json_value`](https://stratadb.org/e/invalid_argument.engine.json_value) - [`invalid_argument.engine.json_document_too_large`](https://stratadb.org/e/invalid_argument.engine.json_document_too_large) - [`invalid_argument.engine.json_document_too_deep`](https://stratadb.org/e/invalid_argument.engine.json_document_too_deep) - [`invalid_argument.engine.json_array_too_large`](https://stratadb.org/e/invalid_argument.engine.json_array_too_large) ## Invocation - CLI: `strata json set` - Wire type: `json_set` --- # Scan JSON documents Source: https://stratadb.org/docs/reference/json/scan Scans visible JSON documents starting at an optional document key. Each item includes the key, full document value, and commit metadata exposed by the executor output. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples Scan documents from the start, in key order. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}}],"type":"json_batch_set"}' $ strata json scan ``` ### Wire ```json {"entries":[{"key":"a","path":"$","value":{"v":1}},{"key":"b","path":"$","value":{"v":2}}],"type":"json_batch_set"} {"type":"json_scan"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `limit` | `integer` | no | Optional row limit. | | `start` | `string` | no | Optional inclusive start document key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_document_id`](https://stratadb.org/e/invalid_argument.engine.json_document_id) ## Invocation - CLI: `strata json scan` - Wire type: `json_scan` --- # Batch delete KV values Source: https://stratadb.org/docs/reference/kv/batch_delete Deletes multiple KV keys and returns one positional mutation result per key. Missing keys are represented as no-op item results. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Delete many keys in one commit. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"}' $ strata command run --command-json '{"keys":["YQ==","Yg=="],"type":"kv_batch_delete"}' $ strata command run --command-json '{"keys":["YQ==","Yg=="],"type":"kv_batch_exists"}' ``` ### Wire ```json {"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"} {"keys":["YQ==","Yg=="],"type":"kv_batch_delete"} {"keys":["YQ==","Yg=="],"type":"kv_batch_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `keys` | `Bytes[]` | yes | Keys to delete. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) - [`invalid_argument.engine.kv_batch`](https://stratadb.org/e/invalid_argument.engine.kv_batch) - [`invalid_argument.engine.kv_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.engine.kv_batch_duplicate_key) - [`invalid_argument.executor.kv_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.executor.kv_batch_duplicate_key) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `kv_batch_delete` --- # Batch check KV existence Source: https://stratadb.org/docs/reference/kv/batch_exists Checks several KV keys and returns positional boolean status values. The response preserves the input order. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Check existence for many keys at once. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"YQ==","value":"MQ=="}],"type":"kv_batch_put"}' $ strata command run --command-json '{"keys":["YQ==","bWlzc2luZw=="],"type":"kv_batch_exists"}' ``` ### Wire ```json {"entries":[{"key":"YQ==","value":"MQ=="}],"type":"kv_batch_put"} {"keys":["YQ==","bWlzc2luZw=="],"type":"kv_batch_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `keys` | `Bytes[]` | yes | Keys to check. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) - [`invalid_argument.engine.kv_batch`](https://stratadb.org/e/invalid_argument.engine.kv_batch) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `kv_batch_exists` --- # Batch put KV values Source: https://stratadb.org/docs/reference/kv/batch_put Writes multiple KV entries using the executor batch contract. Valid items share commit facts where the underlying engine applies them together. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Write many entries in one commit. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"}' $ strata command run --command-json '{"keys":["YQ==","Yg=="],"type":"kv_batch_get"}' ``` ### Wire ```json {"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"} {"keys":["YQ==","Yg=="],"type":"kv_batch_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `entries` | `BatchKvEntry[]` | yes | Entries to write. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) - [`invalid_argument.engine.kv_batch`](https://stratadb.org/e/invalid_argument.engine.kv_batch) - [`invalid_argument.engine.kv_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.engine.kv_batch_duplicate_key) - [`invalid_argument.executor.kv_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.executor.kv_batch_duplicate_key) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `kv_batch_put` --- # Batch get KV values Source: https://stratadb.org/docs/reference/kv/batch_get Reads several KV keys and returns positional item results. Each item records whether the corresponding key was found and includes value metadata when present. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Read many keys at once; a missing key comes back as null. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"}' $ strata command run --command-json '{"keys":["YQ==","Yg==","bWlzc2luZw=="],"type":"kv_batch_get"}' ``` ### Wire ```json {"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"} {"keys":["YQ==","Yg==","bWlzc2luZw=="],"type":"kv_batch_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `keys` | `Bytes[]` | yes | Keys to read. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult>`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) - [`invalid_argument.engine.kv_batch`](https://stratadb.org/e/invalid_argument.engine.kv_batch) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `kv_batch_get` --- # Count KV keys Source: https://stratadb.org/docs/reference/kv/count Counts visible KV keys in the selected branch and space, optionally constrained by a key prefix. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Count the visible keys. ### CLI ```console $ strata kv put a 1 $ strata kv put b 2 $ strata kv count ``` ### Wire ```json {"key":"YQ==","type":"kv_put","value":"MQ=="} {"key":"Yg==","type":"kv_put","value":"Mg=="} {"type":"kv_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `prefix` | `Bytes` | no | Optional key prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv count` - Wire type: `kv_count` --- # Delete KV value Source: https://stratadb.org/docs/reference/kv/delete Deletes the current visible value for a KV key. Missing keys produce a no-op delete acknowledgement rather than a read-style missing value. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete a key; it is no longer visible afterward. ### CLI ```console $ strata kv put temp scratch $ strata kv delete temp $ strata kv exists temp ``` ### Wire ```json {"key":"dGVtcA==","type":"kv_put","value":"c2NyYXRjaA=="} {"key":"dGVtcA==","type":"kv_delete"} {"key":"dGVtcA==","type":"kv_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `Bytes` | yes | Key bytes. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv delete` - Wire type: `kv_delete` --- # Check KV existence Source: https://stratadb.org/docs/reference/kv/exists Returns a boolean status for one KV key without loading the stored value. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Check whether a key currently has a visible value. ### CLI ```console $ strata kv put k v $ strata kv exists k $ strata kv exists absent ``` ### Wire ```json {"key":"aw==","type":"kv_put","value":"dg=="} {"key":"aw==","type":"kv_exists"} {"key":"YWJzZW50","type":"kv_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `Bytes` | yes | Key to check. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv exists` - Wire type: `kv_exists` --- # Get KV value Source: https://stratadb.org/docs/reference/kv/get Reads one KV key from the selected branch and space. The optional timestamp reads the value visible at that point in time when history is retained. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read a value back; a missing key returns nothing. ### CLI ```console $ strata kv put greeting hello $ strata kv get greeting $ strata kv get absent ``` ### Wire ```json {"key":"Z3JlZXRpbmc=","type":"kv_put","value":"aGVsbG8="} {"key":"Z3JlZXRpbmc=","type":"kv_get"} {"key":"YWJzZW50","type":"kv_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `key` | `Bytes` | yes | Key bytes. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv get` - Wire type: `kv_get` --- # kv commands Source: https://stratadb.org/docs/reference/kv # `kv` — command reference | Command | Summary | |---|---| | [Batch delete KV values](/docs/reference/kv/batch_delete) | Delete multiple KV keys in one itemwise batch. | | [Batch check KV existence](/docs/reference/kv/batch_exists) | Check existence for multiple KV keys. | | [Batch get KV values](/docs/reference/kv/batch_get) | Read multiple KV values by key. | | [Batch put KV values](/docs/reference/kv/batch_put) | Store multiple KV values in one itemwise batch. | | [Count KV keys](/docs/reference/kv/count) | Count visible KV keys. | | [Delete KV value](/docs/reference/kv/delete) | Delete one visible KV key. | | [Check KV existence](/docs/reference/kv/exists) | Check whether one KV key exists. | | [Get KV value](/docs/reference/kv/get) | Read the current or historical value for one KV key. | | [Read KV history](/docs/reference/kv/history) | Read retained version history for one KV key. | | [List KV keys](/docs/reference/kv/list) | List KV keys with optional prefix filtering. | | [Put KV value](/docs/reference/kv/put) | Store or replace a KV value by key. | | [Sample KV rows](/docs/reference/kv/sample) | Sample visible KV rows. | | [Scan KV rows](/docs/reference/kv/scan) | Scan KV rows with values and version facts. | --- # Read KV history Source: https://stratadb.org/docs/reference/kv/history Returns retained history rows for a KV key when history is available. Missing or unavailable history maps to an optional-read result. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples A key that never existed has no history. ### CLI ```console $ strata kv history absent ``` ### Wire ```json {"key":"YWJzZW50","type":"kv_history"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `Bytes` | yes | Key to read. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe>` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv history` - Wire type: `kv_history` --- # Put KV value Source: https://stratadb.org/docs/reference/kv/put Writes a binary value to the selected KV space. If the key already exists, Strata replaces the visible value and records a new version. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Store a value, then replace it. ### CLI ```console $ strata kv put setting v1 $ strata kv put setting v2 # replaces the visible value $ strata kv get setting ``` ### Wire ```json {"key":"c2V0dGluZw==","type":"kv_put","value":"djE="} {"key":"c2V0dGluZw==","type":"kv_put","value":"djI="} {"key":"c2V0dGluZw==","type":"kv_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `key` | `Bytes` | yes | Key bytes. | | `value` | `Bytes` | yes | Value bytes. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv put` - Wire type: `kv_put` --- # List KV keys Source: https://stratadb.org/docs/reference/kv/list Lists visible KV keys in byte order. Prefix, cursor, limit, and timestamp parameters constrain the page returned by the executor. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List keys under a prefix, in key order. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"dXNlcjox","value":"YQ=="},{"key":"dXNlcjoy","value":"Yg=="},{"key":"b3RoZXI=","value":"Yw=="}],"type":"kv_batch_put"}' $ strata kv list --prefix user: ``` ### Wire ```json {"entries":[{"key":"dXNlcjox","value":"YQ=="},{"key":"dXNlcjoy","value":"Yg=="},{"key":"b3RoZXI=","value":"Yw=="}],"type":"kv_batch_put"} {"prefix":"dXNlcjo=","type":"kv_list"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `cursor` | `Bytes` | no | Optional key cursor. | | `limit` | `integer` | no | Optional item limit. Defaults to 100. | | `prefix` | `Bytes` | no | Optional key prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv list` - Wire type: `kv_list` --- # Sample KV rows Source: https://stratadb.org/docs/reference/kv/sample Returns a deterministic bounded sample of visible KV rows plus the total matching count. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples A representative sample plus the total population size. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="},{"key":"Yw==","value":"Mw=="}],"type":"kv_batch_put"}' $ strata kv sample ``` ### Wire ```json {"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="},{"key":"Yw==","value":"Mw=="}],"type":"kv_batch_put"} {"type":"kv_sample"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `count` | `integer` | no | Optional sample count. Defaults to 10. | | `prefix` | `Bytes` | no | Optional key prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `SamplePage`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv sample` - Wire type: `kv_sample` --- # Scan KV rows Source: https://stratadb.org/docs/reference/kv/scan Scans visible KV rows starting at an optional key. Each item includes the key, value, and commit metadata exposed by the executor output. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples Scan full rows from the start, in key order. ### CLI ```console $ strata command run --command-json '{"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"}' $ strata kv scan ``` ### Wire ```json {"entries":[{"key":"YQ==","value":"MQ=="},{"key":"Yg==","value":"Mg=="}],"type":"kv_batch_put"} {"type":"kv_scan"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `limit` | `integer` | no | Optional row limit. | | `start` | `Bytes` | no | Optional inclusive start key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.kv_key`](https://stratadb.org/e/invalid_argument.engine.kv_key) ## Invocation - CLI: `strata kv scan` - Wire type: `kv_scan` --- # Create product space Source: https://stratadb.org/docs/reference/space/create Creates a product space in the branch catalog. Creation is idempotent: creating a space that already exists succeeds with `created: false` and no mutation effect. Names reserved for engine control data are rejected with `invalid_argument.engine.product_space_reserved`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Create a product space. ### CLI ```console $ strata space create app $ strata space list ``` ### Wire ```json {"space":"app","type":"space_create"} {"type":"space_list"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.product_space_reserved`](https://stratadb.org/e/invalid_argument.engine.product_space_reserved) ## Invocation - CLI: `strata space create` - Wire type: `space_create` --- # Delete product space Source: https://stratadb.org/docs/reference/space/delete Drops the product space from the branch catalog. The `default` space refuses deletion with `invalid_argument.engine.space_delete_default`. A space that still contains visible data refuses deletion with `failed_precondition.engine.space_not_empty` unless `force: true` is set, which tombstones the visible rows first and reports the count. Deleting a space that does not exist succeeds with `deleted: false`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete a product space. ### CLI ```console $ strata space create temp $ strata space delete temp $ strata space exists temp ``` ### Wire ```json {"space":"temp","type":"space_create"} {"space":"temp","type":"space_delete"} {"space":"temp","type":"space_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `force` | `boolean` | no | Delete visible data in the space before dropping the catalog entry. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.product_space_reserved`](https://stratadb.org/e/invalid_argument.engine.product_space_reserved) - [`invalid_argument.engine.space_delete_default`](https://stratadb.org/e/invalid_argument.engine.space_delete_default) - [`failed_precondition.engine.space_not_empty`](https://stratadb.org/e/failed_precondition.engine.space_not_empty) - [`invalid_argument.engine.space_delete_too_large`](https://stratadb.org/e/invalid_argument.engine.space_delete_too_large) ## Invocation - CLI: `strata space delete` - Wire type: `space_delete` --- # Check product space existence Source: https://stratadb.org/docs/reference/space/exists Reports whether the named product space is cataloged on the target branch. A missing space is `false`, not an error; reserved names are rejected with `invalid_argument.engine.product_space_reserved`. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Check whether a product space exists. ### CLI ```console $ strata space create app $ strata space exists app $ strata space exists nope ``` ### Wire ```json {"space":"app","type":"space_create"} {"space":"app","type":"space_exists"} {"space":"nope","type":"space_exists"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.product_space_reserved`](https://stratadb.org/e/invalid_argument.engine.product_space_reserved) ## Invocation - CLI: `strata space exists` - Wire type: `space_exists` --- # space commands Source: https://stratadb.org/docs/reference/space # `space` — command reference | Command | Summary | |---|---| | [Create product space](/docs/reference/space/create) | Create a product space on a branch. | | [Delete product space](/docs/reference/space/delete) | Delete a product space from a branch. | | [Check product space existence](/docs/reference/space/exists) | Check whether a product space exists on a branch. | | [List product spaces](/docs/reference/space/list) | List product spaces on a branch. | --- # List product spaces Source: https://stratadb.org/docs/reference/space/list Lists the product space names cataloged on the target branch as a terminal page. Every branch has a `default` space; additional spaces isolate data namespaces within the same branch. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List product spaces. ### CLI ```console $ strata space create app $ strata space list ``` ### Wire ```json {"space":"app","type":"space_create"} {"type":"space_list"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) ## Invocation - CLI: `strata space list` - Wire type: `space_list` --- # Batch delete vectors Source: https://stratadb.org/docs/reference/vector/batch_delete Deletes multiple vector keys and returns one positional mutation result per input key. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Delete many vectors in one commit. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata command run --command-json '{"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]},{"key":"b","vector":[0.0,1.0,0.0]}],"type":"vector_batch_upsert"}' $ strata command run --command-json '{"collection":"docs","keys":["a","b"],"type":"vector_batch_delete"}' $ strata vector count docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]},{"key":"b","vector":[0.0,1.0,0.0]}],"type":"vector_batch_upsert"} {"collection":"docs","keys":["a","b"],"type":"vector_batch_delete"} {"collection":"docs","type":"vector_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `keys` | `string[]` | yes | Keys to delete. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_batch`](https://stratadb.org/e/invalid_argument.engine.vector_batch) - [`invalid_argument.executor.vector_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.executor.vector_batch_duplicate_key) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `vector_batch_delete` --- # Batch check vector existence Source: https://stratadb.org/docs/reference/vector/batch_exists Checks several vector keys in one collection and returns positional boolean status values. The response preserves the input order. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Check existence for many keys at once. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata command run --command-json '{"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]}],"type":"vector_batch_upsert"}' $ strata command run --command-json '{"collection":"docs","keys":["a","missing"],"type":"vector_batch_exists"}' ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]}],"type":"vector_batch_upsert"} {"collection":"docs","keys":["a","missing"],"type":"vector_batch_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `keys` | `string[]` | yes | Vector keys to check. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `vector_batch_exists` --- # Batch upsert vectors Source: https://stratadb.org/docs/reference/vector/batch_upsert Writes multiple vector entries and returns positional mutation results. Valid items share commit facts where the engine applies them together. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Upsert many vectors in one commit. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata command run --command-json '{"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]},{"key":"b","vector":[0.0,1.0,0.0]}],"type":"vector_batch_upsert"}' $ strata vector count docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]},{"key":"b","vector":[0.0,1.0,0.0]}],"type":"vector_batch_upsert"} {"collection":"docs","type":"vector_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `entries` | `BatchVectorEntry[]` | yes | Entries to write. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_batch`](https://stratadb.org/e/invalid_argument.engine.vector_batch) - [`invalid_argument.engine.vector_dimension`](https://stratadb.org/e/invalid_argument.engine.vector_dimension) - [`invalid_argument.engine.vector_embedding`](https://stratadb.org/e/invalid_argument.engine.vector_embedding) - [`invalid_argument.executor.vector_dimension`](https://stratadb.org/e/invalid_argument.executor.vector_dimension) - [`invalid_argument.executor.vector_batch_duplicate_key`](https://stratadb.org/e/invalid_argument.executor.vector_batch_duplicate_key) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `vector_batch_upsert` --- # Count vectors Source: https://stratadb.org/docs/reference/vector/count Counts vectors visible in the selected collection, branch, and space. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Count vectors in a collection. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector upsert docs b [0.0,1.0,0.0] $ strata vector count docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"b","type":"vector_upsert","vector":[0.0,1.0,0.0]} {"collection":"docs","type":"vector_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `collection` | `string` | yes | Collection name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector count` - Wire type: `vector_count` --- # Batch get vectors Source: https://stratadb.org/docs/reference/vector/batch_get Reads several vector keys and returns positional item results. Each item records found or missing state. Itemwise batches return one positional item result per input item. The outer batch status summarizes whether all, some, or none of the items succeeded. ## Examples Read many vectors at once. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata command run --command-json '{"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]},{"key":"b","vector":[0.0,1.0,0.0]}],"type":"vector_batch_upsert"}' $ strata command run --command-json '{"collection":"docs","keys":["a","b"],"type":"vector_batch_get"}' ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","entries":[{"key":"a","vector":[1.0,0.0,0.0]},{"key":"b","vector":[0.0,1.0,0.0]}],"type":"vector_batch_upsert"} {"collection":"docs","keys":["a","b"],"type":"vector_batch_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `keys` | `string[]` | yes | Keys to read. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `BatchResult>`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_batch`](https://stratadb.org/e/invalid_argument.engine.vector_batch) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `vector_batch_get` --- # Delete vector Source: https://stratadb.org/docs/reference/vector/delete Deletes one visible vector entry from a collection. Missing keys are represented as no-op mutation acknowledgements. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete one vector. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector delete docs a $ strata vector exists docs a ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"a","type":"vector_delete"} {"collection":"docs","key":"a","type":"vector_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `key` | `string` | yes | Vector key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector delete` - Wire type: `vector_delete` --- # Delete all vectors Source: https://stratadb.org/docs/reference/vector/delete_all Deletes all vectors visible in the selected collection while preserving the collection itself. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete every vector in a collection. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector delete-all docs $ strata vector count docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","type":"vector_delete_all"} {"collection":"docs","type":"vector_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector delete-all` - Wire type: `vector_delete_all` --- # Check vector existence Source: https://stratadb.org/docs/reference/vector/exists Returns a boolean status for one vector key without loading the embedding. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Check whether a key exists in a collection. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector exists docs a $ strata vector exists docs absent ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"a","type":"vector_exists"} {"collection":"docs","key":"absent","type":"vector_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `key` | `string` | yes | Vector key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusValue`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector exists` - Wire type: `vector_exists` --- # Delete vectors by filter Source: https://stratadb.org/docs/reference/vector/delete_by_filter Scans the collection for visible vectors matching the metadata filter and deletes the matching rows as a bulk mutation. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete every vector whose metadata matches a filter. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] --metadata {"tag":"keep"} $ strata vector upsert docs b [0.0,1.0,0.0] --metadata {"tag":"drop"} $ strata vector delete-by-filter docs {"conditions":[{"field":"tag","op":"eq","value":{"type":"string","value":"drop"}}]} $ strata vector count docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","metadata":{"tag":"keep"},"type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"b","metadata":{"tag":"drop"},"type":"vector_upsert","vector":[0.0,1.0,0.0]} {"collection":"docs","filter":{"conditions":[{"field":"tag","op":"eq","value":{"type":"string","value":"drop"}}]},"type":"vector_delete_by_filter"} {"collection":"docs","type":"vector_count"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `filter` | `VectorMetadataFilter` | yes | Metadata filter. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_filter`](https://stratadb.org/e/invalid_argument.engine.vector_filter) ## Invocation - CLI: `strata vector delete-by-filter` - Wire type: `vector_delete_by_filter` --- # Get vector Source: https://stratadb.org/docs/reference/vector/get Reads one visible vector entry. The optional timestamp reads the vector visible at that point in time when retained history allows it. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read a stored vector, or nothing if the key is absent. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector get docs a $ strata vector get docs absent ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"a","type":"vector_get"} {"collection":"docs","key":"absent","type":"vector_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `collection` | `string` | yes | Collection name. | | `key` | `string` | yes | Vector key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector get` - Wire type: `vector_get` --- # Read vector history Source: https://stratadb.org/docs/reference/vector/history Returns retained history rows for one vector key, including vector revision facts and tombstones when present. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples A key that never existed has no history. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector history docs absent ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"absent","type":"vector_history"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `key` | `string` | yes | Vector key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe>` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector history` - Wire type: `vector_history` --- # vector commands Source: https://stratadb.org/docs/reference/vector # `vector` — command reference | Command | Summary | |---|---| | [Batch delete vectors](/docs/reference/vector/batch_delete) | Delete multiple vectors by key. | | [Batch check vector existence](/docs/reference/vector/batch_exists) | Check existence for multiple vector keys. | | [Batch get vectors](/docs/reference/vector/batch_get) | Read multiple vectors by key. | | [Batch upsert vectors](/docs/reference/vector/batch_upsert) | Upsert multiple vectors in one itemwise batch. | | [Create vector collection](/docs/reference/vector/collection/create) | Create a vector collection with a dimension and metric. | | [Delete vector collection](/docs/reference/vector/collection/delete) | Delete a vector collection. | | [List vector collections](/docs/reference/vector/collection/list) | List vector collections. | | [Read vector collection stats](/docs/reference/vector/collection/stats) | Read facts for one vector collection. | | [Count vectors](/docs/reference/vector/count) | Count visible vectors in a collection. | | [Delete vector](/docs/reference/vector/delete) | Delete one vector key. | | [Delete all vectors](/docs/reference/vector/delete_all) | Delete all vectors in a collection. | | [Delete vectors by filter](/docs/reference/vector/delete_by_filter) | Delete vectors matching a metadata filter. | | [Check vector existence](/docs/reference/vector/exists) | Check whether one vector key exists. | | [Get vector](/docs/reference/vector/get) | Read one vector by key. | | [Read vector history](/docs/reference/vector/history) | Read retained vector history for one key. | | [Query vector index](/docs/reference/vector/index/query) | Search vectors and return index diagnostics. | | [List vector keys](/docs/reference/vector/keys) | List vector keys in a collection. | | [Update vector metadata](/docs/reference/vector/metadata/update) | Patch metadata for one vector. | | [Query vectors](/docs/reference/vector/query) | Search a vector collection. | | [Sample vectors](/docs/reference/vector/sample) | Sample vectors with values and version facts. | | [Scan vectors](/docs/reference/vector/scan) | Scan vectors with values and version facts. | | [Upsert vector](/docs/reference/vector/upsert) | Insert or replace one vector. | --- # List vector keys Source: https://stratadb.org/docs/reference/vector/keys Lists visible vector keys with optional prefix and cursor arguments. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List keys in a collection, in key order. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector upsert docs b [0.0,1.0,0.0] $ strata vector keys docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"b","type":"vector_upsert","vector":[0.0,1.0,0.0]} {"collection":"docs","type":"vector_list_keys"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `collection` | `string` | yes | Collection name. | | `cursor` | `string` | no | Optional key cursor. | | `limit` | `integer` | no | Optional item limit. Defaults to 100. | | `prefix` | `string` | no | Optional key prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector keys` - Wire type: `vector_list_keys` --- # Scan vectors Source: https://stratadb.org/docs/reference/vector/scan Scans visible vectors in a collection starting at an optional key. Each item includes the key, embedding, metadata, and commit metadata exposed by the executor output. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples Scan stored vectors from the start, in key order. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector upsert docs b [0.0,1.0,0.0] $ strata vector scan docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"b","type":"vector_upsert","vector":[0.0,1.0,0.0]} {"collection":"docs","type":"vector_scan"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `limit` | `integer` | no | Optional row limit. | | `start` | `string` | no | Optional inclusive start key. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector scan` - Wire type: `vector_scan` --- # Query vectors Source: https://stratadb.org/docs/reference/vector/query Runs vector search through the engine planner and returns the best matches with scores and optional metadata. Search responses return a bounded list of matches ordered by the engine. They are not cursor pages unless a later command explicitly advertises pagination. ## Examples Find the nearest vectors to a query vector. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector upsert docs b [0.0,1.0,0.0] $ strata vector query docs [1.0,0.0,0.0] 2 ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"b","type":"vector_upsert","vector":[0.0,1.0,0.0]} {"collection":"docs","k":2,"query":[1.0,0.0,0.0],"type":"vector_query"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `collection` | `string` | yes | Collection name. | | `filter` | `VectorMetadataFilter` | no | Optional metadata filter. | | `k` | `integer` | yes | Maximum number of matches. | | `query` | `number[]` | yes | Query embedding. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `SearchResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_filter`](https://stratadb.org/e/invalid_argument.engine.vector_filter) - [`invalid_argument.executor.vector_limit`](https://stratadb.org/e/invalid_argument.executor.vector_limit) ## Invocation - CLI: `strata vector query` - Wire type: `vector_query` --- # Sample vectors Source: https://stratadb.org/docs/reference/vector/sample Returns a deterministic representative sample of vectors from a collection: the total live count and up to `count` entries (default 10), evenly strided over the ordered keys. Latest state only. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples A representative sample of stored vectors plus the total count. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector upsert docs b [0.0,1.0,0.0] $ strata vector sample docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"b","type":"vector_upsert","vector":[0.0,1.0,0.0]} {"collection":"docs","type":"vector_sample"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `count` | `integer` | no | Optional sample count. Defaults to 10. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `SamplePage`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector sample` - Wire type: `vector_sample` --- # Upsert vector Source: https://stratadb.org/docs/reference/vector/upsert Upserts one vector key with a dense embedding and optional metadata. The vector dimension must match the collection configuration. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Insert or replace a vector with optional metadata. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] --metadata {"tag":"x"} $ strata vector exists docs a ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","metadata":{"tag":"x"},"type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"a","type":"vector_exists"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `key` | `string` | yes | Vector key. | | `metadata` | `any` | no | Optional metadata. | | `vector` | `number[]` | yes | Dense embedding. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_dimension`](https://stratadb.org/e/invalid_argument.engine.vector_dimension) - [`invalid_argument.engine.vector_embedding`](https://stratadb.org/e/invalid_argument.engine.vector_embedding) - [`invalid_argument.engine.vector_metadata`](https://stratadb.org/e/invalid_argument.engine.vector_metadata) - [`invalid_argument.executor.vector_dimension`](https://stratadb.org/e/invalid_argument.executor.vector_dimension) ## Invocation - CLI: `strata vector upsert` - Wire type: `vector_upsert` --- # Traverse graph breadth-first Source: https://stratadb.org/docs/reference/graph/analytics/bfs Runs a breadth-first traversal from a start node over a consistent snapshot, bounded by `max_depth` (default 100) and `max_nodes` (default 10000). Returns visited node ids in traversal order, a depth per node, and the tree edges in discovery order. Direction defaults to `outgoing`; an optional edge-type list restricts every hop. The start node must exist (`not_found.engine.graph_node`). Analytics commands compute over a consistent snapshot of the visible graph and return a complete result payload in one response. They accept optional snapshot budgets and an `as_of` timestamp for time travel; results are deterministic for a fixed graph state. ## Examples Breadth-first traversal from a start node. ### CLI ```console $ strata graph create g $ strata graph add-node g a $ strata graph add-node g b $ strata graph add-node g c $ strata graph add-edge g a knows b $ strata graph add-edge g b knows c $ strata graph bfs g a ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","type":"graph_add_node"} {"graph":"g","node_id":"b","type":"graph_add_node"} {"graph":"g","node_id":"c","type":"graph_add_node"} {"dst":"b","edge_type":"knows","graph":"g","src":"a","type":"graph_add_edge"} {"dst":"c","edge_type":"knows","graph":"g","src":"b","type":"graph_add_edge"} {"graph":"g","start":"a","type":"graph_bfs"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `budget` | `GraphAnalyticsBudget` | no | Optional snapshot size bounds. Defaults to the engine limits. | | `direction` | `GraphDirection` | no | Optional traversal direction. Defaults to outgoing. | | `edge_types` | `string[]` | no | Optional edge-type restriction applied at every hop. | | `graph` | `string` | yes | Graph name. | | `max_depth` | `integer` | no | Optional depth bound. Defaults to 100. | | `max_nodes` | `integer` | no | Optional visited-node bound. Defaults to 10000. | | `start` | `string` | yes | Start node id. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `AnalyticsResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_edge_type`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type) - [`not_found.engine.graph_node`](https://stratadb.org/e/not_found.engine.graph_node) - [`resource_exhausted.engine.graph_analytics_budget`](https://stratadb.org/e/resource_exhausted.engine.graph_analytics_budget) - [`invalid_argument.executor.graph_analytics_budget`](https://stratadb.org/e/invalid_argument.executor.graph_analytics_budget) ## Invocation - CLI: `strata graph bfs` - Wire type: `graph_bfs` --- # Detect graph communities Source: https://stratadb.org/docs/reference/graph/analytics/cdlp Detects communities by label propagation over a consistent snapshot: every node repeatedly adopts the most common label among its neighbors until labels stabilize or the iteration bound (default 10) is reached. Every node maps to its community representative node id. Propagation direction defaults to `both`. Accepts an optional snapshot budget and `as_of` for time travel. Analytics commands compute over a consistent snapshot of the visible graph and return a complete result payload in one response. They accept optional snapshot budgets and an `as_of` timestamp for time travel; results are deterministic for a fixed graph state. ## Examples Community detection by label propagation. ### CLI ```console $ strata graph create g $ strata graph add-node g a $ strata graph add-node g b $ strata graph add-node g c $ strata graph add-edge g a knows b $ strata graph add-edge g b knows c $ strata graph cdlp g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","type":"graph_add_node"} {"graph":"g","node_id":"b","type":"graph_add_node"} {"graph":"g","node_id":"c","type":"graph_add_node"} {"dst":"b","edge_type":"knows","graph":"g","src":"a","type":"graph_add_edge"} {"dst":"c","edge_type":"knows","graph":"g","src":"b","type":"graph_add_edge"} {"graph":"g","type":"graph_cdlp"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `budget` | `GraphAnalyticsBudget` | no | Optional snapshot size bounds. Defaults to the engine limits. | | `direction` | `GraphDirection` | no | Optional propagation direction. Defaults to both. | | `graph` | `string` | yes | Graph name. | | `max_iterations` | `integer` | no | Optional iteration bound. Defaults to 10. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `AnalyticsResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`resource_exhausted.engine.graph_analytics_budget`](https://stratadb.org/e/resource_exhausted.engine.graph_analytics_budget) - [`invalid_argument.executor.graph_analytics_budget`](https://stratadb.org/e/invalid_argument.executor.graph_analytics_budget) ## Invocation - CLI: `strata graph cdlp` - Wire type: `graph_cdlp` --- # Compute graph clustering coefficients Source: https://stratadb.org/docs/reference/graph/analytics/lcc Computes the local clustering coefficient for every node over a consistent snapshot: the fraction of a node's neighbor pairs that are themselves connected. Nodes in fully-triangulated neighborhoods score 1.0. Accepts an optional snapshot budget and `as_of` for time travel. Analytics commands compute over a consistent snapshot of the visible graph and return a complete result payload in one response. They accept optional snapshot budgets and an `as_of` timestamp for time travel; results are deterministic for a fixed graph state. ## Examples Local clustering coefficient per node. ### CLI ```console $ strata graph create g $ strata graph add-node g a $ strata graph add-node g b $ strata graph add-node g c $ strata graph add-edge g a knows b $ strata graph add-edge g b knows c $ strata graph lcc g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","type":"graph_add_node"} {"graph":"g","node_id":"b","type":"graph_add_node"} {"graph":"g","node_id":"c","type":"graph_add_node"} {"dst":"b","edge_type":"knows","graph":"g","src":"a","type":"graph_add_edge"} {"dst":"c","edge_type":"knows","graph":"g","src":"b","type":"graph_add_edge"} {"graph":"g","type":"graph_lcc"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `budget` | `GraphAnalyticsBudget` | no | Optional snapshot size bounds. Defaults to the engine limits. | | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `AnalyticsResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`resource_exhausted.engine.graph_analytics_budget`](https://stratadb.org/e/resource_exhausted.engine.graph_analytics_budget) - [`invalid_argument.executor.graph_analytics_budget`](https://stratadb.org/e/invalid_argument.executor.graph_analytics_budget) ## Invocation - CLI: `strata graph lcc` - Wire type: `graph_lcc` --- # Compute graph pagerank Source: https://stratadb.org/docs/reference/graph/analytics/pagerank Computes PageRank over a consistent snapshot. Tunable damping (default 0.85), iteration bound (default 20), and convergence tolerance (default 1e-6); the response reports how many iterations actually ran. Optional personalization seeds steer both teleport and dangling mass toward weighted nodes, and the response flags `personalized: true`. Results are deterministic for a fixed graph state. Accepts an optional snapshot budget and `as_of` for time travel. Analytics commands compute over a consistent snapshot of the visible graph and return a complete result payload in one response. They accept optional snapshot budgets and an `as_of` timestamp for time travel; results are deterministic for a fixed graph state. ## Examples Compute PageRank importance scores. ### CLI ```console $ strata graph create g $ strata graph add-node g a $ strata graph add-node g b $ strata graph add-node g c $ strata graph add-edge g a knows b $ strata graph add-edge g b knows c $ strata graph pagerank g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","type":"graph_add_node"} {"graph":"g","node_id":"b","type":"graph_add_node"} {"graph":"g","node_id":"c","type":"graph_add_node"} {"dst":"b","edge_type":"knows","graph":"g","src":"a","type":"graph_add_edge"} {"dst":"c","edge_type":"knows","graph":"g","src":"b","type":"graph_add_edge"} {"graph":"g","type":"graph_pagerank"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `budget` | `GraphAnalyticsBudget` | no | Optional snapshot size bounds. Defaults to the engine limits. | | `damping` | `number` | no | Optional damping factor. Defaults to 0.85. | | `graph` | `string` | yes | Graph name. | | `max_iterations` | `integer` | no | Optional iteration bound. Defaults to 20. | | `personalization` | `object` | no | Optional seed weights (node id to weight). When present, both teleport and dangling mass follow the seeds. | | `tolerance` | `number` | no | Optional convergence tolerance. Defaults to 1e-6. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `AnalyticsResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_pagerank_options`](https://stratadb.org/e/invalid_argument.engine.graph_pagerank_options) - [`invalid_argument.engine.graph_personalization`](https://stratadb.org/e/invalid_argument.engine.graph_personalization) - [`resource_exhausted.engine.graph_analytics_budget`](https://stratadb.org/e/resource_exhausted.engine.graph_analytics_budget) - [`invalid_argument.executor.graph_analytics_budget`](https://stratadb.org/e/invalid_argument.executor.graph_analytics_budget) ## Invocation - CLI: `strata graph pagerank` - Wire type: `graph_pagerank` --- # Compute graph connected components Source: https://stratadb.org/docs/reference/graph/analytics/wcc Computes weakly connected components over a consistent snapshot of the graph, ignoring edge direction. Every node maps to its component representative - the smallest node id in its component - and the response carries the distinct component count. Accepts an optional snapshot budget and `as_of` for time travel. Analytics commands compute over a consistent snapshot of the visible graph and return a complete result payload in one response. They accept optional snapshot budgets and an `as_of` timestamp for time travel; results are deterministic for a fixed graph state. ## Examples Weakly-connected components. ### CLI ```console $ strata graph create g $ strata graph add-node g a $ strata graph add-node g b $ strata graph add-node g c $ strata graph add-edge g a knows b $ strata graph add-edge g b knows c $ strata graph wcc g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","type":"graph_add_node"} {"graph":"g","node_id":"b","type":"graph_add_node"} {"graph":"g","node_id":"c","type":"graph_add_node"} {"dst":"b","edge_type":"knows","graph":"g","src":"a","type":"graph_add_edge"} {"dst":"c","edge_type":"knows","graph":"g","src":"b","type":"graph_add_edge"} {"graph":"g","type":"graph_wcc"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `budget` | `GraphAnalyticsBudget` | no | Optional snapshot size bounds. Defaults to the engine limits. | | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `AnalyticsResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`resource_exhausted.engine.graph_analytics_budget`](https://stratadb.org/e/resource_exhausted.engine.graph_analytics_budget) - [`invalid_argument.executor.graph_analytics_budget`](https://stratadb.org/e/invalid_argument.executor.graph_analytics_budget) ## Invocation - CLI: `strata graph wcc` - Wire type: `graph_wcc` --- # Add graph edge Source: https://stratadb.org/docs/reference/graph/edge/add Adds a directed edge `src -[edge_type]-> dst` or replaces it if the same triple already exists. Both endpoints must already exist; writing an edge to a missing node fails with `invalid_argument.engine.graph_edge_endpoint`. Weight defaults to 1.0 and must not be negative. Once the graph's ontology is frozen, the edge type and its endpoint object types are validated against the declared link types. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Add a typed edge between two nodes. ### CLI ```console $ strata graph create social $ strata graph add-node social alice $ strata graph add-node social bob $ strata graph add-edge social alice knows bob $ strata graph get-edge social alice knows bob ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","type":"graph_add_node"} {"graph":"social","node_id":"bob","type":"graph_add_node"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_add_edge"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_get_edge"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `dst` | `string` | yes | Destination node id. | | `edge_type` | `string` | yes | Edge type. | | `graph` | `string` | yes | Graph name. | | `properties` | `any` | no | Optional edge properties. | | `src` | `string` | yes | Source node id. | | `weight` | `number` | no | Optional edge weight. Defaults to 1.0. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_edge_type`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type) - [`invalid_argument.engine.graph_edge_type_reserved`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type_reserved) - [`invalid_argument.engine.graph_edge_weight`](https://stratadb.org/e/invalid_argument.engine.graph_edge_weight) - [`invalid_argument.engine.graph_edge_endpoint`](https://stratadb.org/e/invalid_argument.engine.graph_edge_endpoint) - [`invalid_argument.engine.graph_properties`](https://stratadb.org/e/invalid_argument.engine.graph_properties) - [`invalid_argument.engine.graph_properties_too_large`](https://stratadb.org/e/invalid_argument.engine.graph_properties_too_large) - [`failed_precondition.engine.graph_negative_weight`](https://stratadb.org/e/failed_precondition.engine.graph_negative_weight) - [`failed_precondition.engine.graph_ontology_edge_type`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_edge_type) - [`failed_precondition.engine.graph_ontology_endpoint_type`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_endpoint_type) ## Invocation - CLI: `strata graph add-edge` - Wire type: `graph_add_edge` --- # Compute graph shortest paths Source: https://stratadb.org/docs/reference/graph/analytics/sssp Computes weighted shortest-path distances from a source node over a consistent snapshot. Edge weights (default 1.0) accumulate along paths; unreachable nodes are omitted from the result. Direction defaults to `outgoing`. The source node must exist (`not_found.engine.graph_node`). Accepts an optional snapshot budget and `as_of` for time travel. Analytics commands compute over a consistent snapshot of the visible graph and return a complete result payload in one response. They accept optional snapshot budgets and an `as_of` timestamp for time travel; results are deterministic for a fixed graph state. ## Examples Single-source shortest paths from a source node. ### CLI ```console $ strata graph create g $ strata graph add-node g a $ strata graph add-node g b $ strata graph add-node g c $ strata graph add-edge g a knows b $ strata graph add-edge g b knows c $ strata graph sssp g a ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","node_id":"a","type":"graph_add_node"} {"graph":"g","node_id":"b","type":"graph_add_node"} {"graph":"g","node_id":"c","type":"graph_add_node"} {"dst":"b","edge_type":"knows","graph":"g","src":"a","type":"graph_add_edge"} {"dst":"c","edge_type":"knows","graph":"g","src":"b","type":"graph_add_edge"} {"graph":"g","source":"a","type":"graph_sssp"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `budget` | `GraphAnalyticsBudget` | no | Optional snapshot size bounds. Defaults to the engine limits. | | `direction` | `GraphDirection` | no | Optional traversal direction. Defaults to outgoing. | | `graph` | `string` | yes | Graph name. | | `source` | `string` | yes | Source node id. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `AnalyticsResult`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`not_found.engine.graph_node`](https://stratadb.org/e/not_found.engine.graph_node) - [`resource_exhausted.engine.graph_analytics_budget`](https://stratadb.org/e/resource_exhausted.engine.graph_analytics_budget) - [`invalid_argument.executor.graph_analytics_budget`](https://stratadb.org/e/invalid_argument.executor.graph_analytics_budget) ## Invocation - CLI: `strata graph sssp` - Wire type: `graph_sssp` --- # Get graph edge Source: https://stratadb.org/docs/reference/graph/edge/get Reads one edge by its `(src, edge_type, dst)` triple, returning its weight, properties, and last-write commit coordinates. A missing edge reads back as no data. Accepts `as_of` for time travel. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read an edge, or nothing if absent. ### CLI ```console $ strata graph create social $ strata graph add-node social alice $ strata graph add-node social bob $ strata graph add-edge social alice knows bob $ strata graph get-edge social alice knows bob $ strata graph get-edge social alice knows absent ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","type":"graph_add_node"} {"graph":"social","node_id":"bob","type":"graph_add_node"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_add_edge"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_get_edge"} {"dst":"absent","edge_type":"knows","graph":"social","src":"alice","type":"graph_get_edge"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `dst` | `string` | yes | Destination node id. | | `edge_type` | `string` | yes | Edge type. | | `graph` | `string` | yes | Graph name. | | `src` | `string` | yes | Source node id. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_edge_type`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type) ## Invocation - CLI: `strata graph get-edge` - Wire type: `graph_get_edge` --- # Remove graph edge Source: https://stratadb.org/docs/reference/graph/edge/remove Removes one directed edge by its `(src, edge_type, dst)` triple. The endpoints are untouched. Removing an edge that does not exist is not an error: the acknowledgement reports `deleted: false`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Remove an edge. ### CLI ```console $ strata graph create social $ strata graph add-node social alice $ strata graph add-node social bob $ strata graph add-edge social alice knows bob $ strata graph remove-edge social alice knows bob $ strata graph get-edge social alice knows bob ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","type":"graph_add_node"} {"graph":"social","node_id":"bob","type":"graph_add_node"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_add_edge"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_remove_edge"} {"dst":"bob","edge_type":"knows","graph":"social","src":"alice","type":"graph_get_edge"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `dst` | `string` | yes | Destination node id. | | `edge_type` | `string` | yes | Edge type. | | `graph` | `string` | yes | Graph name. | | `src` | `string` | yes | Source node id. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_edge_type`](https://stratadb.org/e/invalid_argument.engine.graph_edge_type) ## Invocation - CLI: `strata graph remove-edge` - Wire type: `graph_remove_edge` --- # Add graph node Source: https://stratadb.org/docs/reference/graph/node/add Adds a node to a graph or replaces it if the node id already exists. A node carries optional JSON properties, an optional declared object type (validated once the graph's ontology is frozen), and an optional entity binding that links the node to a row in another primitive. Cross-branch bindings are rejected. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Add a node with an object type and properties. ### CLI ```console $ strata graph create social $ strata graph add-node social alice --object-type person --properties {"age":30} $ strata graph get-node social alice ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","object_type":"person","properties":{"age":30},"type":"graph_add_node"} {"graph":"social","node_id":"alice","type":"graph_get_node"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `binding` | `GraphEntityBinding` | no | Optional entity binding. | | `graph` | `string` | yes | Graph name. | | `node_id` | `string` | yes | Node id. | | `object_type` | `string` | no | Optional declared object type (validated once the ontology is frozen). | | `properties` | `any` | no | Optional node properties. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) - [`invalid_argument.engine.graph_properties`](https://stratadb.org/e/invalid_argument.engine.graph_properties) - [`invalid_argument.engine.graph_properties_too_large`](https://stratadb.org/e/invalid_argument.engine.graph_properties_too_large) - [`invalid_argument.engine.graph_type_hint`](https://stratadb.org/e/invalid_argument.engine.graph_type_hint) - [`invalid_argument.engine.graph_binding`](https://stratadb.org/e/invalid_argument.engine.graph_binding) - [`unsupported.engine.graph_binding_cross_branch`](https://stratadb.org/e/unsupported.engine.graph_binding_cross_branch) - [`failed_precondition.engine.graph_ontology_node_type`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_node_type) - [`failed_precondition.engine.graph_ontology_required_property`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_required_property) ## Invocation - CLI: `strata graph add-node` - Wire type: `graph_add_node` --- # Get graph node Source: https://stratadb.org/docs/reference/graph/node/get Reads one node by id, returning its properties, declared object type, entity binding, and last-write commit coordinates. A removed or never-written node reads back as no data. Accepts `as_of` for time travel. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read a node's properties, or nothing if absent. ### CLI ```console $ strata graph create social $ strata graph add-node social alice --object-type person --properties {"age":30} $ strata graph get-node social alice $ strata graph get-node social absent ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","object_type":"person","properties":{"age":30},"type":"graph_add_node"} {"graph":"social","node_id":"alice","type":"graph_get_node"} {"graph":"social","node_id":"absent","type":"graph_get_node"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `graph` | `string` | yes | Graph name. | | `node_id` | `string` | yes | Node id. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) ## Invocation - CLI: `strata graph get-node` - Wire type: `graph_get_node` --- # List graph nodes Source: https://stratadb.org/docs/reference/graph/node/list Lists a graph's nodes in node-id order. Accepts an optional id prefix filter, an item limit (default 100), an exclusive cursor, and `as_of` for time travel. Each item carries the full node payload: properties, declared type, binding, and commit coordinates. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List node ids in a graph, in id order. ### CLI ```console $ strata graph create social $ strata graph add-node social alice $ strata graph add-node social bob $ strata graph list-nodes social ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","type":"graph_add_node"} {"graph":"social","node_id":"bob","type":"graph_add_node"} {"graph":"social","type":"graph_list_nodes"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `cursor` | `string` | no | Optional exclusive node id cursor. | | `graph` | `string` | yes | Graph name. | | `limit` | `integer` | no | Optional item limit. Defaults to 100. | | `prefix` | `string` | no | Optional node id prefix. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) ## Invocation - CLI: `strata graph list-nodes` - Wire type: `graph_list_nodes` --- # Remove graph node Source: https://stratadb.org/docs/reference/graph/node/remove Removes a node and every edge incident to it in one commit. Removing a node that does not exist is not an error: the acknowledgement reports `deleted: false`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Remove a node. ### CLI ```console $ strata graph create social $ strata graph add-node social alice $ strata graph remove-node social alice $ strata graph get-node social alice ``` ### Wire ```json {"graph":"social","type":"graph_create"} {"graph":"social","node_id":"alice","type":"graph_add_node"} {"graph":"social","node_id":"alice","type":"graph_remove_node"} {"graph":"social","node_id":"alice","type":"graph_get_node"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | | `node_id` | `string` | yes | Node id. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_node_id`](https://stratadb.org/e/invalid_argument.engine.graph_node_id) ## Invocation - CLI: `strata graph remove-node` - Wire type: `graph_remove_node` --- # Define graph link type Source: https://stratadb.org/docs/reference/graph/ontology/define_link_type Declares a link type in the graph's ontology: a name, its source and target object types, an optional cardinality hint (for example `many-to-one`), and property definitions. Source and target must name declared object types by the time the ontology is frozen. After freezing, this command fails with `failed_precondition.engine.graph_ontology_frozen`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Define a link (edge) type between two object types. ### CLI ```console $ strata graph create g $ strata graph ontology define-object-type g person $ strata graph ontology define-link-type g knows person person $ strata graph ontology get g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","name":"person","type":"graph_define_object_type"} {"graph":"g","name":"knows","source":"person","target":"person","type":"graph_define_link_type"} {"graph":"g","type":"graph_get_ontology"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `cardinality` | `string` | no | Optional cardinality hint (e.g. `one-to-many`). | | `graph` | `string` | yes | Graph name. | | `name` | `string` | yes | Link type name. | | `properties` | `object` | no | Declared properties by name. | | `source` | `string` | yes | Declared source object type. | | `target` | `string` | yes | Declared target object type. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_type_name`](https://stratadb.org/e/invalid_argument.engine.graph_type_name) - [`invalid_argument.engine.graph_type_name_reserved`](https://stratadb.org/e/invalid_argument.engine.graph_type_name_reserved) - [`invalid_argument.engine.graph_property_name`](https://stratadb.org/e/invalid_argument.engine.graph_property_name) - [`failed_precondition.engine.graph_ontology_frozen`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_frozen) ## Invocation - CLI: `strata graph ontology define-link-type` - Wire type: `graph_define_link_type` --- # Define graph object type Source: https://stratadb.org/docs/reference/graph/ontology/define_object_type Declares an object type in the graph's ontology: a name plus property definitions (`value_type`, `required`). While the ontology is a draft, redefining a type replaces it freely. After `graph.ontology.freeze`, the ontology is immutable and this command fails with `failed_precondition.engine.graph_ontology_frozen`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Define an object (node) type. ### CLI ```console $ strata graph create g $ strata graph ontology define-object-type g person $ strata graph ontology summary g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","name":"person","type":"graph_define_object_type"} {"graph":"g","type":"graph_ontology_summary"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | | `name` | `string` | yes | Object type name. | | `properties` | `object` | no | Declared properties by name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_type_name`](https://stratadb.org/e/invalid_argument.engine.graph_type_name) - [`invalid_argument.engine.graph_type_name_reserved`](https://stratadb.org/e/invalid_argument.engine.graph_type_name_reserved) - [`invalid_argument.engine.graph_property_name`](https://stratadb.org/e/invalid_argument.engine.graph_property_name) - [`failed_precondition.engine.graph_ontology_frozen`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_frozen) ## Invocation - CLI: `strata graph ontology define-object-type` - Wire type: `graph_define_object_type` --- # Delete graph link type Source: https://stratadb.org/docs/reference/graph/ontology/delete_link_type Removes a link type from the graph's draft ontology. Deleting a type that was never declared is not an error: the acknowledgement reports `deleted: false`. Once the ontology is frozen this command fails with `failed_precondition.engine.graph_ontology_frozen`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Remove a link type from the ontology. ### CLI ```console $ strata graph create g $ strata graph ontology define-object-type g person $ strata graph ontology define-link-type g knows person person $ strata graph ontology delete-link-type g knows ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","name":"person","type":"graph_define_object_type"} {"graph":"g","name":"knows","source":"person","target":"person","type":"graph_define_link_type"} {"graph":"g","name":"knows","type":"graph_delete_link_type"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | | `name` | `string` | yes | Link type name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_type_name`](https://stratadb.org/e/invalid_argument.engine.graph_type_name) - [`failed_precondition.engine.graph_ontology_frozen`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_frozen) ## Invocation - CLI: `strata graph ontology delete-link-type` - Wire type: `graph_delete_link_type` --- # Delete graph object type Source: https://stratadb.org/docs/reference/graph/ontology/delete_object_type Removes an object type from the graph's draft ontology. Deleting a type that was never declared is not an error: the acknowledgement reports `deleted: false`. Once the ontology is frozen this command fails with `failed_precondition.engine.graph_ontology_frozen`. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Remove an object type from the ontology. ### CLI ```console $ strata graph create g $ strata graph ontology define-object-type g person $ strata graph ontology define-object-type g company $ strata graph ontology delete-object-type g company $ strata graph ontology summary g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","name":"person","type":"graph_define_object_type"} {"graph":"g","name":"company","type":"graph_define_object_type"} {"graph":"g","name":"company","type":"graph_delete_object_type"} {"graph":"g","type":"graph_ontology_summary"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | | `name` | `string` | yes | Object type name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`invalid_argument.engine.graph_type_name`](https://stratadb.org/e/invalid_argument.engine.graph_type_name) - [`failed_precondition.engine.graph_ontology_frozen`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_frozen) ## Invocation - CLI: `strata graph ontology delete-object-type` - Wire type: `graph_delete_object_type` --- # Freeze graph ontology Source: https://stratadb.org/docs/reference/graph/ontology/freeze Validates the draft ontology and freezes it. Validation requires at least one declared type and rejects link types whose source or target reference undeclared object types (`failed_precondition.engine.graph_ontology_freeze`). After freezing, writes enforce declared node object types, required properties, and link-type endpoint rules; the ontology itself can no longer change (`failed_precondition.engine.graph_ontology_frozen`). Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Freeze the ontology so its types can no longer change. ### CLI ```console $ strata graph create g $ strata graph ontology define-object-type g person $ strata graph ontology freeze g $ strata graph ontology get g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","name":"person","type":"graph_define_object_type"} {"graph":"g","type":"graph_freeze_ontology"} {"graph":"g","type":"graph_get_ontology"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) - [`failed_precondition.engine.graph_ontology_freeze`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_freeze) - [`failed_precondition.engine.graph_ontology_frozen`](https://stratadb.org/e/failed_precondition.engine.graph_ontology_frozen) ## Invocation - CLI: `strata graph ontology freeze` - Wire type: `graph_freeze_ontology` --- # Read graph ontology Source: https://stratadb.org/docs/reference/graph/ontology/get Reads the graph's ontology: its status (`draft` or `frozen`) plus every declared object type and link type with their property definitions. Returns no data before any type has been declared. Accepts `as_of` for time travel. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Read the ontology's status. ### CLI ```console $ strata graph create g $ strata graph ontology define-object-type g person $ strata graph ontology get g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","name":"person","type":"graph_define_object_type"} {"graph":"g","type":"graph_get_ontology"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) ## Invocation - CLI: `strata graph ontology get` - Wire type: `graph_get_ontology` --- # Read graph ontology summary Source: https://stratadb.org/docs/reference/graph/ontology/summary Reads the graph's ontology annotated with per-type usage: a node count for each object type and an edge count for each link type. Returns no data before any type has been declared. Accepts `as_of` for time travel. Optional reads distinguish present data from missing data. When version or timestamp facts exist on the executor output, SDK mappings should preserve them. ## Examples Summarize the ontology's object types. ### CLI ```console $ strata graph create g $ strata graph ontology define-object-type g person $ strata graph ontology summary g ``` ### Wire ```json {"graph":"g","type":"graph_create"} {"graph":"g","name":"person","type":"graph_define_object_type"} {"graph":"g","type":"graph_ontology_summary"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. Reads the graph state visible at that instant. | | `graph` | `string` | yes | Graph name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Maybe` — a miss returns nothing rather than raising. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.graph_name`](https://stratadb.org/e/invalid_argument.engine.graph_name) - [`not_found.engine.graph`](https://stratadb.org/e/not_found.engine.graph) ## Invocation - CLI: `strata graph ontology summary` - Wire type: `graph_ontology_summary` --- # List catalog models Source: https://stratadb.org/docs/reference/inference/models/list Lists every model in Strata's built-in catalog as a terminal page. Each entry reports the model's task (embed, generate, or rank), architecture, default quantization, embedding dimension, HuggingFace repository, approximate artifact size, and whether the model artifact is already present in the local model directory. Use `inference models local` to see only the downloaded models, or `inference models pull` to fetch one. ## Examples List the built-in model catalog (spans embedding, generation, ranking). ### CLI ```console $ strata inference models list ``` ### Wire ```json {"type":"inference_models_list"} ``` ## Parameters _No parameters._ ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) ## Invocation - CLI: `strata inference models list` - Wire type: `inference_models_list` --- # List local models Source: https://stratadb.org/docs/reference/inference/models/local Lists the catalog models that have at least one quantization variant present in the local model directory, as a terminal page. Entries carry the same facts as `inference models list` but are restricted to models that can run without a further download. The local model directory is resolved from `STRATA_MODELS_DIR`, falling back to `~/.strata/models`. ## Parameters _No parameters._ ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) ## Invocation - CLI: `strata inference models local` - Wire type: `inference_models_local` --- # Download a model Source: https://stratadb.org/docs/reference/inference/models/pull Resolves a catalog name or model spec and downloads the model artifact into the local model directory, returning the resolved local path. Honors `STRATA_MODELS_DIR` for the destination and `STRATA_HF_ENDPOINT` and `STRATA_HF_TOKEN` (or `HF_TOKEN`) for gated HuggingFace repositories. Downloading requires network access and a build with the local execution feature; cloud-only builds return `inference.unsupported_operation`. ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `model` | `string` | yes | Model spec or catalog name. | ## Returns `PullModelOutput`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`inference.download_disabled`](https://stratadb.org/e/inference.download_disabled) - [`inference.missing_model`](https://stratadb.org/e/inference.missing_model) - [`inference.download_failed`](https://stratadb.org/e/inference.download_failed) - [`inference.download_verification_failed`](https://stratadb.org/e/inference.download_verification_failed) - [`inference.io_failure`](https://stratadb.org/e/inference.io_failure) - [`inference.registry_corrupt`](https://stratadb.org/e/inference.registry_corrupt) ## Invocation - CLI: `strata inference models pull` - Wire type: `inference_models_pull` --- # Create JSON index Source: https://stratadb.org/docs/reference/json/index/create Creates a secondary index over one JSON field path with a numeric, tag, or text kind. Existing documents are indexed at creation and future writes maintain the index automatically. The current wire response is a transitional bare index definition. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Create a secondary index on a JSON field. ### CLI ```console $ strata json index create by_name $.name tag $ strata json index list ``` ### Wire ```json {"field_path":"$.name","index_type":"tag","name":"by_name","type":"json_create_index"} {"type":"json_list_indexes"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `field_path` | `string` | yes | Indexed field path. | | `index_type` | `JsonIndexType` | yes | Index kind. | | `name` | `string` | yes | Index name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_index_name`](https://stratadb.org/e/invalid_argument.engine.json_index_name) - [`invalid_argument.engine.json_index_name_reserved`](https://stratadb.org/e/invalid_argument.engine.json_index_name_reserved) - [`invalid_argument.engine.json_path`](https://stratadb.org/e/invalid_argument.engine.json_path) - [`invalid_argument.engine.json_path_too_long`](https://stratadb.org/e/invalid_argument.engine.json_path_too_long) - [`already_exists.engine.json_index`](https://stratadb.org/e/already_exists.engine.json_index) ## Invocation - CLI: `strata json index create` - Wire type: `json_create_index` --- # Drop JSON index Source: https://stratadb.org/docs/reference/json/index/drop Drops the named JSON secondary index and its stored entries. Documents are unaffected. The current wire response is a transitional boolean status. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Drop a secondary index. ### CLI ```console $ strata json index create by_name $.name tag $ strata json index drop by_name $ strata json index list ``` ### Wire ```json {"field_path":"$.name","index_type":"tag","name":"by_name","type":"json_create_index"} {"name":"by_name","type":"json_drop_index"} {"type":"json_list_indexes"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `name` | `string` | yes | Index name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.json_index_name`](https://stratadb.org/e/invalid_argument.engine.json_index_name) - [`invalid_argument.engine.json_index_name_reserved`](https://stratadb.org/e/invalid_argument.engine.json_index_name_reserved) ## Invocation - CLI: `strata json index drop` - Wire type: `json_drop_index` --- # List JSON indexes Source: https://stratadb.org/docs/reference/json/index/list Lists JSON secondary index definitions in the selected branch and space, including each index's field path and kind. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List secondary indexes. ### CLI ```console $ strata json index create by_name $.name tag $ strata json index list ``` ### Wire ```json {"field_path":"$.name","index_type":"tag","name":"by_name","type":"json_create_index"} {"type":"json_list_indexes"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) ## Invocation - CLI: `strata json index list` - Wire type: `json_list_indexes` --- # Create vector collection Source: https://stratadb.org/docs/reference/vector/collection/create Creates a collection for dense vectors. The dimension and metric become part of the collection contract for future upserts and queries. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Create a vector collection, then confirm its dimension. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector collection stats docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","type":"vector_collection_stats"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `dimension` | `integer` | yes | Embedding dimension. | | `metric` | `VectorDistanceMetric` | yes | Distance metric. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_dimension`](https://stratadb.org/e/invalid_argument.engine.vector_dimension) - [`invalid_argument.executor.vector_dimension`](https://stratadb.org/e/invalid_argument.executor.vector_dimension) ## Invocation - CLI: `strata vector collection create` - Wire type: `vector_create_collection` --- # Delete vector collection Source: https://stratadb.org/docs/reference/vector/collection/delete Deletes the selected vector collection from the current branch and space. The current wire response is a transitional boolean status. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Delete a collection. ### CLI ```console $ strata vector collection create temp 3 cosine $ strata vector collection delete temp $ strata vector collection list ``` ### Wire ```json {"collection":"temp","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"temp","type":"vector_delete_collection"} {"type":"vector_list_collections"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector collection delete` - Wire type: `vector_delete_collection` --- # List vector collections Source: https://stratadb.org/docs/reference/vector/collection/list Lists vector collections visible in the selected branch and space, including collection dimension, metric, and count facts. Paginated responses use opaque cursors. Clients should pass the returned cursor back to the same command shape and must not parse cursor contents. ## Examples List vector collections. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector collection list ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"type":"vector_list_collections"} ``` ## Parameters _No parameters._ Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `Page`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector collection list` - Wire type: `vector_list_collections` --- # Read vector collection stats Source: https://stratadb.org/docs/reference/vector/collection/stats Reads collection-level facts for one vector collection. The current wire response uses the collection-list output with one item. Status commands return a scalar or compact status payload and do not mutate database state. ## Examples Read a collection's dimension, metric, and size. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector collection stats docs ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","type":"vector_collection_stats"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `StatusResponse`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) ## Invocation - CLI: `strata vector collection stats` - Wire type: `vector_collection_stats` --- # Query vector index Source: https://stratadb.org/docs/reference/vector/index/query Runs vector search and includes planner diagnostics such as index policy, source usage, artifact status, and fallback facts. Search responses return a bounded list of matches ordered by the engine. They are not cursor pages unless a later command explicitly advertises pagination. Diagnostic responses include operational facts intended for debugging and tuning. They should not be required for application correctness. ## Examples Nearest-neighbor search that also returns index diagnostics. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] $ strata vector upsert docs b [0.0,1.0,0.0] $ strata command run --command-json '{"collection":"docs","k":2,"query":[1.0,0.0,0.0],"type":"vector_index_query"}' ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"b","type":"vector_upsert","vector":[0.0,1.0,0.0]} {"collection":"docs","k":2,"query":[1.0,0.0,0.0],"type":"vector_index_query"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `as_of` | `integer` | no | Optional timestamp in microseconds. | | `collection` | `string` | yes | Collection name. | | `filter` | `VectorMetadataFilter` | no | Optional metadata filter. | | `k` | `integer` | yes | Maximum number of matches. | | `query` | `number[]` | yes | Query embedding. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `SearchResult + IndexDiagnostics`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_filter`](https://stratadb.org/e/invalid_argument.engine.vector_filter) - [`invalid_argument.executor.vector_limit`](https://stratadb.org/e/invalid_argument.executor.vector_limit) ## Invocation - CLI: via `strata command run` (no dedicated verb) - Wire type: `vector_index_query` --- # Update vector metadata Source: https://stratadb.org/docs/reference/vector/metadata/update Applies a top-level metadata patch to one visible vector. Missing vectors return a no-op mutation acknowledgement. Successful mutations return an acknowledgement that identifies the affected target, the mutation effect, and commit facts when the operation changed stored state. ## Examples Patch the metadata of an existing vector. ### CLI ```console $ strata vector collection create docs 3 cosine $ strata vector upsert docs a [1.0,0.0,0.0] --metadata {"tag":"x"} $ strata vector update-metadata docs a {"tag":"z"} $ strata vector get docs a ``` ### Wire ```json {"collection":"docs","dimension":3,"metric":"cosine","type":"vector_create_collection"} {"collection":"docs","key":"a","metadata":{"tag":"x"},"type":"vector_upsert","vector":[1.0,0.0,0.0]} {"collection":"docs","key":"a","patch":{"tag":"z"},"type":"vector_update_metadata"} {"collection":"docs","key":"a","type":"vector_get"} ``` ## Parameters | Name | Type | Required | Description | |---|---|---|---| | `collection` | `string` | yes | Collection name. | | `key` | `string` | yes | Vector key. | | `patch` | `any` | yes | Top-level metadata patch. | Plus the optional scope: `branch` and `space` (default to the session branch and the `"default"` space). ## Returns `MutationAck`. ## Errors - [`failed_precondition.engine.runtime_closed`](https://stratadb.org/e/failed_precondition.engine.runtime_closed) - [`not_found.engine.branch`](https://stratadb.org/e/not_found.engine.branch) - [`invalid_argument.engine.product_space`](https://stratadb.org/e/invalid_argument.engine.product_space) - [`invalid_argument.engine.vector_collection`](https://stratadb.org/e/invalid_argument.engine.vector_collection) - [`invalid_argument.engine.vector_key`](https://stratadb.org/e/invalid_argument.engine.vector_key) - [`not_found.engine.vector_collection`](https://stratadb.org/e/not_found.engine.vector_collection) - [`invalid_argument.engine.vector_metadata_patch`](https://stratadb.org/e/invalid_argument.engine.vector_metadata_patch) ## Invocation - CLI: `strata vector update-metadata` - Wire type: `vector_update_metadata` --- # Commits and versioning (whitepaper) Source: https://stratadb.org/architecture/commits-and-versioning StrataDB has no `begin` / `commit` / `rollback`. Writes commit automatically, each into a versioned commit unit, and the commit timeline that results is what powers time travel. This page explains how commits and versions work under the hood; the product-level view is in [commits](/docs/concepts/commits) and [time travel](/docs/concepts/time-travel). ## Writes auto-commit Every write is applied as a **commit unit** — an atomic unit of change that the storage commit runtime allocates a version for, orders, and makes durable through the write-ahead log before its effects become visible. There is no session to open and no transaction to hold; a write either commits as a unit or does not apply. The commit unit is internal machinery. What the product exposes on top of it is clear write and batch semantics, not a manual transaction API — a deliberate V1 decision, because a public transaction surface would imply an isolation and ACID contract the product does not claim. ## Versions and the commit timeline Two facts travel with every commit, and both are **storage-native substrate**, not engine bookkeeping: - a **version** — monotonically allocated, the identity of that committed state; - a **commit timestamp** — one timestamp stamped on the whole committed batch. Storage persists a **per-branch timeline mapping commit version to timestamp**, and exposes timestamp-to-version resolution to the engine. That timeline is the entire basis for reading the past: because every commit is on it, "the database as of timestamp *T*" resolves to a concrete version, and every capability reads consistently at that version. The division of labor is clean: **storage owns the timeline as a fact; the engine owns the product experience** of `as_of`, branch-from-time, and timeline explanations. See [the storage substrate](/architecture/storage-substrate) for where the commit runtime sits (L7) in the layering. ## Batches are itemwise under one commit A batch applies many items in one call. StrataDB's batches are **itemwise**: you get one positional result per input item, and an outer status summarizes whether all, some, or none succeeded. The valid items the engine applies together share **one commit** — so a batch is atomic at the commit-unit level while still reporting per-item outcomes. Batches are part of the command surface used by the SDKs, the MCP tools, and the raw command path rather than a bare CLI verb. ## Why no manual transactions The engine keeps the internal commit machinery it needs, but the product surface stops at write and batch semantics on purpose: - Auto-commit means an agent or application never leaves a transaction open, never deadlocks on a held lock, and retries idempotently. - The absence of a session removes a whole class of misuse — partial commits, forgotten rollbacks, long-lived read snapshots pinning resources. - Isolation is provided by [branches](/docs/concepts/branches): to work against an isolated view, you fork a branch, not open a transaction. If a future product decision ever introduces a public transaction, it would come with an explicit isolation contract, backend requirements, and a conformance suite — it is not something the current architecture leaves half-exposed. ## Versioning is uniform across capabilities Because versioning lives in the substrate under the single physical row, it applies identically to KV, JSON, events, vectors, and graphs — one commit can span several capabilities and lands as one versioned unit, and a historical read at a version sees all of them consistently. That uniformity is a direct consequence of [one substrate underneath](/architecture/storage-substrate) rather than per-capability version schemes. --- # Errors and diagnostics (whitepaper) Source: https://stratadb.org/architecture/errors-and-diagnostics Errors in StrataDB follow the same rule as everything else: **storage owns the mechanics, the engine owns the meaning.** Storage failures are detailed and mechanic-specific; the engine decides which of them become public product errors and how they are explained. This page is the propagation architecture — the product-level error contract is [errors](/docs/concepts/errors). ## Two audiences, one path A failure deep in storage — a checksum mismatch, a torn write at the log tail, a backend that cannot satisfy a capability — is described in storage's own terms, with all the mechanic detail needed to diagnose it. That detail is for storage tests and internal diagnostics. Before it reaches a user, the engine **translates** it into a public error with a stable `..` code, a one-line hint, and a docs reference. The user sees a small, stable vocabulary they can branch on; the mechanic detail stays where it is useful. The consequence for callers is the core rule: > Recover by **code and class**, never by message text. The code is stable; the > message is for humans and may change. ## What the architecture must surface as typed errors The error model is required to make each of these a typed failure rather than a crash or a wrong answer: - typed **open** failures; - typed **backend capability** failures (a mode a backend cannot satisfy); - typed **corruption and recovery** failures; - **read-only write rejection**, before any mutation; - **IPC** transport and protocol failures; - search, index, and model **availability** failures. Because these are typed at the boundary, an application can react to "this backend can't do that" or "this history is out of range" specifically, instead of parsing prose. ## Diagnostics stay above the mechanics A guiding constraint: normal diagnostics must not require a user to understand WAL records, manifests, checkpoints, memtables, segment compaction, or cleanup history. Those are storage's concern. What the engine exposes instead is **structured health, metrics, describe, and durability counters** — enough to answer "is this database healthy, durable, and recovered?" without a tour of the internals. When a raw storage fact *is* worth surfacing, the engine converts it deliberately into an engine-owned diagnostic rather than leaking the mechanic. ## Secrets never travel with an error The error and diagnostic path redacts sensitive material by default — provider API keys, signed URLs, prompts, and document contents — so an error is safe to log and to show a user without exposing what produced it. Redaction is a property of the boundary, not something each call site has to remember. ## Recovery health is a storage-owned fact Recovery outcomes — whether recovery was clean, degraded, or found a fault — are **storage-owned facts** that the engine re-exports or wraps as public diagnostics. Ownership sits with the layer that actually performs recovery, which keeps the source of truth for "what happened on open" in one place. See [durability and recovery](/architecture/durability-and-recovery). ## Related - [Errors (concept)](/docs/concepts/errors) — the `class.area.detail` contract and the fixed class taxonomy. - [Error handling (guide)](/docs/guides/error-handling) — parsing the envelope, retry policy, and commit outcome. - [The layered stack](/architecture/layered-stack) — why meaning and mechanics are split in the first place. --- # Runtime modes (whitepaper) Source: https://stratadb.org/architecture/runtime-modes The same StrataDB binary opens a database in several ways, and adapts its resource use to the machine it runs on. This page covers the runtime modes and the resource-profile model; how those modes persist data is [durability and recovery](/architecture/durability-and-recovery). ## Access modes ### Durable local The reference V1 mode. It opens or creates a database at a local filesystem path, acquires writer protection, runs deterministic recovery before serving traffic, and preserves committed data across ordinary crashes. Local filesystem is the reference durable backend. ### Cache Explicit and non-durable. Cache mode avoids all hidden disk durability — no WAL, manifest, checkpoint, or durable files — while still supporting normal data capability behavior in memory. It is visibly different from durable mode in info and health output, so it is never mistaken for a durable database. Disk-backed cache mode is not a V1 mode. ### Read-only Opens an existing database without permitting mutation, and rejects writes before they mutate anything. It preserves the same branch, space, search, graph, and time-travel *read* semantics as a writable open, and it explains clearly when an operation would require write access (for example, when recovery or repair is needed). ### IPC-backed local shared access Strata is embedded, but two local processes — an application and a Strata AI assistant, say — sometimes need the same database. Rather than open a second direct writer, the secondary process connects over **IPC** to the process that already owns the database. IPC: - routes secondary access through the existing database owner; - preserves access-mode semantics and the same command classification, so writes are rejected exactly as they would be for a local handle; - uses the serializable command boundary and never bypasses engine validation; - surfaces stale-socket, permission, protocol, lock, and server failures explicitly. IPC is a supported path, not a mandatory server: ordinary single-process embedded use needs no daemon. (The older follower mode is not part of V1.) ## The backend capability contract A backend is not "supported" because its adapter compiles — it is supported for a mode only when it **declares and passes the capabilities that mode requires**. The contract defines backend address syntax, capability declarations, the required capabilities per runtime mode, explicit unsupported-capability errors, and backend conformance tests. Local filesystem is the reference; browser/WASM and cache targets are explicit about their durability limits; object-storage and OpenDAL-backed targets are supported only where their declared capabilities pass conformance. Open fails clearly when a backend cannot satisfy the selected mode. ## The resource-profile model One binary must run on a constrained edge device, a laptop, a cloud VM, and a large server. The engine owns that adaptation: - The **engine probes the host**, classifies a resource profile, applies any explicit user overrides in precedence order, and allocates product-wide budgets. - **Storage receives resolved budgets** and spends within them — it does not classify the host or mutate product defaults. - Graph, vector, search, and retrieval features receive engine-owned budget guidance instead of independently probing the machine. - Resolved runtime plans are **observable but not persisted** as user configuration — they are a computed plan, not saved state. - Low-memory conditions produce typed resource errors or bounded/degraded operation *before* uncontrolled out-of-memory behavior. The result is that scaling from small to large is a matter of the resolved plan, not a different build — the same architecture, sized to the host. ## Related - [Durability and recovery](/architecture/durability-and-recovery) — what each mode guarantees across a crash. - [The storage substrate](/architecture/storage-substrate) — the backend layer the capability contract sits over. - [Embedded architecture](/docs/concepts/embedded-architecture) — the product-level view of these modes. --- # Data capabilities (whitepaper) Source: https://stratadb.org/architecture/data-capabilities StrataDB has exactly one physical storage primitive: a branch-aware, versioned (MVCC) key–value row. KV, JSON, events, vectors, graph, and branches are not six storage engines bolted together — they are six *engine capabilities* layered over that one row. Storage persists bytes, versions, timestamps, and tombstones under opaque space IDs. It does not know what a JSON document, an event log, a vector, or a graph edge *is*. All of that meaning lives in the engine. This page is the "engine owns semantics" story: how each capability is built over the same substrate, what each one declares, and how graph doubles as a relationship layer across every other capability. ## One row, six capabilities The engine sees a generic `Key`/`Value` MVCC substrate. KV, JSON, event, vector, and graph each build *typed* keys, values, indexes, and derived state over that substrate. None of them is a peer storage engine, and none of them can reach around the engine to talk to storage directly — only the engine's persistence adapter imports storage at all. Branches are the sixth capability, but of a different kind: every row is already branch-tagged and versioned, so branching is the isolation-and-history dimension baked into the substrate itself. The other five are data *shapes*; branch is the axis they all vary along. ## What "engine owns semantics" means The engine is the layer that assigns meaning to operations. Concretely it owns: - **Open policy** — durable, cache, and read-only open; same-path reuse; layout validation. Pre-V1 database directories are refused at open. - **Branch, space, version, history, time-travel, and restore semantics** — the product model for isolation and time. - **The data-capability APIs** — the KV/JSON/event/vector/graph surfaces. - **Derived-state management** — search indexes, vector (ANN) indexes, graph relationship and traversal projections, shadow vectors, and recipe outputs, each with manifests, watermarks, health, and rebuild behavior. - **Commit-unit and batch semantics as product operations** — not public transaction sessions (see below). - **Engine-owned public errors** and **the serializable command boundary** used by the CLI, IPC, tests, and agents. Storage owns none of this. It stores generic rows; the engine decides what they mean. Upper layers (executor, CLI, SDK, Strata AI) consume the engine's command boundary and never import storage. See [The layered stack](/architecture/layered-stack) and [The storage substrate](/architecture/storage-substrate). ## The capability contract Every capability is built to the same shape, so branch operations, retrieval, and cross-capability workflows can treat them uniformly. A capability declares: - a **facade** (its product-facing handle and methods) and its **types**; - **entity addressing** — how user objects map to typed entity references; - **row families**, **key encoding**, and **value encoding** over the persistence adapter; - **read operations** — latest, by-version, by-timestamp, history, and prefix/range, all branch-aware; - **write operations** over the internal commit unit; - a **branch adapter** (how the capability participates in branch operations — diff, revert, copy, and merge-conflict granularity); - a **search/text adapter** (optional text projection and search participation); - a **relationship adapter** (optional entity resolution and relationship-layer participation); - **derived-state hooks** (index rebuild, shadow state, recovery, diagnostics); - **conformance tests** — shared capability tests plus capability-specific ones. The engine's target semantics per capability: | Capability | Branch-merge adapter | Search adapter | Relationship participation | Derived runtime state | |---|---|---|---|---| | KV | Simple | Yes | As entity | None | | JSON | Structured | Yes | As entity / subpath | Indexes | | Event | Append / ordered | Yes | As entity | Optional | | Vector | Config + record aware | Vector search | As entity / source link | ANN indexes | | Graph | Relationship / ontology aware | Graph search | Native + entity-bound | Traversal / index projections | Two V1 refinements narrow the table: JSON branch merge resolves at **whole-document** granularity, and a branch merge across **divergent concurrent history is refused**, not auto-reconciled. A capability may own its own row encodings and expose these adapters, but it must not call a sibling capability's internals or hide cross-capability behavior inside its own CRUD methods. Cross-capability work is coordinated above the capabilities, never smuggled inside one. ## Branches: the sixth capability Branching is a first-class product capability, not a copy utility. One canonical `BranchId` lives in core; the engine owns its derivation and the branch DAG. The guarantees: - **Branch generations are monotonic**, scoped per branch name. - **Empty-branch creation is supported** — a branch need not fork existing data. - **Cross-branch references are rejected** — an entity reference is valid only within its own branch. - **Merge is strict.** In V1 the branching model is fork / isolate / time-travel; a merge across divergent concurrent history is a structured refusal rather than an automatic reconcile. The engine owns fork, branch-from-current, branch-from-version, branch-from-time, diff, revert, and restore. Storage provides generic branch-isolated physical mechanics; the engine provides branch *names*, the DAG, and user-facing conflict policy. See [Commits and versioning](/architecture/commits-and-versioning) and [Branches](/docs/concepts/branches). ### Commits, not sessions The engine keeps an internal commit unit — commit context, batch construction, version coordination with storage, write ordering, and observers — but it does **not** expose manual begin/commit/rollback sessions as the product model. Instead: every normal public write is **one commit**, and explicit batch operations (such as KV batch put/delete) are **atomic inside a single capability**. Cross-capability public batches are not a V1 surface. ## Graph's two roles Graph is the one capability with a dual identity, and it is the most novel part of the design. **1. A standalone capability.** Nodes, edges, ontology, traversal, and analytics — graph as its own data shape, with graph-aware search and traversal/index projections as its derived state. **2. A relationship layer across everything.** Because every capability declares entity addressing, any KV row, JSON document, event, vector, or graph node can be named by a typed entity reference. Graph stores relationships *between those references*, letting you link records that live in different capabilities: ```text entity-addressable records (KV / JSON / event / vector / graph) -> a relationship policy or explicit link -> graph stores the relationship as nodes/edges -> graph traversal returns entity references -> callers fetch each source record through its owning capability ``` Traversal returns *references*, not copies — you follow edges in the graph, then read each endpoint through the capability that actually owns it. This is how graph becomes the connective tissue of a multi-model database without duplicating the data it connects. See [Graph](/docs/data/graph) and [Combining primitives](/docs/data/combining-primitives). ## Derived state accelerates; it never replaces Search indexes, ANN indexes, graph projections, and shadow vectors are all **derived state**: engine-owned, rebuildable acceleration structures. The invariant is absolute — **source rows are authoritative**, and derived state must never silently contradict a committed source row. Every derived structure carries a manifest, a watermark, health, and rebuild behavior, tracked in the per-branch `_system_` control space so retrieval only trusts an index when it is compatible with the requested branch and time. **Shadow vectors** are the clearest example. A shadow vector is an engine-owned *derived row*: the engine owns the row, its lifecycle, and its link back to the source record. Deciding *what* to embed — and running any model — belongs above the engine, in intelligence and inference; the engine never calls a model provider. In V1 the shadow-vector *mechanism* exists and is engine-owned; it is the substrate for embedding-driven retrieval, not a shipped end-to-end auto-embedding feature. ## Retrieval is a service, not a capability Search and retrieval — BM25 indexing, recipe resolution, vector retrieval, graph-aware expansion, result fusion, and temporal index-compatibility checks — are **engine services over the capability adapters**, not a seventh data capability. They consume each capability's search/text adapter and the control plane's recipes and manifests; they do not own authored capability data. That is why there are exactly six capabilities — KV, JSON, event, vector, graph, branch — and no more. Errors raised at every boundary above use structured `..` codes — opening a pre-V1 database, an embedding-model mismatch during retrieval, or a cross-branch reference each surface as engine-owned typed errors. See [Errors and diagnostics](/architecture/errors-and-diagnostics) and [Primitives](/docs/concepts/primitives). --- # Durability and recovery (whitepaper) Source: https://stratadb.org/architecture/durability-and-recovery StrataDB's durability is designed to be honest and testable: a committed write survives an ordinary process crash, recovery is deterministic, and the failure modes are typed rather than silent. This page covers the model; the row store it protects is [the storage substrate](/architecture/storage-substrate). ## Two axes: storage mode and durability policy Durability is expressed as two independent axes, not a single dial: ```text StorageMode = Cache | Durable DurabilityPolicy = Standard | Always (only meaningful when Durable) ``` The three product modes fall out of that: - **`cache`** — an ephemeral *storage mode*. No write-ahead log, no crash durability, no durable files at all. Cache still allocates versions, records commit timestamps, and maintains branch state in memory; it simply promises nothing across a restart. - **`standard`** — a durable storage mode with a WAL-backed crash-recovery path and background or periodic durability barriers. It has a bounded crash-loss window set by its configured interval and the backend's capabilities. - **`always`** — the same durable storage mode with a force-durability barrier before *each* committed write is acknowledged. No crash-loss window, at the cost of a sync per commit. A runtime may switch between `standard` and `always` where the backend supports both. Moving into or out of `cache` is not a durability-policy switch — it is a different storage mode entirely. ## What "committed" means Durable mode defines committed precisely: a write counts as committed once its commit unit is durable according to the active policy, and it becomes visible at that point. Everything the substrate persists — the WAL, snapshots, the manifest, and table blocks — is written with **one uniform codec**, and the durable format is frozen and guarded by golden vectors, so a database written by one build reads identically in another. ## The write-ahead log Durable writes go through a write-ahead log first. The WAL is what makes crash recovery possible: a commit is appended and made durable there before its effects are considered committed. The WAL has one non-negotiable rule: > **The WAL writer halts on fsync failure.** If the log cannot be made durable, > the writer stops rather than pretending the write succeeded. A halt is not a silent degradation — it surfaces, and the database is resumed through an explicit recovery path, never by best-effort guessing. ## Recovery on open Opening a durable database runs **deterministic recovery before it serves any traffic**. Recovery replays the durable log and manifest to reconstruct the last consistent committed state, accepts the writes that were fully committed, and rejects torn or partial state at the tail. Because recovery is deterministic, the same on-disk bytes always recover to the same state — which is exactly what makes crash recovery testable under fault injection (torn writes, failed syncs, stale manifests, checksum failures). Corruption, an incompatible on-disk format, an unsupported backend, a permission error, or an IO failure each surface as a **typed** open failure rather than a crash or a wrong answer — see [errors and diagnostics](/architecture/errors-and-diagnostics). ## Maintenance is internal Flush, compaction, checkpointing, and retention are lifecycle *mechanics*, not product workflows. They run under engine-owned policy with observable status, so a normal user never issues a manual `flush`, `compact`, or `checkpoint` command. The details of how they run are the substrate's concern; what the product exposes is health, metrics, and durability counters. ## Cache is deliberately different Cache mode is not "durable but weaker" — it is a different storage mode with no durable services at all. It creates no WAL, manifest, snapshot, checkpoint, or durable table objects, and info and health output make the distinction visible so a cache database is never mistaken for a durable one. See [runtime modes](/architecture/runtime-modes) and the [durability concept](/docs/concepts/durability) for the product-level view. --- # Architecture overview (whitepaper) Source: https://stratadb.org/architecture/index StrataDB is an embedded, local-first database built as a layered Rust workspace. The whole system is designed to be explainable in one line: ```text core → storage → engine → intelligence → inference ``` Data flows up through those layers, and dependencies point down. Only the engine consumes storage directly; everything above the engine uses engine-owned product APIs, intelligence APIs, or the serializable command boundary. The one invariant that organizes everything else is this: > **The engine owns the meaning of a database operation. Storage owns the > mechanics of persisting and recovering rows.** Storage never decides product > behavior; the engine never reaches around storage's lifecycle. ## The layers - **core** — the smallest shared contract layer: stable IDs, version and timestamp vocabulary, branch and space identifiers, and the error-category building blocks that genuinely belong below both storage and engine. No runtime, no product policy, no helper sprawl. - **storage** — the persistence substrate. It stores generic rows over a single physical primitive and owns backends, the write-ahead log, manifests, snapshots, checkpoints, compaction, retention, and recovery. It knows *nothing* about KV, JSON, events, vectors, or graphs. See [the storage substrate](/architecture/storage-substrate). - **engine** — the database-semantics layer. Branches, versions, time travel, the six data capabilities, derived state, commit and batch semantics, public errors, and the command boundary all live here. See [data capabilities](/architecture/data-capabilities). - **intelligence** — database-aware retrieval and AI orchestration: recipes, query expansion, reranking, RAG, and explanation provenance. It consumes the engine for state and inference for models. - **inference** — model and provider execution: adapters, tokenization, embedding, and generation. It is not a database layer and depends on neither storage nor engine. The dependency rules that keep these honest are the subject of [the layered stack](/architecture/layered-stack). ## One substrate underneath The five data capabilities are not five storage engines. Underneath, StrataDB has a **single physical primitive: a branch-aware, versioned (MVCC) key-value row.** KV, JSON, events, vectors, and graph nodes and edges are all encoded as rows in that one store, which is why every capability inherits branch isolation, versioning, time travel, and durability the same way — see [the storage substrate](/architecture/storage-substrate) and [data capabilities](/architecture/data-capabilities). ## The whitepapers - **[The layered stack](/architecture/layered-stack)** — the five crates, their responsibilities, and the dependency rules the build enforces. - **[The storage substrate](/architecture/storage-substrate)** — generic rows, the single physical primitive, and backend portability. - **[Durability and recovery](/architecture/durability-and-recovery)** — storage modes, durability policies, the write-ahead log, and crash recovery. - **[Commits and versioning](/architecture/commits-and-versioning)** — auto-commit semantics, the commit timeline, batches, and why there are no manual transactions. - **[Data capabilities](/architecture/data-capabilities)** — how the engine turns one row into six capabilities, and graph's dual role. - **[Runtime modes](/architecture/runtime-modes)** — durable, cache, read-only, and IPC access, plus the one-binary resource-profile model. - **[Errors and diagnostics](/architecture/errors-and-diagnostics)** — how storage mechanics become engine-owned public errors. For the product-level mental model rather than the internals, start with the [concepts](/docs/concepts) documentation. --- # The layered stack (whitepaper) Source: https://stratadb.org/architecture/layered-stack StrataDB is a Rust workspace of five layers. Each has one job, and the dependency graph between them is enforced by a workspace guard so the boundaries cannot erode over time. ```text core ← storage ← engine ← intelligence ← executor / CLI / SDK ← inference ← ``` Arrows point in the direction of *depends on*. Read top to bottom, each layer may only reach the layer below it through that layer's public contract. ## What each layer owns ### core The smallest shared contract layer — vocabulary that genuinely belongs below both storage and engine. It holds stable IDs and transparent newtypes, version and timestamp types, branch and space identifiers, and the shared error-category building blocks. It deliberately does **not** hold storage IO, product behavior, CLI or SDK affordances, data-capability objects, or general-purpose helpers. Every public type in core has to justify itself by naming which lower layers need the same concept. ### storage The persistence substrate. It stores generic rows over a single physical primitive and owns backend access, the physical keyspace, commit-unit persistence, and the write-ahead log, manifest, snapshot, checkpoint, compaction, retention, and recovery mechanics. It knows nothing about JSON paths, event meaning, embeddings, graph ontology, or search ranking. Details: [the storage substrate](/architecture/storage-substrate). ### engine The database-semantics layer, and the heart of the product. It owns open policy; branch, space, version, history, time-travel, and restore behavior; the six data capabilities; derived-state management; commit and batch semantics; the public error surface; and the serializable command boundary that the CLI, IPC, tests, and agents all speak. Details: [data capabilities](/architecture/data-capabilities). ### intelligence The database-aware AI and retrieval orchestration layer. It provides retrieval recipes, query expansion and reranking, RAG and answer generation, and explanations of which branches, records, versions, and models contributed to a result. It depends on the engine for database state and on inference for models — and it never bypasses the engine to touch storage. ### inference The model and provider execution layer. It provides provider adapters, local or remote execution, and tokenization, embedding, and generation utilities. It is **not a database layer**: it depends on nothing from storage or engine, and it never makes an implicit network call without explicit configuration. ## The dependency rules The guard test enforces these on every change: 1. Storage may depend on core. 2. Engine may depend on storage and core. 3. Intelligence may depend on engine, core, and inference. 4. Product crates above the engine — executor, CLI, SDK, Strata AI — must **not** depend on storage. 5. Inference must **not** depend on engine or storage. 6. Everything above the engine consumes engine and intelligence APIs, not storage APIs. Two consequences fall out of these rules and matter enough to state directly: - **Only the engine consumes storage.** If an upper layer needs storage-backed behavior, the answer is a new engine API, never a direct storage import. The allowed exceptions — tests, benches, fuzz targets, diagnostic and migration tools — are explicit. - **Optional model and provider features cannot affect durability.** Because inference sits off to the side and never reaches into storage, enabling or disabling a model feature can never change what a committed write means. ## Why the split is worth it Keeping meaning (engine) strictly above mechanics (storage), with a thin shared vocabulary (core) below both, is what lets the same substrate carry six capabilities, lets storage be fault-injected and crash-tested without any product semantics, and lets the AI layers be optional without ever putting database correctness at risk. The boundaries are not stylistic — they are the reason the [storage substrate](/architecture/storage-substrate) can stay simple while the [data capabilities](/architecture/data-capabilities) stay rich. --- # The storage substrate (whitepaper) Source: https://stratadb.org/architecture/storage-substrate StrataDB is built as a stack: **core → storage → engine → intelligence → inference**. Storage sits near the bottom, and only the engine consumes it directly. This page describes what storage is responsible for — and, just as importantly, what it refuses to know. The dividing line is simple to state and load-bearing everywhere: **storage owns persistence mechanics; the engine owns product meaning.** Storage moves bytes durably, orders commits, versions rows, and recovers after a crash. It does not know what a JSON path is, what an event chain means, how a vector is embedded, or what a graph edge represents. Those are [engine capabilities](/architecture/data-capabilities) layered over one generic row model. ## One physical primitive There is exactly one physical storage primitive: a **branch-aware, versioned (MVCC) key-value row**. Every data capability — KV, JSON, event, vector, graph — is layered *over* that single row model by the engine. Storage never sees a capability. It sees physical keys, opaque storage-space identifiers, row values, and commit metadata. The storage-space identifier is the mechanism that keeps meaning out of storage. Each row belongs to an opaque **storage space / family id** supplied by the engine. Storage may route by that byte, but it must not know whether the byte means KV, JSON, graph, vector, event, search, or a capability that does not exist yet. Storage reserves the low range `0x00..=0x1f` for its own internal row families (with `0x01` assigned to the commit timeline, below); the engine owns `0x20..=0xff` and publishes its own product-space registry. New capabilities extend storage by choosing spaces, key encodings, and derived rows in the engine — never by adding a storage layer. ## What storage owns, and what it excludes Storage owns the full set of durable-row mechanics: - Backend access and physical keyspace / row layout - The internal commit unit: version allocation, commit ordering, and commit-unit persistence - WAL, manifest, snapshot, and checkpoint services - Compaction, retention, and recovery mechanics - Backend capability validation and raw storage health facts Storage explicitly excludes all product semantics — JSON document behavior, event-chain meaning, vector/embedding policy, graph ontology and traversal, search ranking and BM25, RAG, IPC, StrataHub datasets, and cross-branch merge strategy. It may *persist* rows the engine uses for any of these, but it does not define their meaning. Merge is a good example: storage retains branch history and rows, but the V1 merge strategy is engine-owned product behavior, not a storage CRDT. ## The L1–L9 layer stack Storage is layered from the backend up to a single API boundary. The governing rule is that **a lower layer must not know the concepts of a higher layer** — backend IO must not know manifests, formats must not know recovery policy, table code must not know branch commands. ```text strata-engine | v +------------------------------------------------+ | L9. Storage API Boundary | | L8. Lifecycle / Recovery / Maintenance | | L7. Commit Runtime | | L6. Branch-Isolated LSM Runtime | | L5. Table Runtime | | L4. Log / Manifest / Snapshot Services | | L3. Durable Format / Codec Layer | | L2. Object Layout Layer | | L1. Backend IO Layer | +------------------------------------------------+ | v storage backend ``` - **L1 — Backend IO.** The portability layer. Owns access to storage backends in Strata's own vocabulary (read/write/list/delete objects, conditional publish, sync barriers, capability declaration). Knows nothing of branches, versions, WAL records, or manifests. - **L2 — Object Layout.** Maps database-relative concepts to backend object names — WAL, table, manifest, snapshot, and temporary object names — behind a single layout contract. - **L3 — Durable Format / Codec.** Owns bytes: WAL framing and record encoding, manifest and snapshot encoding, table metadata, checksums, and strict decode. It performs no IO and makes no recovery decisions. - **L4 — Log / Manifest / Snapshot Services.** Turns backend IO, layout, and formats into usable durable services: append/read WAL, publish manifests, write/read snapshots, WAL truncation and safe deletion. - **L5 — Table Runtime.** The reusable table primitives — mutable and frozen tables, immutable tables, ordered byte-key comparison, tombstones, TTL, block cache, bloom filters, indexes, merge cursors, and generic table compaction. (Immutable tables are called "tables," not "segments.") - **L6 — Branch-Isolated LSM Runtime.** Where Strata's storage identity begins: a branch-indexed MVCC LSM forest. Each branch owns its table state and leveled view; forks inherit ancestor table layers under a copy-on-write, fork-version frontier. Owns MVCC visibility and version- and timestamp-bounded reads. - **L7 — Commit Runtime.** The internal commit unit — version allocation, commit ordering, branch commit locks, WAL-before-visible discipline, and batch apply. This is not a public transaction product; it is the mechanism that makes writes ordered, durable, and visible. - **L8 — Lifecycle / Recovery / Maintenance.** Storage-internal orchestration: open mechanics, WAL replay, snapshot install, table recovery, checkpoint and compaction scheduling, retention/pruning, quarantine and repair, shutdown sync, and raw health and metrics. - **L9 — Storage API Boundary.** The only normal production surface. Exposes storage capabilities in storage language and hides WAL, table, manifest, and cache internals. ## The runtime boundary: L9 / L8 / L7 The engine attaches to storage only through the **L9 / L8 / L7 runtime contracts** — never through WAL, manifest, table, object, or backend-publish primitives directly. L9 is the sole boundary consumed in production: open a runtime from a backend and config, commit a batch, read latest, read by version, read by timestamp, scan by physical key range, read history, fork or materialize a branch, drive maintenance and health hooks, and shut down safely. This is a durable design decision, not an accident of the current code. Keeping the boundary at L9/L8/L7 is what lets future compute nodes attach to storage through storage runtime contracts instead of reaching into lower-level durable objects. It is also why the engine is the only workspace crate that imports storage at all — see the [layered stack](/architecture/layered-stack). ## Backend portability L1 makes the substrate portable. Strata owns a **backend capability contract**, and every backend declares what it supports; higher layers consume the contract rather than hand-rolling POSIX sequences. The durable publish primitive is a good illustration: L1 exposes a backend-owned publish / conditional-publish operation, and the local filesystem implements it internally with temp-write, sync, rename, and directory sync. | Backend | Status | |---|---| | Local filesystem | Reference durable backend | | Memory / test | Supported, non-durable | | Browser / WASM | Explicit direction, durability limits stated | | Object-storage / OpenDAL-backed | Architecture-aware direction, per-mode required capabilities and conformance tests | Portability is architecture-aware, not a blanket promise: V1 implements cache mode and durable local-filesystem mode. Object-store and OpenDAL-backed durability are designed for but not claimed production-ready — Strata does not require OpenDAL, and V1 does not assert every OpenDAL backend is production-grade. Each target is explicit about its durability limits, and backend conformance and capability-mismatch faults are first-class tests. Storage also does not detect host hardware. The engine supplies a **resolved storage runtime budget**, and storage owns how it is spent — table cache size, mutable-table sizing, compaction rate, pressure facts, and maintenance scheduling. The same binary runs from constrained edge devices to server-class machines through that budget. See [runtime modes](/architecture/runtime-modes) for how `cache`, `standard`, and `always` map onto storage mode and durability policy, and the [durability concept](/docs/concepts/durability) for the user-facing view. ## The commit timeline Time travel rests on a storage-native substrate. L7 stamps **every committed batch with exactly one commit timestamp**, and storage persists a **per-branch commit-version → timestamp timeline** — stored as storage-owned system rows under storage space `0x01`, not as a separate object family. Storage exposes timestamp-to-version resolution to the engine, which owns the product UX for `as_of` and branch-from-time. This keeps a clean split: the generic timeline is storage-owned mechanics; what a user means by "as of yesterday" is engine semantics. The details of that split live in [commits and versioning](/architecture/commits-and-versioning) and the [branches concept](/docs/concepts/branches). ## Recovery and maintenance are automatic Users should never manually flush, compact, checkpoint, prune, or recover during normal use. L8 makes those mechanics automatic, observable database internals: WAL replay, snapshot install, table recovery, retention, and quarantine/repair all run below any product policy. The WAL follows a WAL-before-visible discipline and halts on fsync failure, with recovery by explicit resume. Committed rows recover from row-native storage snapshots plus the log — engine-owned snapshot sections are permitted only for derived, rebuildable state and are never required to recover a committed row. The result is a substrate that is boring on purpose: one row model, one commit unit, one API boundary, and a strict refusal to learn what any of the bytes mean. Everything a user recognizes as a capability is assembled above it. See [durability and recovery](/architecture/durability-and-recovery) for the crash-consistency story in full.