<!-- Generated by crates/swarmops-cli/src/reference.rs from the code: do not edit. Change the code, then run SWARMOPS_REGEN_REFERENCE=1 with the regen_reference test. -->

# Schema types

The 91 request, response and value types of the API, as `swarmops schema` prints their JSON Schemas (2020-12); `swarmops schema <TYPE>` prints one. The command line, the MCP tools and the store exchange exactly this JSON.

## Index

| Type | Kind | Description |
| --- | --- | --- |
| [`Advanced`](#advanced) | object | `commit` with `advance`: the ref's move, made in the commit's own transaction. |
| [`Attribution`](#attribution) | object | Whom a changeset is attributed to. |
| [`BlobHasReq`](#blobhasreq) | object | `blob_has` (CLI `blob has`): which of some blobs the store holds. |
| [`BlobHasResp`](#blobhasresp) | object | `blob_has`: the blobs the store holds, of those asked for. |
| [`BlobPutReq`](#blobputreq) | object | `blob_put` (CLI `blob put`): store content as a blob, outside any commit, so that a commit's change list can name it by its id (`{"blob": id}`) instead of carrying its bytes. |
| [`BlobPutResp`](#blobputresp) | object | `blob_put`: the blob stored. |
| [`ChangeInput`](#changeinput) | object | One change of a commit. |
| [`ChangeOp`](#changeop) | enumeration | What a change does to its path, in a commit's change list and a changeset's changes alike. |
| [`ChangeOut`](#changeout) | object | One entry of a changeset's changes. |
| [`ChangesetDetail`](#changesetdetail) | object | `show`: a changeset's header, changes and metadata. |
| [`ChangesetSummary`](#changesetsummary) | object | One changeset of a log. |
| [`CommitReq`](#commitreq) | object | `commit`: record a changeset from an explicit change list. |
| [`CommitResp`](#commitresp) | object | `commit`: the changeset that was recorded. |
| [`ConflictKindOut`](#conflictkindout) | enumeration | What kind of conflict a file has. |
| [`ConflictReport`](#conflictreport) | object | Why a land could not merge its change onto the target, file by file, or could not apply its resolutions to it: the report `E_CONFLICT` carries in `details.report`. |
| [`ContentEncoding`](#contentencoding) | enumeration | How `FileContent.content` encodes bytes. |
| [`ContentInput`](#contentinput) | one of | A `put`'s content, as an object with one key. |
| [`DeriveReq`](#derivereq) | object | `derive`: derive ahead of any reader the eager derived values (each changeset's first-parent skip list) of the changesets the journal records after a frame, so that reads find them stored. |
| [`DeriveResp`](#deriveresp) | object | `derive`: how many values one call derived, how many the store held already, and where to go on. |
| [`Diff`](#diff) | object | `diff`: a page of the files that differ between two revisions, in path order (by bytes). |
| [`DiffFormat`](#diffformat) | enumeration | What `diff` says of each file. |
| [`DiffHunk`](#diffhunk) | object | A hunk of a unified diff: one or more changes and the unchanged lines around them, with the numbers of its header, `@@ -old_start,old_lines +new_start,new_lines @@`. |
| [`DiffLineOut`](#difflineout) | object | One line of a hunk. |
| [`DiffReq`](#diffreq) | object | `diff`: the files that differ between two revisions, in path order, a page at a time. |
| [`DiffStatus`](#diffstatus) | enumeration | What happened to a file between the two revisions. |
| [`EntryKindOut`](#entrykindout) | enumeration | What a tree entry is. |
| [`Envelope`](#envelope) | object | One command's output: `result` on success, `error` on failure, `meta` either way. |
| [`ErrorCode`](#errorcode) | enumeration | Why an operation failed: a stable code with a fixed exit code and retry advice. |
| [`FileConflictOut`](#fileconflictout) | object | One conflicting file. |
| [`FileContent`](#filecontent) | object | `read_file` (CLI `cat`): a file's content, or the part of it the request names. |
| [`FileDiff`](#filediff) | object | One file that differs: a file, an executable or a symlink whose content or kind changed, or that is on one side only. |
| [`FileKind`](#filekind) | enumeration | What a file is; never a directory. |
| [`GitExportReq`](#gitexportreq) | object | `git export`: write the history behind a store ref into a branch of a git repository. |
| [`GitExportResp`](#gitexportresp) | object | `git export`: what the export wrote, and where the branch stands. |
| [`GitImportReq`](#gitimportreq) | object | `git import`: bring a git repository's history into the store. |
| [`GitImportResp`](#gitimportresp) | object | `git import`: what the import brought in, and where the target ref stands. |
| [`HunkOut`](#hunkout) | object | One place where the two sides' edits of a text file meet: each side's lines there. |
| [`Identity`](#identity) | object | The caller of a mutation: an agent name `<family>/<instance>` (`agent/worker-17`, `human/purple`) and an optional run id. |
| [`IdentityInfo`](#identityinfo) | object | `whoami`: the identity the caller's mutations carry. |
| [`InfoReq`](#inforeq) | object | `info`: describe the store. |
| [`InitReq`](#initreq) | object | `init`: create a store. |
| [`LandReq`](#landreq) | object | `land`: merge a change three-way onto a target ref and publish it there as one new changeset, in one transaction. |
| [`LandResp`](#landresp) | object | `land`: where the change landed. |
| [`LandStatus`](#landstatus) | enumeration | How a land ended. |
| [`LineOp`](#lineop) | enumeration | Which side of a diff a hunk's line is on. |
| [`LineRange`](#linerange) | object | A range of a file's lines, numbered from 1: `first` to `last`, both included. |
| [`LinesOut`](#linesout) | object | One side's lines of a hunk: `first` to `last`, numbered from 1, both included. |
| [`LogCutOut`](#logcutout) | object | Where the journal was cut (`meta.recovered.log_cut`). |
| [`LogPage`](#logpage) | object | `log`: a page of changesets, newest first, following first parents. |
| [`LogReq`](#logreq) | object | `log`: history along first parents, a page at a time. |
| [`LossyClass`](#lossyclass) | enumeration | A class of git content that a changeset cannot hold as git has it. |
| [`LossyCommitOut`](#lossycommitout) | object | `git import`: a commit taken lossily, and what it lost. |
| [`Meta`](#meta) | object | What the envelope reports besides the outcome. |
| [`ModeInput`](#modeinput) | enumeration | The kind of entry a `put` writes. |
| [`OpChangesetOut`](#opchangesetout) | object | A changeset an operation recorded. |
| [`OpError`](#operror) | object | A failed operation: the envelope's `error` object. |
| [`OpLogPage`](#oplogpage) | object | `op_log` (CLI `op log`): a page of operations, newest first. |
| [`OpLogReq`](#oplogreq) | object | `op_log` (CLI `op log`): the store's operations, newest first, a page at a time. |
| [`OperationKind`](#operationkind) | enumeration | What an operation did, read from what it recorded. |
| [`OperationOut`](#operationout) | object | One operation: a write transaction, as the journal recorded it. |
| [`PathHistoryEntry`](#pathhistoryentry) | object | One changeset of a path's history, and what the path holds after it. |
| [`PathHistoryPage`](#pathhistorypage) | object | `path_history` (CLI `history`): a page of a path's history, newest first. |
| [`PathHistoryReq`](#pathhistoryreq) | object | `path_history` (CLI `history`): the changesets that changed what a path holds, newest first, following first parents, a page at a time. |
| [`ReadFileReq`](#readfilereq) | object | `read_file` (CLI `cat`): read one file at a revision, without a checkout: from an offset, or a range of its lines. |
| [`ReadTreeReq`](#readtreereq) | object | `read_tree` (CLI `ls`): list one directory at a revision, without a checkout, a page at a time; with `depth`, the directories below it too. |
| [`RecoveredOut`](#recoveredout) | object | What a write's recovery repaired (`meta.recovered`), as offsets and counts in the store's metadata files, with no paths. |
| [`RefDeleteReq`](#refdeletereq) | object | `ref delete`: remove a ref by compare-and-swap. |
| [`RefListReq`](#reflistreq) | object | `ref list`: list every ref. |
| [`RefListResp`](#reflistresp) | object | `ref list`: every ref. |
| [`RefMoveOut`](#refmoveout) | object | A move of a ref, as the journal recorded it. |
| [`RefOut`](#refout) | object | One ref. |
| [`RefSetReq`](#refsetreq) | object | `ref set`: move a ref, or create one, by compare-and-swap. |
| [`RefSetResp`](#refsetresp) | object | `ref set` and `ref delete`: the move that was made. |
| [`RepoInfo`](#repoinfo) | object | `init` and `info`: what the store is and holds. |
| [`ResolutionInput`](#resolutioninput) | object | What a land makes of one path, and of every path below it: exactly one of `take`, `content` and `delete` (anything else is `E_INVALID_ARG`, a rule the server checks), the rest of the merge as it merged. |
| [`ResolutionsInput`](#resolutionsinput) | object | A land's resolutions (`land --resolve`): what to make of some paths of the merge of the change onto the target, decided against one of the target's heads. |
| [`ResolveRevReq`](#resolverevreq) | object | `resolve_rev` (CLI `resolve`): the changeset a revision names, as every operation resolves it. |
| [`ResolvedRev`](#resolvedrev) | object | `resolve_rev` (CLI `resolve`): the changeset a revision names, and what kind of revision it is. |
| [`Rev`](#rev) | string | A revision as the caller wrote it, for the store to resolve: a ref name (`main`, `release/1.2`), a full 64-hex changeset id or a unique prefix of at least 12 hex digits, optionally followed by `~N` for the N-th first-parent ancestor. |
| [`RevKind`](#revkind) | enumeration | What kind of revision `resolve_rev` resolved. |
| [`ShowReq`](#showreq) | object | `show`: one changeset in full. |
| [`Side`](#side) | enumeration | One side of a land's merge. |
| [`SignatureOut`](#signatureout) | object | A git signature: who, and when. |
| [`Signatures`](#signatures) | object | A changeset's git signatures: git-fidelity data for import and export. |
| [`TreeEntryOut`](#treeentryout) | object | One entry of a listing. |
| [`TreeListing`](#treelisting) | object | `read_tree` (CLI `ls`): a page of a directory's entries, in pre-order: a directory, then the entries below it to the request's `depth`, each directory's entries by name bytes (at `depth` 1, the tree's order). |
| [`UndoReq`](#undoreq) | object | `undo` (CLI `op undo`): restore every ref an operation moved to what it named before, by compare-and-swap, in one transaction: all of them or none. |
| [`UndoResp`](#undoresp) | object | `undo` (CLI `op undo`): the moves that restored the refs. |
| [`VerifyFinding`](#verifyfinding) | object | One problem `verify` found, as a program reads it: what kind of damage it is, and what it names. |
| [`VerifyReport`](#verifyreport) | object | `verify`: what the consistency check found. |
| [`VerifyReq`](#verifyreq) | object | `verify`: check the whole store's consistency. |

## Advanced

`commit` with `advance`: the ref's move, made in the commit's own transaction.

Kind: object. `swarmops schema Advanced` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `already_applied` | `boolean` | yes | The ref held the changeset already, from an identical request before, so nothing was written and a replay is safe. |
| `name` | `string` | yes | The ref. |
| `new` | `string` | yes | What it holds now: the changeset. |
| `old` | `string` or `null` | no | What the ref held before: the changeset's parent; omitted for a root commit, whose move created the ref. |

## Attribution

Whom a changeset is attributed to.

Kind: object. `swarmops schema Attribution` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `agent` | `string` | yes | The agent that wrote it: the changeset's `agent` metadata, or `unknown/unknown` for a changeset that records none. |
| `on_behalf_of` | `string` or `null` | no | Whom the agent acted for; recorded once the review model exists, so omitted in M1. |
| `run_id` | `string` or `null` | no | The run it was written in: the changeset's `run_id` metadata, when present. |

## BlobHasReq

`blob_has` (CLI `blob has`): which of some blobs the store holds.

Kind: object. `swarmops schema BlobHasReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `ids` | array of `string` | yes | The blob ids, 64 hex digits each; one that is not is `E_INVALID_ARG`. |

## BlobHasResp

`blob_has`: the blobs the store holds, of those asked for.

Kind: object. `swarmops schema BlobHasResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `present` | array of `string` | yes | The ids of `ids` that the store holds a blob under, in lowercase hex, in the order first given, each once; an id of another kind of object (a tree, a changeset) is not among them. |

## BlobPutReq

`blob_put` (CLI `blob put`): store content as a blob, outside any commit, so that a commit's change list can name it by its id (`{"blob": id}`) instead of carrying its bytes. The blob is durable once the call returns; until a commit names it, nothing references it.

Kind: object. `swarmops schema BlobPutReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `content` | [`ContentInput`](#contentinput) | yes | The content: inline, base64 or a client file, at most 512 MiB (more is `E_TOO_LARGE` with `scope` `put`). A `blob` names content the store holds already, and is `E_INVALID_ARG` here. |

## BlobPutResp

`blob_put`: the blob stored.

Kind: object. `swarmops schema BlobPutResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `blob` | `string` | yes | The blob's id, which a change names it by: `{"blob": id}`. |
| `size` | `integer` (uint64) | yes | The content's size in bytes. |
| `written` | `boolean` | yes | Whether this call placed the blob in the object store; false when the store held it already, or a concurrent writer placed it first. |

## ChangeInput

One change of a commit.

Kind: object. `swarmops schema ChangeInput` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `content` | [`ContentInput`](#contentinput) or `null` | no | The new content, at most 512 MiB (more is `E_TOO_LARGE` with `scope` `put`); a `put` needs it, a `delete` takes none. |
| `mode` | [`ModeInput`](#modeinput) or `null` | no | The kind of entry a `put` writes; `file` when omitted. |
| `op` | [`ChangeOp`](#changeop) | yes | Whether to write the path or remove it. |
| `path` | `string` | yes | The repository path: `/`-separated, relative to the root. |

## ChangeOp

What a change does to its path, in a commit's change list and a changeset's changes alike.

Kind: enumeration. `swarmops schema ChangeOp` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"put"` | Write the content at the path, creating or replacing the entry. |
| `"delete"` | Remove the path. |

## ChangeOut

One entry of a changeset's changes.

Kind: object. `swarmops schema ChangeOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `blob` | `string` or `null` | no | For a `put`: the content's blob id. |
| `kind` | [`FileKind`](#filekind) or `null` | no | For a `put`: the file's kind. |
| `op` | [`ChangeOp`](#changeop) | yes | What happened to the path. |
| `path` | `string` | yes | The repository path. |

## ChangesetDetail

`show`: a changeset's header, changes and metadata. Byte strings are decoded as UTF-8, with invalid bytes replaced, except metadata values (see `metadata`).

Kind: object. `swarmops schema ChangesetDetail` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `author` | [`Attribution`](#attribution) | yes | Who wrote the change. |
| `changes` | array of [`ChangeOut`](#changeout) | yes | What changed relative to the first parent, ordered by path: at most `max_changes` entries. |
| `changes_truncated` | `boolean` | yes | Whether `changes` stops before the changeset's last change. |
| `created_at` | `integer` (uint64) | yes | When it was recorded: the committer signature's time, in Unix milliseconds. |
| `files_changed` | `integer` (uint64) | yes | How many paths the changeset changes in all, also when `changes` is truncated. |
| `id` | `string` | yes | The changeset's id. |
| `land_key` | `string` or `null` | no | The idempotency key of the land that made it (its `land_key` metadata), when it had one. |
| `lander` | [`Attribution`](#attribution) or `null` | no | Who landed it, for a changeset a `land` made: its `lander` and `lander_run_id` metadata. Omitted for any other changeset. |
| `message` | `string` | yes | The message. |
| `metadata` | map of `string` to `string` | yes | SwarmOps metadata, such as `agent` and `run_id`. A value that is not UTF-8 is given in standard, padded base64, under its key with `:b64` appended. A commit refuses a key that ends in `:b64`, so `k:b64` is always the base64 of `k`'s value, which is not UTF-8. |
| `parents` | array of `string` | yes | The parents' ids; the first is the mainline parent that `changes` are relative to. |
| `root` | `string` | yes | The root tree's id. |
| `seq` | `integer` (uint64) | yes | Its position in the store's changeset index, in commit order. |
| `signatures` | [`Signatures`](#signatures) | yes | The git author and committer signatures, kept for git fidelity. |
| `squashed_from` | array of `string` | no | The changesets a land squashed into it, oldest first: the landed head's first-parent chain after the land's base, ending at that head (its `squashed_from` metadata). Omitted for a changeset no land made. |

## ChangesetSummary

One changeset of a log.

Kind: object. `swarmops schema ChangesetSummary` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `author_agent` | `string` | yes | The agent that wrote it, as `show` gives `author.agent`. |
| `created_at` | `integer` (uint64) | yes | When it was recorded: the committer signature's time, in Unix milliseconds. |
| `id` | `string` | yes | The changeset's id. |
| `parents` | array of `string` | yes | The parents' ids, mainline parent first. |
| `title` | `string` | yes | The message's first line. |

## CommitReq

`commit`: record a changeset from an explicit change list. It moves no ref, unless `advance` names one.

Kind: object. `swarmops schema CommitReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `advance` | `string` or `null` | no | Also move this ref (`main` or `release/<name>`) to the new changeset, in the same transaction as the changeset itself, so that both are recorded or neither. The move happens only if the ref still names the changeset's parent (for a root commit, only if the ref does not exist yet): it is always a one-step fast-forward. Otherwise nothing is recorded and the commit fails with `E_CAS_MISMATCH` (`details.committed: false`, `details.actual` what the ref names). Give as `parent` the full id the ref held when you read it: without `parent` the commit builds on the ref's head when it runs, so the move catches a race from there on, not a change made since you read the ref (M1 has no merge). `swarmops mcp` refuses `advance` without a full 64-hex `parent` (`E_INVALID_ARG`). A store that does not know this field ignores it and moves no ref: its response has no `advanced`. |
| `allow_empty` | `boolean` | no | Record the changeset even if it changes nothing. Default: `false`. |
| `changes` | array of [`ChangeInput`](#changeinput) | yes | What to change, relative to the parent. The contents hold at most 1 GiB together, by the sizes they declare (inline text's length, the bytes base64 decodes to, a client file's length; a `blob` named by id counts nothing): more is `E_TOO_LARGE` with `scope` `commit`, refused before any content is read. Store large contents with `blob_put` first, and name them by id. |
| `idempotency_key` | `string` or `null` | no | Makes a retry of this commit safe: a uuid v7 (anything else is `E_INVALID_ARG`). The commit takes the key's time, to the second, as its signature time and records the key as `commit_key` metadata, so the same request on the same parent makes the same changeset, which the store holds already: the response says `replayed`, and nothing is written. With `advance`, a ref whose head carries the key is a replay too. Give `parent` by its full id: without it, a retry after the head moved commits again, on the new head. |
| `message` | `string` | yes | The commit message. |
| `parent` | [`Rev`](#rev) or `null` | no | The changeset to commit on top of. An explicit `parent` always wins; when it is omitted, the current head of the ref `advance` names is used, else of `main`, if that ref exists, and otherwise the commit is a root commit. `null` is the same as omitting it. Once `main` exists, a root commit needs an `advance` naming a ref that does not exist yet (a known M1 limitation). |

## CommitResp

`commit`: the changeset that was recorded.

Kind: object. `swarmops schema CommitResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `advanced` | [`Advanced`](#advanced) or `null` | no | The move of the ref the request's `advance` named: present exactly when the ref names `changeset` because of this request, or of an identical one before it (`already_applied`). A request with `advance` whose response lacks it went to a store that ignores the field, and moved no ref. |
| `blobs_written` | `integer` (uint64) | yes | How many blobs this commit's own writes placed in the object store; blobs that were there already, or that a concurrent writer placed first, count 0. |
| `changeset` | `string` | yes | The new changeset's id. |
| `files_changed` | `integer` (uint64) | yes | How many paths the changeset changes. |
| `parent` | `string` or `null` | no | The changeset it was committed on top of; omitted for a root commit. |
| `replayed` | `boolean` | no | The store held the changeset already, from an identical request before (a retry with the same `idempotency_key`), so nothing was written. Always written; a response from a store that does not know the field reads as `false`. Default: `false`. |
| `root` | `string` | yes | The new root tree's id. |
| `warnings` | array of `string` | no | Problems found after the commit became durable, such as failed housekeeping; the commit itself succeeded. Omitted when empty. |

## ConflictKindOut

What kind of conflict a file has. `ours` is the change, `theirs` the target.

Kind: enumeration. `swarmops schema ConflictKindOut` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"content"` | Both sides edited the same lines of a text file, or lines next to each other. |
| `"binary"` | Both sides changed the content of a file that is not text, or of a symlink, differently. |
| `"delete_modify"` | The change deleted the file, and the target changed it. |
| `"modify_delete"` | The change changed the file, and the target deleted it. |
| `"add_add"` | Both sides added the file, with contents that do not merge. |
| `"mode"` | Both sides changed the file's kind (file, executable or symlink), differently. |
| `"type_change"` | One side has a file where the other has a directory. |

## ConflictReport

Why a land could not merge its change onto the target, file by file, or could not apply its resolutions to it: the report `E_CONFLICT` carries in `details.report`. `ours` is the change, `theirs` the target. Ids are full.

Kind: object. `swarmops schema ConflictReport` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `auto_merged` | array of `string` | no | The paths both sides changed that merged cleanly. Omitted when empty. |
| `base` | `string` | yes | The merge base: the changeset the change starts from. |
| `files` | array of [`FileConflictOut`](#fileconflictout) | yes | The files that conflict, by path. |
| `kinds` | array of [`ConflictKindOut`](#conflictkindout) | yes | The kinds of conflict in `files`, each once. |
| `ours` | `string` | yes | The change's head. |
| `stale` | array of `string` | no | The paths whose resolutions did not apply, since the target holds there what their `against` did not: the target changed them after the report the resolutions answered. Read them at `theirs` and resolve them again, against it. Omitted when empty. |
| `theirs` | `string` | yes | The target's head the change was merged with. |
| `truncated` | `boolean` | yes | Whether hunk texts were left out to keep the report within the request's `max_conflict_bytes`; the line positions and blob ids are always there. |

## ContentEncoding

How `FileContent.content` encodes bytes.

Kind: enumeration. `swarmops schema ContentEncoding` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"utf8"` | The bytes are UTF-8 text, and `content` is that text. |
| `"base64"` | `content` is the bytes in standard, padded base64. |

## ContentInput

A `put`'s content, as an object with one key.

Kind: one of. `swarmops schema ContentInput` prints its JSON Schema.

One of:

- `inline`: `string`. UTF-8 text, verbatim.
- `base64`: `string`. Bytes in standard, padded base64.
- `blob`: `string`. A blob the store holds already, by its id (64 hex digits), as `blob_put` returns it: the commit neither sends nor reads its bytes. An id the store holds no blob under (none, or a tree's or a changeset's) is `E_INVALID_ARG`, and nothing is written. `blob_put` takes the other forms only.
- `file`: `string`. A file on the client's machine. The client reads it and sends its bytes, so the store is never asked to read a path.

## DeriveReq

`derive`: derive ahead of any reader the eager derived values (each changeset's first-parent skip list) of the changesets the journal records after a frame, so that reads find them stored. It writes only the store's cache of derived values, so it takes no identity.

Kind: object. `swarmops schema DeriveReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `after` | `integer` (uint64) or `null` | no | Go on after this journal frame: a previous call's `next`. From the journal's first frame when omitted. |
| `limit` | `integer` (uint) | no | The most journal frames to read; a frame is one transaction, a commit or a ref's move. 0 reads none and derives nothing: `next` is then the journal's last frame, from where the next calls derive only what is recorded later. Default: `1000`. |

## DeriveResp

`derive`: how many values one call derived, how many the store held already, and where to go on.

Kind: object. `swarmops schema DeriveResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cached` | `integer` (uint64) | yes | How many of those values the store held already. |
| `derived` | `integer` (uint64) | yes | How many values it derived: of each eager derivation, one for each changeset its frames record whose value the store lacked. Values those needed on the way, an older changeset's, are derived too and not counted. |
| `next` | `integer` (uint64) or `null` | no | The last frame it read: pass it as the next call's `after` to go on, through a journal longer than `limit` frames or through the frames recorded since. Omitted when it read no frame, as none follows `after`: it is at the journal's end. With `limit` 0, the journal's last frame, omitted while the journal holds none. |

## Diff

`diff`: a page of the files that differ between two revisions, in path order (by bytes).

Kind: object. `swarmops schema Diff` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | `string` or `null` | no | When `truncated`: where the next page starts. Opaque: pass it back as given, as the next request's `cursor`. |
| `files` | array of [`FileDiff`](#filediff) | yes | The files. |
| `from` | `string` | yes | The changeset `from` named. |
| `to` | `string` | yes | The changeset `to` named. |
| `truncated` | `boolean` | yes | Whether more files follow this page. |

## DiffFormat

What `diff` says of each file.

Kind: enumeration. `swarmops schema DiffFormat` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"names"` | Its path and status. |
| `"stat"` | Also whether it is binary and, for text, the lines it inserts and deletes. |
| `"unified"` | Also its kinds, its blobs and, for text, its hunks. |

## DiffHunk

A hunk of a unified diff: one or more changes and the unchanged lines around them, with the numbers of its header, `@@ -old_start,old_lines +new_start,new_lines @@`.

Kind: object. `swarmops schema DiffHunk` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `lines` | array of [`DiffLineOut`](#difflineout) | yes | Its lines, in order; each change's removed lines come before its added lines. |
| `new_lines` | `integer` (uint64) | yes | How many new lines it holds: its context and added lines. |
| `new_start` | `integer` (uint64) | yes | The first new line it holds, counted as `old_start` is. |
| `old_lines` | `integer` (uint64) | yes | How many old lines it holds: its context and removed lines. |
| `old_start` | `integer` (uint64) | yes | The first old line it holds, counted from 1; when it holds none, the line before where they would be (0 at the top), as git prints it. |

## DiffLineOut

One line of a hunk.

Kind: object. `swarmops schema DiffLineOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | [`LineOp`](#lineop) | yes | Whether both sides have it, only the new one, or only the old one. |
| `text` | `string` | yes | The line with its line break, a carriage return before it kept; a file's last line has none when the file does not end in one. |

## DiffReq

`diff`: the files that differ between two revisions, in path order, a page at a time.

Kind: object. `swarmops schema DiffReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `context` | `integer` (uint32) | no | The unchanged lines around each change in a `unified` hunk. Default: `3`. |
| `cursor` | `string` or `null` | no | Resume a diff: the previous page's `cursor`. Pass it back exactly as returned; do not construct it (cursors are opaque). This page starts after the file it names. |
| `format` | [`DiffFormat`](#diffformat) | no | What to say of each file: `names` its path and status; `stat` also whether it is binary and, for text, the lines it inserts and deletes; `unified` also its kinds, its blobs and, for text, its hunks. Default: `"names"`. |
| `from` | [`Rev`](#rev) | yes | The revision to diff from: the old side. |
| `limit` | `integer` (uint) | no | The most files to return: at least 1 (0 is `E_INVALID_ARG`). Default: `500`. At least 1. |
| `max_bytes` | `integer` (uint64) | no | The most bytes a `unified` page's files take, as the JSON array `files` they print as: at least 1 (0 is `E_INVALID_ARG`). The page stops before the first file that would take it past this, but always holds one file, whose hunks are cut to the first ones that fit (`hunks_truncated`) when they alone would pass it. A `names` or `stat` page is held by `limit` alone. Default: `32768`. At least 1. |
| `paths` | array of `string` | no | Only the files at or below these repository paths (a file's path takes that file; one trailing `/` is taken); every file when empty or omitted. |
| `to` | [`Rev`](#rev) | yes | The revision to diff to: the new side. |

## DiffStatus

What happened to a file between the two revisions.

Kind: enumeration. `swarmops schema DiffStatus` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"added"` | It is in `to` only: in `from`, nothing or a directory is there. |
| `"deleted"` | It is in `from` only. |
| `"modified"` | Its content or its exec bit changed: a file or an executable on both sides, or a symlink on both sides. |
| `"type_changed"` | A symlink on one side, a file or an executable on the other. |

## EntryKindOut

What a tree entry is.

Kind: enumeration. `swarmops schema EntryKindOut` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"file"` | A regular file. |
| `"exec"` | An executable file. |
| `"symlink"` | A symlink. |
| `"dir"` | A directory. |

## Envelope

One command's output: `result` on success, `error` on failure, `meta` either way.

Exactly one of `result` and `error` is present; the other is omitted, never written as null.

Kind: object. `swarmops schema Envelope` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `api` | `integer` (uint32) | yes | The API version. |
| `error` | [`OpError`](#operror) | no | The failure; present exactly when not `ok`. |
| `meta` | [`Meta`](#meta) | yes | Context for either outcome. |
| `ok` | `boolean` | yes | Whether the operation succeeded. |
| `op` | `string` | yes | The operation's name, such as `commit`. |
| `result` | any | no | The operation's response; present exactly when `ok`. |

Exactly one of these shapes holds:

- `result` is present; `error` is absent; `ok` is `true`.
- `error` is present; `result` is absent; `ok` is `false`.

## ErrorCode

Why an operation failed: a stable code with a fixed exit code and retry advice.

Serialized as its `E_*` string, which `OpError.code` carries too, so a client can read codes newer than its copy of this enum.

Kind: enumeration. `swarmops schema ErrorCode` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"E_EXISTS"` | `init` found a store at the target path already. |
| `"E_NOT_A_REPO"` | No store at the given path, or no store was named. |
| `"E_IDENTITY_REQUIRED"` | A mutation was asked for without an identity. |
| `"E_REV_NOT_FOUND"` | A revision names no changeset. |
| `"E_AMBIGUOUS_ID"` | An id prefix matches more than one changeset; give more digits. |
| `"E_PATH_NOT_FOUND"` | The path does not exist at that revision. |
| `"E_IS_DIR"` | A file operation named a directory. |
| `"E_TOO_LARGE"` | The content is larger than the operation allows. |
| `"E_EMPTY_COMMIT"` | The commit changes nothing and `allow_empty` is off. |
| `"E_TYPE_CONFLICT"` | A change puts an entry below a file, or a file onto a directory. |
| `"E_UNKNOWN_PARENT"` | The parent changeset is not in the store. |
| `"E_CAS_MISMATCH"` | The ref no longer holds the expected target (or, with `create`, exists at another one); `details.actual` holds what it does, `null` when the ref does not exist. |
| `"E_REF_NOT_FOUND"` | No ref by that name. |
| `"E_REF_NAME_INVALID"` | The ref name is not `main` or `release/<name>`. |
| `"E_STORE_CORRUPT"` | Stored data failed verification. A metadata file that does not parse also names `details.fs_op` and `details.store_file`. |
| `"E_INVALID_ARG"` | A malformed argument or request, including a command-line usage error. |
| `"E_UNSUPPORTED_FS"` | The store path is not on a native Linux filesystem (for example WSL's `/mnt/*`). |
| `"E_IO"` | The filesystem refused an operation: `details.fs_op` names it, and `details.store_file` the file of the store it was on, relative to the store's root. A journal append it refused for want of permission or as a read-only filesystem also says `details.committed: false`: nothing was committed, and running the same operation again fails the same way until the hint's cause is fixed. |
| `"E_IO_TRANSIENT"` | A journal append failed, and the store cut what it wrote back off the journal (`details.committed` is `false`): nothing was committed, so running the same operation again is safe. A failure after the commit point is no error: the operation succeeds, with a warning. `details.fs_op` and `details.store_file` name the append that failed. |
| `"E_BUSY"` | Another writer held the store's metadata lock for the whole wait, or commits landed during every one of a read's attempts to take a snapshot; nothing was committed (a commit's flushed objects may remain, for GC), and running the operation again can succeed. |
| `"E_INTERNAL"` | A bug in SwarmOps, such as a caught panic. |
| `"E_CONFLICT"` | The change conflicts with the target: `details.report` lists each conflicting file with its kind, its hunks and who changed it on the target. Nothing was recorded; resolve the conflicts, then land again (the `hint` says how). |
| `"E_CAS_RETRY_EXHAUSTED"` | The target moved before every one of the land's attempts could publish; nothing was recorded, and running the land again can succeed. |
| `"E_NOTHING_TO_LAND"` | The land has nothing to add to the target: its head is on the target already, or its change is (`details.reason` says which). |
| `"E_NOTHING_TO_UNDO"` | The operation moved no ref, so there is nothing to restore. |
| `"E_OP_NOT_FOUND"` | The store has no operation by that number. |
| `"E_AUTH"` | The caller's token failed verification. |
| `"E_POLICY_DENIED"` | A policy refused the operation for this identity. |
| `"E_MAINTENANCE_BUSY"` | Maintenance (gc or verify) holds the store's maintenance lease. |
| `"E_GIT_NOT_A_REPO"` | `git import` found no git repository it can open at `git_path` (`details.git_path`). |
| `"E_GIT_REF_NOT_FOUND"` | `git import`: the source repository has no `git_ref`, or it names no commit (`details.git_ref`; `details.kind` the object it names instead, such as a tree). |
| `"E_GIT_IMPORT_DIVERGED"` | `git import`: the target ref's head is not the import of `git_ref`'s commit or of an ancestor of it, because the source was rewritten or a native changeset was committed on the target, so nothing was written; there is no silent merge. `details` names `target_ref`, `target_head`, `git_head` and `base`, the git commit the head stands for (the one it holds, or for a native head the one it exports to); and `external_id` (`commit`, `changeset`) where the import passed over an external id entry whose changeset stands for another commit, which `verify --deep` reports. |
| `"E_GIT_IMPORT_LOSSY"` | `git import`: a commit holds content a changeset cannot keep as git has it; `details` names the `commit`, the `path` (also as `path_base64` when it is not UTF-8) and the lossy `class`, which the request's `lossy` can allow. The import stops before that commit, and the target ref does not move. |
| `"E_GIT_UNSUPPORTED"` | `git import` does not read the source: a SHA-256 repository, reftable refs, a shallow clone, a FIFO, a socket or a device where it reads a file of the git directory, a file it reads whole there that is longer than 16 MiB, a commit of more than 255 parents, or an entry whose mode is no kind of entry; `details.reason` says which (`object_format`, `ref_storage`, `shallow`, `special_file`, `file_too_long`, `parents`, `mode`), `details.file` names the file of `special_file` and `file_too_long` by its path in the git directory (`details.size` and `details.max` give the long one's length and the limit), and `details.commit` names the commit of `parents` and `mode`. |
| `"E_GIT_READ"` | `git import` could not read the source: an object is missing (as in a partial clone), does not hash to its id or does not parse, or the filesystem refused a read (`details.reason`; `details.object` names the object when there is one). |
| `"E_GIT_EXPORT_DIVERGED"` | `git export`: the branch holds commits that are not the export of the source ref's head or of an ancestor of it, so the branch did not move; there is no silent merge, and the request's `force` moves it anyway. `details.reason` says why: `branch_ahead` (commits made in git on top of the export of the head itself, which `git import` brings in), `both_moved` (commits made in git on top of an older export, while the source ref moved too), `branch_moved` (the branch names a commit that is no export of this history), `source_moved_back` (the source ref's head is behind the export the branch holds, after an `undo` or a `ref set` backwards), `lossy_history` (the branch holds the original commits of a history imported lossily, which the export would replace) or `moved_during_export` (another writer moved the branch while this export wrote; running the export again settles it, and what it wrote stays). The first five are found before anything is written. `details` also names `branch`, `git_head` (the commit the branch holds), `head_changeset` and, when the branch holds the export of a changeset, `exported_changeset`. |
| `"E_GIT_WRITE"` | `git export` could not write the repository; `details.reason` says what failed: `io` (the filesystem refused a write; `details.path` names the file, relative to the git directory), `ref_locked` (the branch's lock file, `refs/heads/<branch>.lock`, exists: another git process holds it, or an earlier export died holding it, and git itself says to remove it once no git process runs; `details.path` names it) or `ref_name_conflict` (an existing ref stands where the branch's name needs a directory, or the other way round; `details.branch`). Running the export again after the cause is gone writes what is still missing. |

## FileConflictOut

One conflicting file. Its blobs are the file's content on each side, which `read_file` reads at that side's changeset; a side without a file at the path (deleted, never added, or a directory there) has none.

Kind: object. `swarmops schema FileConflictOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `base_blob` | `string` or `null` | no | Its blob at the merge base. |
| `hunks` | array of [`HunkOut`](#hunkout) | no | The places where the two sides' edits of its lines meet, in file order: for a text file both sides edited (`content`, and `add_add` of two texts). Omitted when there are none. |
| `kind` | [`ConflictKindOut`](#conflictkindout) | yes | What kind of conflict it is. |
| `ours_blob` | `string` or `null` | no | Its blob in the change. |
| `path` | `string` | yes | The file's repository path. |
| `theirs_agent` | `string` or `null` | no | The agent that wrote `theirs_changeset`. |
| `theirs_blob` | `string` or `null` | no | Its blob on the target. |
| `theirs_changeset` | `string` or `null` | no | The newest changeset on the target since the merge base that changed this path: what to read for the other side's edit. |

## FileContent

`read_file` (CLI `cat`): a file's content, or the part of it the request names.

Kind: object. `swarmops schema FileContent` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `blob` | `string` | yes | The blob's id. |
| `content` | `string` | yes | The bytes returned: those from `offset`, or the requested lines, at most `max_bytes` of them. A cut keeps text as text: it falls where a character starts, so text may stop up to 3 bytes short of `max_bytes`, while bytes that are not text stop at exactly `max_bytes`. |
| `encoding` | [`ContentEncoding`](#contentencoding) | yes | How `content` encodes the bytes it returns: `utf8` when they are text, `base64` when they are not (as when `offset` falls inside a character). |
| `kind` | [`FileKind`](#filekind) | yes | The file's kind. |
| `lines` | [`LineRange`](#linerange) or `null` | no | For a request by `lines`: the lines of its range that exist, which `content` holds (the start of them when `truncated`); omitted when none does. |
| `next_offset` | `integer` (uint64) or `null` | no | When `truncated`: where `content` stops, the `offset` that reads on from there. A cut text holds whole characters, so a `max_bytes` under 4 can stop before a longer character at the `offset` it started from. |
| `offset` | `integer` (uint64) or `null` | no | Where `content` starts in the file, in bytes: the request's `offset`, or where the first of its `lines` that exists starts (the file's size when none does); omitted when that is the file's start. |
| `size` | `integer` (uint64) | yes | The whole blob's size in bytes, also when `content` is part of it. |
| `truncated` | `boolean` | yes | Whether `content` stops before the end of what was asked for: the file, from `offset`; or the requested lines that exist. |

## FileDiff

One file that differs: a file, an executable or a symlink whose content or kind changed, or that is on one side only. A directory never is one: a file that becomes a directory is that file deleted and the directory's files added. No rename is detected: a file that moved is one deleted and one added. Which fields follow `status` depends on the request's `format`, and a field that says nothing is omitted.

Kind: object. `swarmops schema FileDiff` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `binary` | `boolean` or `null` | no | `stat` and `unified`: whether it is binary, which gets no line counts and no hunks: a side that is not UTF-8, or holds a NUL in its first 8,000 bytes. |
| `deletions` | `integer` (uint64) or `null` | no | `stat` and `unified`, for text: the lines the change deletes. |
| `hunks` | array of [`DiffHunk`](#diffhunk) or `null` | no | `unified`, for text: the hunks, in order; empty when only the exec bit or the kind changed. |
| `hunks_truncated` | `boolean` or `null` | no | `unified`: true when `hunks` stops before the file's last hunk, to keep the page within `max_bytes`; omitted otherwise. `insertions` and `deletions` count every line all the same. |
| `insertions` | `integer` (uint64) or `null` | no | `stat` and `unified`, for text: the lines the change inserts. |
| `new_blob` | `string` or `null` | no | `unified`: its blob id in `to`; omitted for a deleted file. |
| `new_kind` | [`FileKind`](#filekind) or `null` | no | `unified`: its kind in `to`; omitted for a deleted file. |
| `old_blob` | `string` or `null` | no | `unified`: its blob id in `from`; omitted for an added file. |
| `old_kind` | [`FileKind`](#filekind) or `null` | no | `unified`: its kind in `from`; omitted for an added file. |
| `path` | `string` | yes | The repository path. |
| `status` | [`DiffStatus`](#diffstatus) | yes | What happened to it. |

## FileKind

What a file is; never a directory.

Kind: enumeration. `swarmops schema FileKind` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"file"` | A regular file. |
| `"exec"` | An executable file. |
| `"symlink"` | A symlink. |

## GitExportReq

`git export`: write the history behind a store ref into a branch of a git repository. Every commit that the branch's last export does not reach is written, parents first: a changeset that was imported from git keeps the commit it came from, and one made in the store becomes a commit with its own signatures and `SwarmOps-*` trailers. The branch moves to the export of the ref's head by compare-and-swap, and only once everything it reaches is durable. It runs on the caller's host, as `git import` does: no server receives this request, and it is no MCP tool.

Kind: object. `swarmops schema GitExportReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `branch` | `string` | no | The git branch to write, by its short name (`main`, the default, or `stable`; the repository's `refs/heads/<branch>`), created if it does not exist. If it does, its commit must be the export of `source_ref`'s head or of an ancestor of it, and only the commits after that export are written; a branch at any other commit is `E_GIT_EXPORT_DIVERGED`, and nothing is written. In a repository with a work tree, the branch that `HEAD` names is refused (`E_INVALID_ARG`, with `details.reason` `checked_out`), as `git push` refuses it by default. Default: `"main"`. |
| `force` | `boolean` | no | Move the branch although it diverged: to the export of `source_ref`'s head, by compare-and-swap against the commit the export read, so that a branch another writer moves meanwhile still stops it. It does not override a checked-out branch. Off by default. Default: `false`. |
| `git_path` | `string` | yes | The git repository to write, on the caller's host: its directory, absolute or relative to the caller's working directory (a bare repository, or a work tree with its `.git`). It exists already: `git init --bare` makes one. The caller reads and writes it; no store or server is ever asked to read or write a path. |
| `source_ref` | `string` | no | The store ref whose history to export: `main` (the default) or `release/<name>`. Its head is the commit the branch ends at. Default: `"main"`. |

## GitExportResp

`git export`: what the export wrote, and where the branch stands.

Kind: object. `swarmops schema GitExportResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `branch` | `string` | yes | The branch the export wrote, by its short name. |
| `branch_moved` | `boolean` | yes | Whether this export moved the branch, or created it; `false` when the branch named `head_sha` already, after an earlier export of the same head or a concurrent one. |
| `exported` | `integer` (uint64) | yes | How many commits this export wrote to the repository: the commits of the ref's history that the branch's last export did not reach and the repository did not hold. A branch that is up to date exports 0. |
| `head_changeset` | `string` | yes | The changeset at `source_ref`'s head, which `head_sha` is the export of. |
| `head_sha` | `string` | yes | The commit the branch names now, the export of `head_changeset`: its git id, 40 lowercase hex digits. |
| `incremental` | `boolean` | yes | Whether the branch held an earlier export that this one continued, so that only the commits after it were written; `false` for a branch the export created, or one that `force` moved from a history that was no export of this one. |
| `objects_written` | `integer` (uint64) | yes | How many git objects (commits, trees and blobs) this export wrote to the repository. |
| `old_sha` | `string` or `null` | no | The commit the branch named when the export started; omitted when the branch did not exist, and the export created it. |
| `rewritten` | `integer` (uint64) | yes | How many of the exported commits have another id than the commit they were imported from: a commit the import took lossily (`git.lossy`) renders to other bytes than the git commit it came from, and so does every commit above it, whose parent has another id now; their signature headers no longer verify. Commits made in the store were never imported and are not counted. |
| `warnings` | array of `string` | no | What the export has to say that did not stop it, such as how many of its commits it rewrote (`rewritten`). Omitted when empty. |

## GitImportReq

`git import`: bring a git repository's history into the store. Every commit that `git_ref` reaches and the store does not hold yet becomes a changeset, parents first, and `target_ref` moves to the changeset of `git_ref`'s commit. It runs on the caller's host, as `init` does: no server receives this request, and it is no MCP tool.

Kind: object. `swarmops schema GitImportReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `git_path` | `string` | yes | The git repository to read, on the caller's host: its directory, absolute or relative to the caller's working directory (a bare repository, or a work tree with its `.git`). The caller reads it; no store or server is ever asked to read a path. |
| `git_ref` | `string` | no | The commit to import, with every commit it reaches: `HEAD` (the default), a ref name, short or full (`stable`, `refs/heads/stable`), looked up in git's order, or a commit id of 40 hex digits; a tag is peeled to its commit. There is no revision syntax such as `main~3`. Default: `"HEAD"`. |
| `lossy` | array of [`LossyClass`](#lossyclass) | no | The classes of content the import may drop or normalize; a changeset that loses any names them in its `git.lossy` metadata. Empty by default: a commit holding any class is refused with `E_GIT_IMPORT_LOSSY`, which names the commit, the path and the class. Default: `[]`. |
| `target_ref` | `string` | no | The ref to move to that commit's changeset: `main` (the default) or `release/<name>`, created if it does not exist. If it does, its head must be the import of that commit or of an ancestor of it, and only the commits after that head are imported; any other head (the source was rewritten, or a native changeset was committed on the ref) is `E_GIT_IMPORT_DIVERGED`, and nothing is written. Default: `"main"`. |

## GitImportResp

`git import`: what the import brought in, and where the target ref stands.

Kind: object. `swarmops schema GitImportResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `git_head_sha` | `string` | yes | `git_ref`'s commit: its git id, 40 lowercase hex digits. |
| `head_changeset` | `string` | yes | The changeset of `git_ref`'s commit, which `target_ref` names now. |
| `imported` | `integer` (uint64) | yes | How many commits became changesets in this import. |
| `lossy` | array of [`LossyCommitOut`](#lossycommitout) | yes | The commits this import took lossily, as the request's `lossy` allowed: the first 100, in the order imported. `lossy_total` counts them all. |
| `lossy_total` | `integer` (uint64) | yes | How many commits this import took lossily, the ones past the first 100 included. |
| `old_head` | `string` or `null` | no | What `target_ref` named when the import started; omitted when it did not exist, and the import created it. |
| `ref_moved` | `boolean` | yes | Whether this import moved `target_ref`, or created it; `false` when the ref named `head_changeset` already, after an earlier import of the same commit or a concurrent one. |
| `skipped` | `integer` (uint64) | yes | How many commits the import found in the store already, where its walk stopped: the commit of the target's head, or commits an earlier import made. Importing the commit the target names already imports 0 and skips 1. |
| `target_ref` | `string` | yes | The ref the import moved, or found at `head_changeset` already. |
| `warnings` | array of `string` | no | Problems the import met that did not stop it, such as failed housekeeping after the target's move became durable; the import itself succeeded. Omitted when empty. |

## HunkOut

One place where the two sides' edits of a text file meet: each side's lines there. The lines are numbered from 1, and each side's range includes both ends, as `read_file` takes a range of lines.

Kind: object. `swarmops schema HunkOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `base` | [`LinesOut`](#linesout) | yes | The lines at the merge base. |
| `id` | `integer` (uint32) | yes | Its number in the file, from 0. |
| `ours` | [`LinesOut`](#linesout) | yes | The change's lines. |
| `theirs` | [`LinesOut`](#linesout) | yes | The target's lines. |

## Identity

The caller of a mutation: an agent name `<family>/<instance>` (`agent/worker-17`, `human/purple`) and an optional run id. M1 trusts the name as claimed.

The agent name always follows the grammar below, also in an identity read from JSON.

Kind: object. `swarmops schema Identity` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `agent` | `string` | yes | `<family>/<instance>`, exactly as the schema's `pattern` and `maxLength` give it. At most 255 characters. Matches `^[a-z0-9-]+/[A-Za-z0-9_-][A-Za-z0-9._-]*$`. |
| `run_id` | `string` or `null` | no | The run the agent acts in, when it has one. |

## IdentityInfo

`whoami`: the identity the caller's mutations carry.

Kind: object. `swarmops schema IdentityInfo` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `agent` | `string` or `null` | no | `<family>/<instance>`; omitted for an anonymous caller. |
| `auth` | `string` | yes | How this caller's identity was established: `trust` (claimed, not verified) or `anonymous`. |
| `run_id` | `string` or `null` | no | The run the agent acts in, when it has one. |

## InfoReq

`info`: describe the store. It has no options yet.

Kind: object. `swarmops schema InfoReq` prints its JSON Schema.

It has no properties.

## InitReq

`init`: create a store.

Kind: object. `swarmops schema InitReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `string` | yes | The repository's name: at most 255 bytes of UTF-8. |
| `path` | `string` | yes | The directory to create the store in. |

## LandReq

`land`: merge a change three-way onto a target ref and publish it there as one new changeset, in one transaction. The change is `head` with its first-parent chain after `base`, squashed: the landed changeset's parent is the target's head, so the target stays linear. A conflict is the error `E_CONFLICT`, with the report in `details.report`; nothing is recorded then.

Kind: object. `swarmops schema LandReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `base` | [`Rev`](#rev) or `null` | no | Where the change starts: a first-parent ancestor of `head`, whose own changes are not part of it (anything else is `E_INVALID_ARG`). It need not be on the target. When omitted, the merge base of `head` and the target's head, along first parents. |
| `head` | [`Rev`](#rev) | yes | The changeset to land: the change's head. |
| `idempotency_key` | `string` or `null` | no | Makes a retry of this land safe: 1 to 64 letters, digits and `-`, such as a uuid v7. A land with a key first looks down the target's first parents, to `base`, for a changeset that landed with the same key: one squashed from this `head` is the replay, which writes nothing (`status` is `replayed`); one from another head is `E_INVALID_ARG`, a key used for another change. |
| `max_attempts` | `integer` (uint32) | no | How many times to try to publish before failing with `E_CAS_RETRY_EXHAUSTED`: 1 to 32. Default: `8`. At least 1. At most 32. |
| `max_conflict_bytes` | `integer` (uint64) | no | The most bytes of hunk text an `E_CONFLICT` report carries: past it, the texts are left out (`truncated`), and the line positions and blob ids stay. Default: `32768`. |
| `message` | `string` or `null` | no | The landed changeset's message; `head`'s when omitted. |
| `resolutions` | [`ResolutionsInput`](#resolutionsinput) or `null` | no | What to make of the paths an `E_CONFLICT` report named, decided without a checkout . Each resolution applies to its path while the target holds there what `against` held, whether the path conflicts or not; a path the target changed since is stale, and the land fails `E_CONFLICT` again, with a fresh report that names it in `stale`. Conflicts left unresolved fail it too. `swarmops mcp` refuses an `against` that is not a full 64-hex id (`E_INVALID_ARG`). |
| `target` | `string` | no | The ref to land on: `main` or `release/<name>`, which must exist. Default: `"main"`. |

## LandResp

`land`: where the change landed. Ids are full.

Kind: object. `swarmops schema LandResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `attempts` | `integer` (uint32) | yes | How many times the land tried to publish. |
| `auto_merged` | array of `string` | no | The paths both sides changed that merged cleanly. Omitted when empty. |
| `base` | `string` | yes | The changeset the change was taken from: what `head`'s first-parent chain added after it is what landed. |
| `files_changed` | `integer` (uint64) | yes | How many paths the landed changeset changes. |
| `landed` | `string` | yes | The landed changeset: the change squashed into one changeset on the target. |
| `rebased_onto` | `string` | yes | The target's head the change landed on: `landed`'s parent. |
| `relocated` | `boolean` | yes | The target moved after the land read it, and the publish put the change on the new head itself, without another attempt. |
| `squashed_from` | array of `string` | yes | The changesets the land squashed, oldest first: `head`'s first-parent chain after `base`, ending at `head`. |
| `status` | [`LandStatus`](#landstatus) | yes | `landed`, or `replayed` when a land with the same `idempotency_key` had landed the change already. |
| `target` | `string` | yes | The ref it landed on. |
| `warnings` | array of `string` | no | Problems found after the land became durable, such as failed housekeeping; the land itself succeeded. Omitted when empty. |

## LandStatus

How a land ended.

Kind: enumeration. `swarmops schema LandStatus` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"landed"` | This request landed the change. |
| `"replayed"` | A land with the same `idempotency_key` had landed it already; nothing was written. |

## LineOp

Which side of a diff a hunk's line is on.

Kind: enumeration. `swarmops schema LineOp` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"context"` | Both: an unchanged line around a change. |
| `"add"` | The new side only. |
| `"remove"` | The old side only. |

## LineRange

A range of a file's lines, numbered from 1: `first` to `last`, both included.

Kind: object. `swarmops schema LineRange` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `first` | `integer` (uint64) | yes | The range's first line: at least 1. At least 1. |
| `last` | `integer` (uint64) | yes | The range's last line: at least `first`. At least 1. |

## LinesOut

One side's lines of a hunk: `first` to `last`, numbered from 1, both included. A side without lines there has `last` one less than `first`: its place is before line `first`.

Kind: object. `swarmops schema LinesOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `first` | `integer` (uint64) | yes | The first line. |
| `last` | `integer` (uint64) | yes | The last line; `first` minus one when the side has none. |
| `text` | `string` or `null` | no | The lines' text; omitted when the report would pass its `max_conflict_bytes` (`truncated`). |

## LogCutOut

Where the journal was cut (`meta.recovered.log_cut`).

Kind: object. `swarmops schema LogCutOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `at` | `integer` (uint64) | yes | The journal's byte offset where the torn tail started, and where the journal ends now. |
| `bytes` | `integer` (uint64) | yes | How many bytes were cut, to where the journal ended. |

## LogPage

`log`: a page of changesets, newest first, following first parents.

Kind: object. `swarmops schema LogPage` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | `string` or `null` | no | When `truncated`: where the next page continues. Opaque: pass it back as given, as the next request's `cursor`. |
| `entries` | array of [`ChangesetSummary`](#changesetsummary) | yes | The changesets. |
| `truncated` | `boolean` | yes | Whether older history follows this page. |

## LogReq

`log`: history along first parents, a page at a time.

Kind: object. `swarmops schema LogReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | `string` or `null` | no | Resume a log: the previous page's `cursor`. Pass it back exactly as returned; do not construct it (cursors are opaque). This page continues from the first parent of the changeset it names, and `rev` is not used. |
| `limit` | `integer` (uint) | no | The most entries to return: at least 1 (0 is `E_INVALID_ARG`). Default: `50`. At least 1. |
| `paths` | array of `string` | no | Only the changesets that change one of these paths: a file (its content or kind, or whether it is there), or a directory and anything below it; one trailing `/` is taken. Omitted or empty for every changeset. |
| `rev` | [`Rev`](#rev) or `null` | no | Where to start; `main` when omitted. |

## LossyClass

A class of git content that a changeset cannot hold as git has it. A commit holding one is refused unless the import's `lossy` allows its class; an allowed class is dropped or normalized, a directory a drop leaves empty is dropped with it, and the changeset's `git.lossy` metadata names the classes, since it no longer renders back to the commit's own git id.

Kind: enumeration. `swarmops schema LossyClass` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"gitlinks"` | A submodule's entry (git mode 160000): dropped. |
| `"paths"` | A name that is not UTF-8, or is `.` or `..`: dropped. |
| `"modes"` | A mode written other than git's own `100644`, `100755`, `120000` and `40000`, such as `100664` or a zero-padded `040000`: a regular file's becomes a file or an executable by its owner's execute bit, and `040000` a directory. |
| `"tree_order"` | A tree whose entries are not in git's order, or that names one entry twice: put in order, the first of a name kept. |
| `"empty_trees"` | An entry naming an empty tree: dropped. |
| `"nonstandard"` | A commit whose bytes the changeset cannot keep: a signature line, time or header line that renders back differently, no blank line before the message, or a parent listed twice (kept once). |

## LossyCommitOut

`git import`: a commit taken lossily, and what it lost.

Kind: object. `swarmops schema LossyCommitOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `changeset` | `string` | yes | The changeset made of it, whose `git.lossy` metadata names the same classes. |
| `classes` | array of [`LossyClass`](#lossyclass) | yes | The classes dropped or normalized in it, ordered by name, as `git.lossy` lists them. |
| `commit` | `string` | yes | The git commit: its id, 40 lowercase hex digits. |

## Meta

What the envelope reports besides the outcome.

Kind: object. `swarmops schema Meta` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `auth` | `string` | yes | The store's authentication mode (`trust` in M1), not how this caller was identified. |
| `elapsed_ms` | `integer` (uint64) | yes | How long the command took, in milliseconds. |
| `recovered` | [`RecoveredOut`](#recoveredout) or `null` | no | What the command's write repaired before its own work, of what earlier writers left when they crashed or failed after their commit point; omitted when there was nothing to repair, and for a command that writes nothing. `commit`, `ref_set` and `ref_delete` report it on success and on `E_CAS_MISMATCH` alike, and lose it when they fail otherwise. Whoever writes next gets it, not the agent whose process crashed, and it is no failure: `warnings` still names only the steps after this command's own commit point that failed. |
| `repo` | `string` or `null` | no | The store as the user named it, for display; omitted when the command used no store. |
| `resolved` | map of `string` to `string` | yes | Every revision the command resolved: the string given and the full changeset id it named. |

## ModeInput

The kind of entry a `put` writes.

Kind: enumeration. `swarmops schema ModeInput` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"file"` | A regular file (git mode 100644). |
| `"exec"` | An executable file (git mode 100755). |
| `"symlink"` | A symlink; the content is the link's target. |

## OpChangesetOut

A changeset an operation recorded.

Kind: object. `swarmops schema OpChangesetOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `agent` | `string` | yes | The agent that wrote it, as `show` gives `author.agent`. |
| `created_at` | `integer` (uint64) | yes | When it was recorded: the committer signature's time, in Unix milliseconds. |
| `id` | `string` | yes | Its id. |
| `land_key` | `string` or `null` | no | The idempotency key of the land that made it, when it had one. |
| `title` | `string` | yes | The message's first line. |

## OpError

A failed operation: the envelope's `error` object.

`code`, `exit` and `retryable` come from one `ErrorCode`. `code` stays a string so a client can read codes newer than its own table.

Kind: object. `swarmops schema OpError` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | `string` | yes | The `E_*` code. |
| `details` | `object` | yes | Machine-readable context, such as `actual` for `E_CAS_MISMATCH`; `{}` when there is none. Default: `{}`. |
| `exit` | `integer` (int32) | yes | The exit code of the CLI. |
| `hint` | `string` or `null` | yes | The next command to run when there is an obvious one, else null. |
| `message` | `string` | yes | What went wrong. |
| `retryable` | `boolean` | yes | Whether the operation can succeed when it is run again: as it is after a transient failure, or, after a lost compare-and-swap, with what the error names re-read (the message says how; the `hint` reads it). |

## OpLogPage

`op_log` (CLI `op log`): a page of operations, newest first.

Kind: object. `swarmops schema OpLogPage` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `ops` | array of [`OperationOut`](#operationout) | yes | The operations. |
| `truncated` | `boolean` | yes | Whether older operations follow this page: give the last one's `op` as `before` to read them. |

## OpLogReq

`op_log` (CLI `op log`): the store's operations, newest first, a page at a time. An operation is one write transaction: a frame of the journal, numbered from 0 in commit order.

Kind: object. `swarmops schema OpLogReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `before` | `integer` (uint64) or `null` | no | Start below this operation: the page holds the ones numbered less than it, so the last `op` of a page reads on from there. When omitted, from the newest. |
| `limit` | `integer` (uint) | no | The most operations to return: at least 1 (0 is `E_INVALID_ARG`). Default: `50`. At least 1. |
| `max_changesets` | `integer` (uint) | no | The most changesets to list for each operation; `changesets_total` counts them all. Default: `20`. |

## OperationKind

What an operation did, read from what it recorded.

Kind: enumeration. `swarmops schema OperationKind` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"commit"` | It recorded changesets and moved no ref (`commit`). |
| `"publish"` | It recorded one changeset and moved a ref to it (`commit` with `advance`). |
| `"land"` | It recorded one changeset that names a lander and moved a ref to it (`land`). |
| `"ref_move"` | It moved refs and recorded no changeset (`ref set`, `ref delete`, `undo`). |
| `"compaction"` | It recorded a compaction of the changeset index, and nothing else. |
| `"mixed"` | Any other mix of changesets, ref moves and compactions. |

## OperationOut

One operation: a write transaction, as the journal recorded it.

Kind: object. `swarmops schema OperationOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `changesets` | array of [`OpChangesetOut`](#opchangesetout) | yes | The changesets it recorded, in its order: at most the request's `max_changesets`. |
| `changesets_total` | `integer` (uint64) | yes | How many changesets it recorded in all, also past `max_changesets`. |
| `kind` | [`OperationKind`](#operationkind) | yes | What it did, read from what it recorded. |
| `op` | `integer` (uint64) | yes | Its number: its journal frame's, from 0 in commit order. `undo` takes it. |
| `ref_moves` | array of [`RefMoveOut`](#refmoveout) | yes | The ref moves it made, in its order. |

## PathHistoryEntry

One changeset of a path's history, and what the path holds after it.

Kind: object. `swarmops schema PathHistoryEntry` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `author_agent` | `string` | yes | The agent that wrote the changeset, as `log` gives it. |
| `changeset` | `string` | yes | The changeset's id. |
| `created_at` | `integer` (uint64) | yes | When it was recorded: the committer signature's time, in Unix milliseconds. |
| `id` | `string` or `null` | no | A blob id for a file, an executable or a symlink; a tree id for a directory; omitted after a `delete`. |
| `kind` | [`EntryKindOut`](#entrykindout) or `null` | no | What is at the path after it; omitted after a `delete`. |
| `op` | [`ChangeOp`](#changeop) | yes | `put` when something is at the path after the changeset, `delete` when nothing is. |
| `title` | `string` | yes | The message's first line. |

## PathHistoryPage

`path_history` (CLI `history`): a page of a path's history, newest first.

Kind: object. `swarmops schema PathHistoryPage` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | `string` or `null` | no | When `truncated`: where the next page continues. Opaque: pass it back as given, as the next request's `cursor`. |
| `entries` | array of [`PathHistoryEntry`](#pathhistoryentry) | yes | The changesets that changed what it holds. |
| `path` | `string` | yes | The path, without a trailing `/`. |
| `truncated` | `boolean` | yes | Whether an older changeset that changed it follows this page. |

## PathHistoryReq

`path_history` (CLI `history`): the changesets that changed what a path holds, newest first, following first parents, a page at a time.

Kind: object. `swarmops schema PathHistoryReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | `string` or `null` | no | Resume a history: the previous page's `cursor`. Pass it back exactly as returned; do not construct it (cursors are opaque). This page continues from the first parent of the changeset it names, and `rev` is not used. |
| `limit` | `integer` (uint) | no | The most entries to return: at least 1 (0 is `E_INVALID_ARG`). Default: `50`. At least 1. |
| `path` | `string` | yes | The repository path: a file, whose history is that of its content and kind, or a directory, whose history is that of everything below it. One trailing `/` is taken. |
| `rev` | [`Rev`](#rev) or `null` | no | Where to start; `main` when omitted. |

## ReadFileReq

`read_file` (CLI `cat`): read one file at a revision, without a checkout: from an offset, or a range of its lines.

Kind: object. `swarmops schema ReadFileReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `lines` | [`LineRange`](#linerange) or `null` | no | Read these lines instead, numbered from 1, both ends included: a line ends after its newline, and a last line without one is a line too. The lines of the range that exist come back, none past the file's last. Give this or `offset`, not both (`E_INVALID_ARG`). |
| `max_bytes` | `integer` (uint64) | no | The most content bytes to return; more comes back truncated, with the `next_offset` to read on from. Default: `1048576`. |
| `offset` | `integer` (uint64) | no | Where to start reading, in bytes from the file's start: a truncated read's `next_offset` reads on from where it stopped. An offset past the end gives empty content. Give this or `lines`, not both (`E_INVALID_ARG`). Default: `0`. |
| `path` | `string` | yes | The file's repository path. |
| `rev` | [`Rev`](#rev) | yes | The revision to read at. |

## ReadTreeReq

`read_tree` (CLI `ls`): list one directory at a revision, without a checkout, a page at a time; with `depth`, the directories below it too.

Kind: object. `swarmops schema ReadTreeReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | `string` or `null` | no | Resume a listing: the previous page's `cursor`. Pass it back exactly as returned; do not construct it (cursors are opaque). This page starts after the entry it names. |
| `depth` | `integer` (uint32) | no | How many levels to list: 1 for the directory's own entries, 2 for theirs too, and so on, up to 64 (0 or more than 64 is `E_INVALID_ARG`). Default: `1`. At least 1. At most 64. |
| `limit` | `integer` (uint) | no | The most entries to return: at least 1 (0 is `E_INVALID_ARG`). Default: `250`. At least 1. |
| `path` | `string` or `null` | no | The directory's repository path; omitted for the root. |
| `rev` | [`Rev`](#rev) | yes | The revision to read at. |

## RecoveredOut

What a write's recovery repaired (`meta.recovered`), as offsets and counts in the store's metadata files, with no paths.

Kind: object. `swarmops schema RecoveredOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `frames_listed` | `integer` (uint64) | yes | The journal frames listed that their writer never listed: transactions that committed, their writer having crashed between the frame's sync and its listing, or failed to list it (a warning then); and frames listed again whose entries a power loss zeroed. |
| `frames_rewritten` | `integer` (uint64) | yes | Of those, the frames written to the journal afresh first, because the sync that would have made them durable failed. |
| `index_records_dropped` | `integer` (uint64) | yes | The changeset index records cut, counted in its longest column: records a crash left torn, or a power loss emptied. |
| `log_cut` | [`LogCutOut`](#logcutout) or `null` | no | The torn tail cut off the end of the journal, if there was one: the bytes of a transaction that never reached its commit point; omitted when nothing was cut. |
| `off_bytes_dropped` | `integer` (uint64) | yes | The bytes dropped from the end of the journal's list of frames: part of an entry, or entries a power loss zeroed. |
| `records_replayed` | `integer` (uint64) | yes | The changesets replayed from the journal into the index. |
| `refs_replayed` | `integer` (uint64) | yes | The ref files replayed from the journal: replaced, or removed. |
| `views_rebuilt` | `boolean` | yes | Whether a compaction of the changeset index that a crash interrupted was finished. |

## RefDeleteReq

`ref delete`: remove a ref by compare-and-swap.

Kind: object. `swarmops schema RefDeleteReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `expected_old` | [`Rev`](#rev) | yes | The target the caller last saw, by its full changeset id; if the ref holds another, the delete fails with `E_CAS_MISMATCH`. A ref name or a relative revision is read from the store when the delete runs instead of pinning the id the caller read: the ref's own name always matches, so the compare-and-swap protects nothing, and `main~1` on `main` never matches. An id prefix pins the id the caller read only until another changeset shares it; then it is `E_AMBIGUOUS_ID`. `swarmops mcp` refuses all three (`E_INVALID_ARG`), and the CLI's `--expect` help warns against them. |
| `name` | `string` | yes | The ref. |

## RefListReq

`ref list`: list every ref. It has no options yet.

Kind: object. `swarmops schema RefListReq` prints its JSON Schema.

It has no properties.

## RefListResp

`ref list`: every ref.

Kind: object. `swarmops schema RefListResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `refs` | array of [`RefOut`](#refout) | yes | The refs. |

## RefMoveOut

A move of a ref, as the journal recorded it.

Kind: object. `swarmops schema RefMoveOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `actor` | `string` | yes | Who moved it. |
| `at` | `integer` (int64) | yes | When it moved, in Unix seconds, as its writer recorded it. |
| `name` | `string` | yes | The ref. |
| `new` | `string` or `null` | no | What it names after; omitted for the move that deleted it. |
| `old` | `string` or `null` | no | What it named before; omitted for the move that created it. |

## RefOut

One ref.

Kind: object. `swarmops schema RefOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `string` | yes | `main` or `release/<name>`. |
| `target` | `string` | yes | The changeset it points at. |
| `version` | `integer` (uint64) | yes | How many committed moves changed its target. |

## RefSetReq

`ref set`: move a ref, or create one, by compare-and-swap. Give exactly one of `expected_old` and `create`; both or neither is `E_INVALID_ARG`.

Kind: object. `swarmops schema RefSetReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `create` | `boolean` | no | To create the ref. If it exists at another target, the move fails with `E_CAS_MISMATCH`; if it already holds `new`, nothing is written and the response is a replay (`already_applied`). Give this or `expected_old`, not both. Default: `false`. |
| `expected_old` | [`Rev`](#rev) or `null` | no | To move an existing ref: the target the caller last saw, by its full changeset id; if the ref holds another, the move fails with `E_CAS_MISMATCH`. A ref name or a relative revision is read from the store when the move runs instead of pinning the id the caller read: the ref's own name always matches, so the compare-and-swap protects nothing, and `main~1` on `main` never matches. An id prefix pins the id the caller read only until another changeset shares it; then it is `E_AMBIGUOUS_ID`. `swarmops mcp` refuses all three (`E_INVALID_ARG`), and the CLI's `--expect` help warns against them. Give this or `create`, not both. |
| `name` | `string` | yes | The ref: `main` or `release/<name>`. |
| `new` | [`Rev`](#rev) | yes | The revision to point it at. |

Exactly one of these shapes holds:

- `expected_old` is present; `create`, if given, is `false`; `expected_old` is a `string`.
- `create` is present; `create` is `true`; `expected_old`, if given, is null.

## RefSetResp

`ref set` and `ref delete`: the move that was made.

Kind: object. `swarmops schema RefSetResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `already_applied` | `boolean` | yes | The ref was already in the requested state, so nothing changed and a replay is safe; `old` and `new` are then the request's `expected_old` and `new`, resolved to full ids. |
| `name` | `string` | yes | The ref. |
| `new` | `string` or `null` | no | Its target after; omitted when the ref was deleted. |
| `old` | `string` or `null` | no | What the ref held before a move that was applied. On a replay (`already_applied`) it is `expected_old` as resolved, which the ref need not have held; omitted when `create` was given. |
| `warnings` | array of `string` | no | Problems found after the move became durable, such as failed housekeeping; the move itself succeeded. Omitted when empty. |

## RepoInfo

`init` and `info`: what the store is and holds.

Kind: object. `swarmops schema RepoInfo` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `changesets` | `integer` (uint64) | yes | How many changesets the store holds. |
| `main` | `string` or `null` | no | The changeset `main` points at; omitted until `main` exists. |
| `name` | `string` | yes | The name given at `init`. |
| `refs` | `integer` (uint64) | yes | How many refs the store holds. |
| `repo_id` | `string` | yes | The store's id, fixed at `init`. |
| `store_version` | `integer` (uint32) | yes | The store format version. |

## ResolutionInput

What a land makes of one path, and of every path below it: exactly one of `take`, `content` and `delete` (anything else is `E_INVALID_ARG`, a rule the server checks), the rest of the merge as it merged.

Kind: object. `swarmops schema ResolutionInput` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `content` | [`ContentInput`](#contentinput) or `null` | no | One file of new content, given as a commit's change gives it (inline, base64, a client file, or a stored blob by id), within a commit's limits; nothing below it. |
| `delete` | `boolean` | no | Nothing there: no file at the path, nor below it. |
| `mode` | [`ModeInput`](#modeinput) or `null` | no | The kind of the file `content` makes, only beside it; when omitted, the kind of the file ours holds there, else theirs', else a regular file. |
| `take` | [`Side`](#side) or `null` | no | What one side holds there: `ours`, the change's head, or `theirs`, the target's head. |

## ResolutionsInput

A land's resolutions (`land --resolve`): what to make of some paths of the merge of the change onto the target, decided against one of the target's heads.

Kind: object. `swarmops schema ResolutionsInput` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `against` | [`Rev`](#rev) | yes | The target's head the resolutions were decided against: the conflict report's `theirs`, by its full 64-hex id. A resolution applies while the target holds its path as this changeset does (the same file, the same directory, or nothing). |
| `files` | map of `string` to [`ResolutionInput`](#resolutioninput) | yes | What to make of each path, by its repository path. |

## ResolveRevReq

`resolve_rev` (CLI `resolve`): the changeset a revision names, as every operation resolves it.

Kind: object. `swarmops schema ResolveRevReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `rev` | [`Rev`](#rev) | yes | The revision to resolve. |

## ResolvedRev

`resolve_rev` (CLI `resolve`): the changeset a revision names, and what kind of revision it is.

Kind: object. `swarmops schema ResolvedRev` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | The full id of the changeset the revision names. |
| `kind` | [`RevKind`](#revkind) | yes | What the revision is: `ref` when it is exactly a ref's name, `changeset` otherwise. |

## Rev

A revision as the caller wrote it, for the store to resolve: a ref name (`main`, `release/1.2`), a full 64-hex changeset id or a unique prefix of at least 12 hex digits, optionally followed by `~N` for the N-th first-parent ancestor.

Kind: string. `swarmops schema Rev` prints its JSON Schema.

## RevKind

What kind of revision `resolve_rev` resolved. M5 adds `workspace`, for a workspace's head and the edits not committed yet (`ws:<name>`).

Kind: enumeration. `swarmops schema RevKind` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"ref"` | Exactly a ref's name (`main`, `release/<name>`): `id` is what the ref names now, and moves when the ref does. |
| `"changeset"` | Any other revision: a full changeset id, a unique prefix of one, or a revision followed by `~N` suffixes, a ref's name among them. |

## ShowReq

`show`: one changeset in full.

Kind: object. `swarmops schema ShowReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `max_changes` | `integer` (uint) | no | The most entries of `changes` to return: at least 1 (0 is `E_INVALID_ARG`). Default: `400`. At least 1. |
| `rev` | [`Rev`](#rev) | yes | The changeset to show. |

## Side

One side of a land's merge.

Kind: enumeration. `swarmops schema Side` prints its JSON Schema.

| Value | Description |
| --- | --- |
| `"ours"` | The change: its head. |
| `"theirs"` | The target: its head when the land merges. |

## SignatureOut

A git signature: who, and when.

Kind: object. `swarmops schema SignatureOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | `string` | yes | The email. |
| `name` | `string` | yes | The name; the agent name for a native changeset. |
| `offset_secs` | `integer` (int32) | yes | The UTC offset in seconds. |
| `secs` | `integer` (int64) | yes | Unix time in seconds. |

## Signatures

A changeset's git signatures: git-fidelity data for import and export.

Kind: object. `swarmops schema Signatures` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `author` | [`SignatureOut`](#signatureout) | yes | The git author. |
| `committer` | [`SignatureOut`](#signatureout) | yes | The git committer; its time is `created_at`. |

## TreeEntryOut

One entry of a listing.

Kind: object. `swarmops schema TreeEntryOut` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A blob id for a file, an executable or a symlink; a tree id for a directory. |
| `kind` | [`EntryKindOut`](#entrykindout) | yes | What the entry is. |
| `name` | `string` | yes | The entry's name: one path component. |
| `path` | `string` or `null` | no | Its path below the listed directory, given when the request's `depth` is more than 1: its name, for one of the directory's own entries. |
| `size` | `integer` (uint64) or `null` | no | For a file, an executable or a symlink: its content's size in bytes; omitted for a directory. |

## TreeListing

`read_tree` (CLI `ls`): a page of a directory's entries, in pre-order: a directory, then the entries below it to the request's `depth`, each directory's entries by name bytes (at `depth` 1, the tree's order).

Kind: object. `swarmops schema TreeListing` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | `string` or `null` | no | When `truncated`: where the next page starts. Opaque: pass it back as given, as the next request's `cursor`. |
| `entries` | array of [`TreeEntryOut`](#treeentryout) | yes | The entries. |
| `truncated` | `boolean` | yes | Whether more entries follow this page. |

## UndoReq

`undo` (CLI `op undo`): restore every ref an operation moved to what it named before, by compare-and-swap, in one transaction: all of them or none. Changesets are never removed.

Kind: object. `swarmops schema UndoReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | `integer` (uint64) | yes | The operation to undo: its `op` in the operation log. |

## UndoResp

`undo` (CLI `op undo`): the moves that restored the refs.

Kind: object. `swarmops schema UndoResp` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `already_applied` | `boolean` | yes | Every ref the operation moved already names what it named before, so nothing was written: an undo run again is a replay, and safe. |
| `op` | `integer` (uint64) or `null` | no | The operation this undo recorded, which another undo can take; omitted when it wrote nothing (`already_applied`). |
| `ref_moves` | array of [`RefMoveOut`](#refmoveout) | yes | The moves it made: each ref from what the operation set back to what it named before. |
| `undone` | `integer` (uint64) | yes | The operation undone. |
| `warnings` | array of `string` | no | Problems found after the undo became durable, such as failed housekeeping; the undo itself succeeded. Omitted when empty. |

## VerifyFinding

One problem `verify` found, as a program reads it: what kind of damage it is, and what it names. The keys its kind does not use are omitted; the line at the same index of `problems` says the same for a reader. Ids are lowercase hex.

Kind: object. `swarmops schema VerifyFinding` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cause` | `string` or `null` | no | What disagrees with the record (`index_mismatch`), which says what mends it: `journal` (rebuild the index from the journal), `sorted_view` (rebuild the sorted views from the index columns) or `object` (derive the record from its object again). |
| `changeset` | `string` or `null` | no | The changeset: the first, in seq order, that references the missing object (`missing_object`), the one that names a missing parent (`missing_parent`), the one whose root is not its first parent's root with its delta applied (`root_mismatch`), the one an external id's entry names: not in the store (`external_id_dangling`), or with a `git.oid` that is another oid than the entry's key, or, found by a deep verify, with none and exporting to another commit (`external_id_mismatch`), or the one a derived value is about (`derived_mismatch`). |
| `derivation` | `string` or `null` | no | The derivation whose stored value is not the one the objects give: `first_parent_skip_list`, `last_modified`, or a git export oid memo `git_tree_oid`, `git_blob_oid` or `git_oid` (`derived_mismatch`, which a deep verify finds; `git_oid` names its `changeset`, the tree and blob memos their `object`). Removing the value's file under `meta/derived/<derivation>/`, or all of `meta/derived/`, has it derived again. |
| `key` | `string` or `null` | no | The key, in lowercase hex: the external id whose entry it is, a git commit's oid for system `git` (`external_id_corrupt`, `external_id_dangling`, `external_id_mismatch`); or a derived value's key, its postcard bytes, omitted for a derivation whose key is `()` (`derived_mismatch`: a path's for `last_modified`). |
| `kind` | `string` | yes | What is damaged: `corrupt_object`, `missing_object`, `missing_parent`, `root_mismatch`, `dangling_ref`, `corrupt_ref`, `index_mismatch`, `journal_corrupt`, `meta_corrupt`, `external_id_corrupt`, `external_id_dangling`, `external_id_mismatch` or `derived_mismatch`. A string, as `OpError.code` is, so that a client can read kinds newer than its own list. |
| `object` | `string` or `null` | no | The object: one whose content does not hash to its id or does not decode (`corrupt_object`), one a changeset references that the store lacks, or holds as another kind (`missing_object`), or the tree or blob a git export oid memo (`git_tree_oid`, `git_blob_oid`) is about (`derived_mismatch`). |
| `offset` | `integer` (uint64) or `null` | no | Where the corrupt frame starts in `journal.log` (`journal_corrupt`); nothing after it is read. |
| `parent` | `string` or `null` | no | The parent the changeset names, which the store does not hold (`missing_parent`). |
| `ref` | `string` or `null` | no | The ref: one that names no changeset in the store (`dangling_ref`), or whose file does not read as a ref (`corrupt_ref`). |
| `seq` | `integer` (uint64) or `null` | no | The changeset record's place in the index, from 0 (`index_mismatch`). |
| `system` | `string` or `null` | no | The system of the external id index whose entry it is: `git`, whose keys are git commit oids, or another (`external_id_corrupt`, `external_id_dangling`, `external_id_mismatch`). |

## VerifyReport

`verify`: what the consistency check found.

Kind: object. `swarmops schema VerifyReport` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `changesets_checked` | `integer` (uint64) | yes | How many changesets were checked. |
| `findings` | array of [`VerifyFinding`](#verifyfinding) | no | One finding per problem found, for a program to act on: `findings[i]` is the problem that the line `problems[i]` describes. Empty for a clean store; a report without it reads as having none. Default: `[]`. |
| `objects_checked` | `integer` (uint64) | yes | How many objects were checked. |
| `problems` | array of `string` | yes | One line per problem found, for a reader of lines; empty for a clean store. `findings` holds the same problems, at the same indexes, for a program. |

## VerifyReq

`verify`: check the whole store's consistency.

Kind: object. `swarmops schema VerifyReq` prints its JSON Schema.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `deep` | `boolean` | no | Re-hash every object, and check every derived value of the built-in derivations (the first-parent skip lists, the last touches of paths) against the objects. When `false`, verify checks structure only: parents, that referenced objects exist, the index against the journal, and refs. Default: `false`. |
