<!-- 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. -->

# Limits

The limits of the SwarmOps contract: what a request may hold, with the error a request past a limit gets, and how far a response goes before it leaves the rest out. Each limit names the constant that sets it, so a value here is the code's. Then the defaults a paged request takes, the bounds the JSON Schema states, and, apart, internal values that are not part of the contract.

## Contract limits

| Limit | Value | Constant | Error |
| --- | --- | --- | --- |
| [Request text](#request-text) | 67,108,864 bytes (64 MiB) | `swarmops_ops::content::MAX_REQUEST_BYTES` | [`E_TOO_LARGE`](errors.md#e_too_large) |
| [One content](#one-content) | 536,870,912 bytes (512 MiB) | `swarmops_ops::content::MAX_CONTENT_BYTES` | [`E_TOO_LARGE`](errors.md#e_too_large) |
| [A commit's contents](#a-commits-contents) | 1,073,741,824 bytes (1 GiB) | `swarmops_ops::content::MAX_COMMIT_CONTENT_BYTES` | [`E_TOO_LARGE`](errors.md#e_too_large) |
| [An object](#an-object) | 536,870,912 bytes (512 MiB) | `swarmops_store::MAX_OBJECT_LEN` | [`E_TOO_LARGE`](errors.md#e_too_large) |
| [Tree depth](#tree-depth) | 64 levels | `swarmops_api::MAX_TREE_DEPTH` | [`E_INVALID_ARG`](errors.md#e_invalid_arg) |
| [Land attempts](#land-attempts) | 32 attempts | `swarmops_api::MAX_LAND_ATTEMPTS` | [`E_INVALID_ARG`](errors.md#e_invalid_arg) |
| [Land key](#land-key) | 64 characters | `swarmops_ops::local::MAX_LAND_KEY` | [`E_INVALID_ARG`](errors.md#e_invalid_arg) |
| [Agent name](#agent-name) | 255 bytes | `swarmops_api::identity::MAX_AGENT_LEN` | [`E_INVALID_ARG`](errors.md#e_invalid_arg) |
| [Ref name](#ref-name) | 255 bytes | `swarmops_store::meta::refs::MAX_NAME_LEN` | [`E_REF_NAME_INVALID`](errors.md#e_ref_name_invalid) |
| [Repository name](#repository-name) | 255 bytes | `swarmops_repo::repo::MAX_NAME_LEN` | [`E_INVALID_ARG`](errors.md#e_invalid_arg) |

### Request text

The text of a request that a client reads: `commit`'s `--changes` file or stdin, `land`'s `--resolve` file, and each message line `mcp` reads. The command line refuses it before parsing it, with `details.scope` `request`; `mcp` answers a longer line with a JSON-RPC Invalid Request without an `id`, and reads on at the next line.

- Value: 67,108,864 bytes (64 MiB).
- Constant: `swarmops_ops::content::MAX_REQUEST_BYTES`, in `crates/swarmops-ops/src/content.rs`.
- Commands: [`commit`](commands/commit.md), [`land`](commands/land.md), [`mcp`](commands/mcp.md).
- Error: [`E_TOO_LARGE`](errors.md#e_too_large).

### One content

One put's content, inline, base64 (by the bytes it decodes to) or a file, in a commit's change list, a land's resolutions or a `blob put`: the most an object of the store holds. It is measured before it is converted, with `details.scope` `put`; a blob named by id counts nothing.

- Value: 536,870,912 bytes (512 MiB).
- Constant: `swarmops_ops::content::MAX_CONTENT_BYTES`, in `crates/swarmops-ops/src/content.rs`.
- Commands: [`commit`](commands/commit.md), [`land`](commands/land.md), [`blob put`](commands/blob-put.md).
- Error: [`E_TOO_LARGE`](errors.md#e_too_large).

### A commit's contents

The contents of a commit's change list together, or of a land's resolutions, with `details.scope` `commit`. The sizes the contents declare are checked before any file is read; a blob named by id counts nothing.

- Value: 1,073,741,824 bytes (1 GiB).
- Constant: `swarmops_ops::content::MAX_COMMIT_CONTENT_BYTES`, in `crates/swarmops-ops/src/content.rs`.
- Commands: [`commit`](commands/commit.md), [`land`](commands/land.md).
- Error: [`E_TOO_LARGE`](errors.md#e_too_large).

### An object

An object's payload in the store, with `details.store_limit` `object_bytes`: a commit's tree or changeset object past it, since a put's content is refused at the same size first.

- Value: 536,870,912 bytes (512 MiB).
- Constant: `swarmops_store::MAX_OBJECT_LEN`, in `crates/swarmops-store/src/fs_objects.rs`.
- Commands: [`commit`](commands/commit.md).
- Error: [`E_TOO_LARGE`](errors.md#e_too_large).

### Tree depth

How many levels `ls --depth` (`read_tree`'s `depth`) lists below a directory: 1 to this many, with `details.depth`.

- Value: 64 levels.
- Constant: `swarmops_api::MAX_TREE_DEPTH`, in `crates/swarmops-api/src/ops.rs`.
- Commands: [`ls`](commands/ls.md).
- Error: [`E_INVALID_ARG`](errors.md#e_invalid_arg).

### Land attempts

`land --max-attempts` (`max_attempts`): 1 to this many, checked before anything is resolved or read, with `details.max_attempts`.

- Value: 32 attempts.
- Constant: `swarmops_api::MAX_LAND_ATTEMPTS`, in `crates/swarmops-api/src/ops.rs`.
- Commands: [`land`](commands/land.md).
- Error: [`E_INVALID_ARG`](errors.md#e_invalid_arg).

### Land key

`land --key` (`idempotency_key`): 1 to this many ASCII letters, digits and `-`, a uuid v7 or a changeset id's 64 hex digits, with `details.idempotency_key`.

- Value: 64 characters.
- Constant: `swarmops_ops::local::MAX_LAND_KEY`, in `crates/swarmops-ops/src/local.rs`.
- Commands: [`land`](commands/land.md).
- Error: [`E_INVALID_ARG`](errors.md#e_invalid_arg).

### Agent name

The agent name of `--as` or `SWARMOPS_AGENT`, `<family>/<instance>`, which a ref move records with a one-byte length. `details.source` names where the name came from.

- Value: 255 bytes.
- Constant: `swarmops_api::identity::MAX_AGENT_LEN`, in `crates/swarmops-api/src/identity.rs`.
- Commands: [`whoami`](commands/whoami.md), [`commit`](commands/commit.md), [`land`](commands/land.md), [`blob put`](commands/blob-put.md), [`ref set`](commands/ref-set.md), [`ref delete`](commands/ref-delete.md), [`op undo`](commands/op-undo.md), [`git import`](commands/git-import.md), [`mcp`](commands/mcp.md).
- Error: [`E_INVALID_ARG`](errors.md#e_invalid_arg).

### Ref name

A ref's name, `main` or `release/<x>`, which a ref move records with a one-byte length: `commit --advance`, `land --target`, `ref set`, `ref delete`, `git import --into` and `git export --ref`.

- Value: 255 bytes.
- Constant: `swarmops_store::meta::refs::MAX_NAME_LEN`, in `crates/swarmops-store/src/meta/refs.rs`.
- Commands: [`commit`](commands/commit.md), [`land`](commands/land.md), [`ref set`](commands/ref-set.md), [`ref delete`](commands/ref-delete.md), [`git import`](commands/git-import.md), [`git export`](commands/git-export.md).
- Error: [`E_REF_NAME_INVALID`](errors.md#e_ref_name_invalid).

### Repository name

`init --name`, refused before anything is created, with `details.store_limit` `repo_name_bytes`.

- Value: 255 bytes.
- Constant: `swarmops_repo::repo::MAX_NAME_LEN`, in `crates/swarmops-repo/src/repo.rs`.
- Commands: [`init`](commands/init.md).
- Error: [`E_INVALID_ARG`](errors.md#e_invalid_arg).

## Bounds without an error

A response past these leaves the rest out, and says so in its fields; nothing fails.

| Limit | Value | Constant | Commands |
| --- | --- | --- | --- |
| [Lossy commits listed](#lossy-commits-listed) | 100 commits | `swarmops_git::import::MAX_LOSSY_LISTED` | [`git import`](commands/git-import.md) |
| [Line diff lines](#line-diff-lines) | 49,152 lines | `swarmops_merge::line_diff::MAX_DIFF_LINES` | [`diff`](commands/diff.md), [`land`](commands/land.md) |
| [Line diff bytes](#line-diff-bytes) | 8,388,608 bytes (8 MiB) | `swarmops_merge::line_diff::MAX_DIFF_BYTES` | [`diff`](commands/diff.md), [`land`](commands/land.md) |
| [Text probe](#text-probe) | 8,000 bytes | `swarmops_merge::line_diff::TEXT_PROBE` | [`diff`](commands/diff.md), [`land`](commands/land.md) |
| [Conflict report entries](#conflict-report-entries) | 24,576 bytes (24 KiB) | `swarmops_ops::conflict::MAX_ENTRY_BYTES` | [`land`](commands/land.md) |

### Lossy commits listed

`git import`'s `lossy` lists the first this many commits it took lossily, in the order imported; `lossy_total` counts them all.

- Value: 100 commits.
- Constant: `swarmops_git::import::MAX_LOSSY_LISTED`, in `crates/swarmops-git/src/import.rs`.
- Commands: [`git import`](commands/git-import.md).

### Line diff lines

The most lines a side of a file may have to be diffed by lines. Past it, `diff` gives the file no line counts and no hunks, with `hunks_truncated`, and a land that must merge the file by lines reports a `binary` conflict.

- Value: 49,152 lines.
- Constant: `swarmops_merge::line_diff::MAX_DIFF_LINES`, in `crates/swarmops-merge/src/line_diff.rs`.
- Commands: [`diff`](commands/diff.md), [`land`](commands/land.md).

### Line diff bytes

The most bytes a side of a file may have to be diffed by lines, as for the lines above.

- Value: 8,388,608 bytes (8 MiB).
- Constant: `swarmops_merge::line_diff::MAX_DIFF_BYTES`, in `crates/swarmops-merge/src/line_diff.rs`.
- Commands: [`diff`](commands/diff.md), [`land`](commands/land.md).

### Text probe

How many leading bytes are searched for a NUL, as git does: a side that is not UTF-8, or holds a NUL there, is binary, which gets no line counts and no hunks.

- Value: 8,000 bytes.
- Constant: `swarmops_merge::line_diff::TEXT_PROBE`, in `crates/swarmops-merge/src/line_diff.rs`.
- Commands: [`diff`](commands/diff.md), [`land`](commands/land.md).

### Conflict report entries

The most bytes an `E_CONFLICT` report's files and hunks take as JSON, their texts aside (`--max-conflict-bytes` bounds those). The first file always goes in; from the first file left out none follows, and `truncated` says so.

- Value: 24,576 bytes (24 KiB).
- Constant: `swarmops_ops::conflict::MAX_ENTRY_BYTES`, in `crates/swarmops-ops/src/conflict.rs`.
- Commands: [`land`](commands/land.md).

## Defaults

What a paged request takes when it does not say. The command line's flag has the same default, and a request over MCP that leaves the field out takes it too.

| Command | Flag | Request field | Default | Constant |
| --- | --- | --- | --- | --- |
| [`cat`](commands/cat.md) | `--max-bytes` | [`ReadFileReq`](schema-types.md#readfilereq) `max_bytes` | 1,048,576 bytes (1 MiB) | `swarmops_api::DEFAULT_MAX_BYTES` |
| [`ls`](commands/ls.md) | `--limit` | [`ReadTreeReq`](schema-types.md#readtreereq) `limit` | 250 entries | `swarmops_api::DEFAULT_READ_TREE_LIMIT` |
| [`show`](commands/show.md) | `--max-changes` | [`ShowReq`](schema-types.md#showreq) `max_changes` | 400 changes | `swarmops_api::DEFAULT_MAX_CHANGES` |
| [`log`](commands/log.md) | `--limit` | [`LogReq`](schema-types.md#logreq) `limit` | 50 changesets | `swarmops_api::DEFAULT_LOG_LIMIT` |
| [`history`](commands/history.md) | `--limit` | [`PathHistoryReq`](schema-types.md#pathhistoryreq) `limit` | 50 changesets | `swarmops_api::DEFAULT_PATH_HISTORY_LIMIT` |
| [`diff`](commands/diff.md) | `--limit` | [`DiffReq`](schema-types.md#diffreq) `limit` | 500 files | `swarmops_api::DEFAULT_DIFF_LIMIT` |
| [`diff`](commands/diff.md) | `--max-bytes` | [`DiffReq`](schema-types.md#diffreq) `max_bytes` | 32,768 bytes (32 KiB) | `swarmops_api::DEFAULT_DIFF_MAX_BYTES` |
| [`diff`](commands/diff.md) | `--context` | [`DiffReq`](schema-types.md#diffreq) `context` | 3 lines | `swarmops_api::DEFAULT_DIFF_CONTEXT` |
| [`land`](commands/land.md) | `--max-attempts` | [`LandReq`](schema-types.md#landreq) `max_attempts` | 8 attempts | `swarmops_api::DEFAULT_MAX_ATTEMPTS` |
| [`land`](commands/land.md) | `--max-conflict-bytes` | [`LandReq`](schema-types.md#landreq) `max_conflict_bytes` | 32,768 bytes (32 KiB) | `swarmops_api::DEFAULT_MAX_CONFLICT_BYTES` |
| [`op log`](commands/op-log.md) | `--limit` | [`OpLogReq`](schema-types.md#oplogreq) `limit` | 50 operations | `swarmops_api::DEFAULT_OP_LOG_LIMIT` |
| [`op log`](commands/op-log.md) | `--max-changesets` | [`OpLogReq`](schema-types.md#oplogreq) `max_changesets` | 20 changesets | `swarmops_api::DEFAULT_MAX_CHANGESETS` |
| [`derive`](commands/derive.md) | none | [`DeriveReq`](schema-types.md#derivereq) `limit` | 1,000 frames | `swarmops_api::DEFAULT_DERIVE_LIMIT` |

## Bounds in the JSON Schema

The bounds `swarmops schema` states on a field, beside the integer formats' own. A request that breaks one is `E_INVALID_ARG`.

| Type | Field | Bound |
| --- | --- | --- |
| [`DiffReq`](schema-types.md#diffreq) | `limit` | at least 1 |
| [`DiffReq`](schema-types.md#diffreq) | `max_bytes` | at least 1 |
| [`Identity`](schema-types.md#identity) | `agent` | at most 255 characters; matches `^[a-z0-9-]+/[A-Za-z0-9_-][A-Za-z0-9._-]*$` |
| [`LandReq`](schema-types.md#landreq) | `max_attempts` | 1 to 32 |
| [`LineRange`](schema-types.md#linerange) | `first` | at least 1 |
| [`LineRange`](schema-types.md#linerange) | `last` | at least 1 |
| [`LogReq`](schema-types.md#logreq) | `limit` | at least 1 |
| [`OpLogReq`](schema-types.md#oplogreq) | `limit` | at least 1 |
| [`PathHistoryReq`](schema-types.md#pathhistoryreq) | `limit` | at least 1 |
| [`ReadTreeReq`](schema-types.md#readtreereq) | `depth` | 1 to 64 |
| [`ReadTreeReq`](schema-types.md#readtreereq) | `limit` | at least 1 |
| [`ShowReq`](schema-types.md#showreq) | `max_changes` | at least 1 |

## Internal values

Not part of the contract: these tune the implementation, or bound the store's layout where no request reaches. No option sets them; they are listed for operators, and a release can change them.

| Value | Amount | Constant | What it does |
| --- | --- | --- | --- |
| Writer lock wait | 10 s | `swarmops_store::meta::store::DEFAULT_LOCK_TIMEOUT` | How long a write waits for the store's lock; a write that waits it out fails with `E_BUSY`. |
| Index sync threads | 5 threads | `swarmops_store::meta::store::DEFAULT_PARALLELISM` | How many threads a write transaction syncs the five index files from. |
| Import frame | 8,192 changesets | `swarmops_git::import::DEFAULT_FRAME_CHANGESETS` | How many changesets a journal frame of `git import` holds. |
| Import object batch | 67,108,864 bytes (64 MiB) | `swarmops_git::import::DEFAULT_OBJECT_BATCH_BYTES` | How many bytes of new trees and blobs `git import` gathers before it stores them. |
| Import busy retries | 3 retries | `swarmops_git::import::BUSY_RETRIES` | How many times `git import` makes a store call again that found the writer lock held for its whole wait. |
| Raw batch | 65,535 changesets | `swarmops_repo::MAX_RAW_BATCH` | The most changesets one journal frame of `git import` holds, whatever its frame size asks. |
| Export branch walk | 1,000 commits | `swarmops_git::export::BRANCH_WALK` | How many first parents of the branch's commit `git export` reads, looking for the export of the head or of an ancestor of it, before it says the branch moved. |
| Export branch lock | 100 ms | `swarmops_git::gix_sink::LOCK_TIMEOUT` | How long `git export` tries a branch's lock, git's `core.filesRefLockTimeout` default, so that two exports racing to one branch take turns. |
| Git file read whole | 16,777,216 bytes (16 MiB) | `swarmops_git::gix_source::MAX_WHOLE_LEN` | The longest file of the git directory (`HEAD` and other ref files, `config`, `objects/info/alternates`) that `git import` reads into memory whole; a longer one is refused unread. |
| Held conflict hunks | 128 hunks | `swarmops_repo::merge::MAX_HELD_HUNKS` | The most conflict hunks a merge holds over all its files; past them, each file's hunks are held as one that spans them. |
| MCP line buffer | 65,536 bytes (64 KiB) | `swarmops_cli::mcp::LINE_KEEP` | The most bytes `mcp`'s line buffer keeps between messages. |
| Parents | 255 parents | `swarmops_store::meta::parents::MAX_PARENTS` | The most parents a changeset's record holds (`details.store_limit` `parents`): a commit has one parent. |
| Actor | 255 bytes | `swarmops_store::meta::store::MAX_ACTOR_LEN` | The most bytes a ref move's actor takes (`details.store_limit` `actor_bytes`): the agent name's limit keeps a request within it. |
| Records | 65,535 records | `swarmops_store::meta::frame::MAX_RECORDS` | The most records one journal frame holds (`details.store_limit` `records`). |

## Details

### Page sizes of 0

A `limit` or `max_changes` of 0, and a `diff` `max_bytes` of 0, is `E_INVALID_ARG`: the schema
states their minimum of 1 above. `derive`'s `limit` takes 0, and then gives the journal's last
frame as `next`.

### Contents past a limit

A change list holds at most 64 MiB and a commit's contents 1 GiB together; a blob named by id
counts toward neither. So store a large content first with `swarmops blob put`, which takes up
to 512 MiB, and name it in the change by its id: `{"blob": "<id>"}`. A request past a limit
writes nothing, and running it again fails the same way: `E_TOO_LARGE` is not retryable
([E_TOO_LARGE](errors.md#e_too_large)).

### Over MCP

`swarmops mcp` runs each tool through the operation its command runs, so a tool meets the same
limits and errors. Only the request text differs: a message line past 64 MiB is a JSON-RPC
Invalid Request without an `id`, and the server reads on at the next line. The tool descriptions
ask agents for small pages, since clients limit long tool results
([Give agents the store](../operate/agents.md#the-tools-agents-get)).

### Reads with no upper limit

`cat`'s `--max-bytes` (`read_file`'s `max_bytes`) has a default and no upper limit but the
file's size ([Known limitations](../known-limitations.md)).
