> For the complete documentation index, see [llms.txt](https://stemma.sh/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stemma.sh/docs/understand-the-model/stability.md).

# Stability

Stemma is pre-1.0. Under standard [`0.x` semver](https://semver.org/#spec-item-4), a minor version (`0.MINOR.PATCH`) may contain breaking changes. This page states what "breaking" means for each surface stemma exposes, so you can depend on it deliberately. It describes the contract the project already follows, not an aspiration.

There are two kinds of surface: the **Rust API**, which is linked into your binary, and the **wire surfaces**, which carry JSON across a process boundary for transactions, MCP tool calls, and HTTP. They evolve under different rules.

## Rust API

The Rust surface is tiered, and the tiers *are* the stability contract. This is documented in full at the top of [`stemma-engine/src/lib.rs`](https://github.com/stemma-sh/stemma/blob/main/stemma-engine/src/lib.rs) and in [`stemma-engine/README.md`](https://github.com/stemma-sh/stemma/blob/main/stemma-engine/README.md); in short:

* **Tier 1: the `api::Document` facade.** The intended public surface and the one new consumers should depend on. Stable within a `0.x` minor release line.
* **Tier 2 covers the typed IR and domain model** (`domain`, `table`, `tracked_model`, `vocabulary`, …). Public but **engine-version-bound**: do not persist the IR. Its shape can change with any engine release.
* **Tier 3 covers the unstable engine API** (`edit`, `edit_v4`, `view`, `import`, the part-level modules, …). A deliberate, explicitly-unstable surface that the in-workspace transports drive directly. May change between minor versions.
* Everything else is sealed (`pub(crate)`).

Document comparison is not an engine tier. The separate `stemma-diff` crate depends on the engine's version-bound compiler surface and exposes one small product facade: `diff`, `diff_as`, their metadata-bearing `diff_detailed` and `diff_as_detailed` forms, `ComparisonResult`, `FlattenedInputRevisions`, and the comparison read model. The comparison entry points and the two result types are stable within the matching `0.x` minor release line. The rich types returned by `tracked_document_view` remain engine-version-bound as documented in the [read model reference](/docs/reference/read-model.md): do not persist them, and re-read after every engine upgrade. Use matching `stemma` and `stemma-diff` minor versions. The engine itself remains usable without comparison and has no production dependency back to it.

Persist **DOCX bytes plus edit transactions** for durability. Never persist the IR or an `EditSnapshot`. Together the bytes and transactions reconstruct any past state by replay; a stored snapshot becomes a migration problem on the next engine release. The rule as a working flow (what to store, how to replay, the failure modes, checkpointing) is [Persist and replay](/docs/understand-the-model/persistence.md).

The Tier 2 and 3 READ shapes a renderer consumes (blocks, segments, run formatting, revision identity) are documented, with the same generation and drift-guard rigor as the stable write wire but the opposite stability promise, in the [read model reference](/docs/reference/read-model.md).

## Wire surfaces

### v4 transaction JSON: additive, unknown fields rejected

The v4 edit-transaction schema ([`stemma-engine/src/edit_v4.rs`](https://github.com/stemma-sh/stemma/blob/main/stemma-engine/src/edit_v4.rs)) is the durable, cross-boundary edit format. Its evolution is **additive**: new optional fields and new op types may appear in a minor release; the meaning of an existing op does not change under it.

Deserialization is strict. Every transaction struct is `#[serde(deny_unknown_fields)]`. An unrecognized field is a **hard error**, not a warning, and this is deliberate: a misspelled or misplaced key is far more likely to be an authoring mistake that would silently no-op than an intended input, and silently ignoring it is exactly the "best-effort into an unknown state" this project refuses. Author against the fields the schema defines; do not send speculative keys expecting them to be ignored.

The complete operation catalog, generated from that parser table, is published as the [v4 operation reference](/docs/reference/operations.md).

Because the format is additive and strict, a transaction that a newer engine accepts is still accepted by that engine after a minor bump; a transaction using a *newer* field will be rejected by an *older* engine (rather than mis-interpreted). Any breaking change to an existing field's meaning gets a [CHANGELOG](https://github.com/stemma-sh/stemma/blob/main/CHANGELOG.md) entry.

### MCP tool schema: additive, renames are announced

The [MCP tool surface](/docs/reference/mcp.md) evolves additively within `0.x`:

* A tool's argument schema may gain **optional** parameters in a minor release.
* New tools may be added.
* A successful response may gain additive identity or diagnostic fields. Existing response keys keep their meaning; clients should ignore response fields they do not consume.
* Making a previously-optional parameter required, renaming a tool or a parameter, or removing one is a breaking change and gets a [CHANGELOG](https://github.com/stemma-sh/stemma/blob/main/CHANGELOG.md) entry.

Build agents against documented tool arguments; unknown arguments are rejected at the wire edge for the same reason transactions reject unknown fields.

### Task manifest: versioned and strict

`stemma.task_manifest.v1` is a persisted evidence format. Its schema field is mandatory, all objects reject unknown fields, and cross-field invariants are validated before emission and after decoding. An incompatible shape receives a new schema identifier; `stemma verify-task` refuses an unknown schema rather than guessing. Additive producer or diagnostic information therefore still requires an explicit schema decision instead of silently changing what an offline verifier trusts.

### HTTP API: demo surface, no stability promise

[`stemma-api`](/docs/reference/http.md) is demo infrastructure for the browser editor, not a product surface. Its routes and JSON shapes **carry no stability guarantee** and may change or disappear in any release without a changelog entry. It binds to loopback by default; `--host` binds all interfaces. It has no authentication, TLS, authorization, or rate limiting and must not be exposed to an untrusted network. See [SECURITY.md](https://github.com/stemma-sh/stemma/blob/main/SECURITY.md). If you need a stable programmatic surface, embed the Rust `api::Document` facade or drive the MCP tools.

## Summary

| Surface                       | Within a `0.x` minor line                       | Across `0.x` minors                             |
| ----------------------------- | ----------------------------------------------- | ----------------------------------------------- |
| Rust Tier 1 (`api::Document`) | stable                                          | may break, with changelog                       |
| Rust Tier 2 (typed IR)        | engine-version-bound; do not persist            | may change                                      |
| Rust Tier 3 (engine API)      | unstable                                        | may change                                      |
| `stemma-diff` facade          | stable within the matching minor line           | may break, with changelog                       |
| v4 transaction JSON           | additive; unknown fields rejected               | breaking meaning-changes get a changelog entry  |
| MCP tool schema               | additive (optional params)                      | renames/removals get a changelog entry          |
| Task manifest JSON            | exact versioned schema; unknown fields rejected | incompatible shapes get a new schema identifier |
| HTTP API                      | no promise                                      | no promise                                      |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://stemma.sh/docs/understand-the-model/stability.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
