Skip to content

CLI reference

Use this page to look up command syntax, flags, output, and failure behavior. For a first import, follow Quickstart.

Vault commands use ~/.docbank unless DOCBANK_HOME selects another location. See Configuration. Virtual paths are absolute, /-separated, and case-sensitive. Errors go to stderr and produce a nonzero exit code.

Data commands send HTTP requests to the daemon and start it in the background if needed. They never open the vault directly. docbank daemon status and docbank daemon stop never start a daemon. See Daemon and Ownership and concurrency.

docbank mailbox

docbank mailbox import <mbox-or-zip> [--dest /] [--dialect mboxrd|mboxo] [--id ID] [--job-id ID] [--preview] [--label-tag LABEL=TAG-ID]
docbank mailbox status|watch|cancel|resume|continue <job-id>
docbank mailbox receipts <job-id> [--after ORDINAL] [--limit 100]
docbank mailbox register <archive-id> <description>
docbank mailbox transfer <message.eml> --archive ID --reference REF [--dest /] [--settings ID] [--if-rev REV]

Imports stream caller-selected files to the daemon. Output is JSON. watch prints newline-delimited job snapshots until a terminal state. Upload progress goes to stderr. Canceling watch closes the observer but does not stop the job. Use cancel to stop the import itself. --preview retains a verified source without importing messages. Receipt pages contain at most 100 occurrences. Pass the final ordinal as --after to read the next page.

--id identifies the source upload and, by default, the import job. Repeat it to retry without resending verified chunks. Use a distinct --job-id to import the same sealed source with different settings or a different destination.

See Mailbox archives for retention, limits, explicit continuation, and the EML transfer retry contract.

docbank package

docbank package preflight <directory> --profile dat-concordance-v1|csv-rfc4180-v1 --encoding utf-8|windows-1252 [--page-map-profile ID] [--map mapping.json] [--json]
docbank package import <preflight-id> --name NAME [--into /] [--party LABEL] [--operation-id UUID] [--accept-partial] [--index-supplied-text] [--json]
docbank package import status <operation-id> [--json]
docbank package import cancel <operation-id> [--json]
docbank package list [--direction received|produced] [--after PACKAGE-ID] [--limit 100] [--json]
docbank package show <package-id> [--json]
docbank package members <package-id> [--after-ordinal N] [--limit 100] [--json]
docbank package record <package-id> <row-id> [--json]

Imports a review production as one auditable package. preflight validates a directory that holds the DAT or CSV load file, an optional OPT or LFP page map, and the referenced original documents, images, and supplied text. It reports diagnostics and retains a short-lived preflight ID. Resolve blocking diagnostics before starting an import.

import starts a durable job from that preflight. The daemon verifies files against their preflight SHA-256 hashes and records a receipt for each committed record. Keep the source unchanged while the job runs. status reports committed, gap, and total counts.

Without --accept-partial, the worker verifies every declared file before creating document entries. A missing file, changed source inventory, or content mismatch rejects the job during that check. With --accept-partial, the job retains supported records and reports files that become unavailable as gaps. It finishes as partial when it commits at least one record and reports gaps. --index-supplied-text indexes the sender's text files for search.

cancel stops a queued or running job. It retains records already committed with receipts and removes staged document entries that have no receipt. Shared file bytes remain subject to ordinary garbage collection.

--operation-id makes a retry return the original job when you reuse the same preflight and import options. list, show, members, and record browse retained packages and their immutable rows. Page limits are 50, 100, or 250.

The web application imports a ZIP of the same layout through Import load files. See the web application guide.

docbank labels

docbank labels lookup <label> [--package UUID] [--label-set SET] [--provenance received|assigned] [--cursor CURSOR] [--limit 100] [--json]

Finds every scoped occurrence or page that carries one exact Bates label. A label is only unique inside its package and label set, so scope the lookup with --package when senders reuse numbering. Received labels come from the sender's load file; assigned labels come from Docbank's own productions.

docbank email-pdf

docbank email-pdf <version-id> <local-file> [--paper A4|Letter] [--overwrite]

Requests a retained PDF for one EML version through the daemon, waits for its processing job, verifies the bytes independently, and publishes the local file atomically. New requests require a configured local renderer. See Email PDFs for retained browser downloads and setup.

docbank info

docbank info [--json]

Shows which vault DOCBANK_HOME selects and confirms that its daemon is reachable. Human output includes:

  • The canonical local vault path and stable vault ID.
  • Live file and directory counts, excluding the virtual root.
  • Trash size.
  • Retained version count and logical bytes.
  • Tracked content blobs.
  • Physical storage used by loose files and packs.

--json exposes the same values as stable fields. Agents should record vault_id as identity and use vault_path only to confirm local placement: restoring or moving a vault changes its path without changing its ID. Tracked blob totals can include content awaiting garbage collection. storage reports the files and packs currently occupying physical storage.

docbank formats

docbank formats [--family <family>] [--format <id> | --extension <extension>] [--json]

Reports what the running Docbank binary can do for each classified format. The human table prints FORMAT, CAPABILITY, STATE, and REASON, with one row for each of the seven capability keys. --family limits returned format rows. --format and --extension attach an exact lookup and return only the matching classified row. They cannot be used together.

--json emits the flat format-coverage/v1 response with contract_version, formats, pending, generated_by, and an optional lookup. A recognized pending extension and an unknown extension both succeed, but their lookup matches are pending and unknown_format respectively. See Format coverage for the capability and state definitions.

Node selectors

Commands that inspect or mutate an existing node accept either its absolute virtual path or a stable selector such as id:42. Paths are convenient live coordinates. id:42 continues to name the same document after a move or rename. Human listings print this copyable id:<positive-decimal> form. Machine-readable JSON continues to expose node IDs as numbers.

The destination of mv remains an absolute path because it describes where the node should go. restore also accepts its older bare numeric form for compatibility, although new scripts should use the unambiguous id:42 form. Commands that require a live tree entry reject trashed selectors. Read-only stat, cat, versions list, photos assets inspect, audit status, and audit history can still inspect a trashed node by stable ID. restore is the mutation that returns it to the live tree.

docbank photos

docbank photos assets create <node-selector> [--kind photo|video] [--role ROLE]
docbank photos assets inspect <asset-id|node-selector>
docbank photos assets trash <asset-id> [--revision REV]
docbank photos assets attach <asset-id> <node-selector> [--revision REV] [--role ROLE] [--sidecar-of-file-id ID]
docbank photos assets detach <asset-id> <file-id> [--revision REV]
docbank photos assets exclude <asset-id> [--revision REV] [--excluded=true]
docbank photos assets promote <node-selector> [--revision REV] [--kind KIND] [--role ROLE]
docbank photos assets display <asset-id> [file-id] [--revision REV]
docbank photos settings show
docbank photos settings set raw|image [--revision REV]
docbank photos settings reset [--revision REV]
docbank photos import <source-root> [destination] [--json]

Photo commands emit JSON through the daemon. Image and concrete video files are enrolled when created. Generic RAW files require explicit promotion. Existing-asset and settings mutations read the current revision and retry once if another write changes it first. Pass --revision to fail with exit code 4 instead. inspect also accepts an id:N or path selector for a member file. id:N also finds a trashed member. Sidecars must point at a same-asset RAW or image member and never become the display member.

Photo assets, albums, memberships, settings, and bounded decision receipts are included in JSONL backup and restore.

Photo albums

docbank photos albums create <name>
docbank photos albums list
docbank photos albums show <album-id>
docbank photos albums add <album-id> [asset-id ...] [--query QUERY_JSON]
docbank photos albums remove <album-id> [asset-id ...] [--query QUERY_JSON]
docbank photos albums members <album-id> [--sort added_time|import_time|capture_time] [--direction asc|desc] [--page-size N] [--cursor CURSOR]
docbank photos albums rename <album-id> <name>
docbank photos albums star <album-id> [--starred=false]
docbank photos albums cover <album-id> [asset-id]
docbank photos albums duplicate <album-id> <name>
docbank photos albums delete <album-id>

For add and remove, supply either up to 1,000 asset IDs or --query with strict QueryV1 JSON. A query selects its complete current photo result in one atomic write. Coverage-dependent queries also accept --coverage and --profile-fingerprint. Existing-album writes accept --revision with the same automatic read and retry as asset writes.

members defaults to added_time descending and 50 photos per page; the page size can be 1–250. Omitting the asset ID from cover clears the chosen cover. Removing a photo from an album or deleting the album keeps every file. See Albums for visibility, cover selection, and set: filters.

Photo imports

photos import queues a background import of a folder on the daemon host and prints the operation ID. It creates one photo per same-folder, same-name group discovered in the scan. docbank jobs show <operation-id> --json returns its progress and receipt, including every group the run left unpaired and the number of unsupported files it skipped. docbank jobs cancel <operation-id> stops it. Current duplicate owners preserve existing pairings. See Photos.

docbank people

docbank people list [query] [--limit N] [--cursor C]
docbank people show <person-id>
docbank people create <display-name>
docbank people rename <person-id> <display-name> --revision REV
docbank people retire <person-id> --revision REV
docbank people merge <survivor-id> <absorbed-id> --revision REV --absorbed-revision REV [--operation-id UUID]
docbank people split <person-id> --revision REV --display-name NAME [--identity ID] [--assignment ID] [--external JSON] [--operation-id UUID]

Person commands use the daemon API and emit the same JSON records as the HTTP client. List accepts a folded display-name prefix. show includes identity, external UID, and revision data needed to choose split members. Mutations use the revision supplied by the caller. The merge and split operation IDs make retries replayable. When you omit one, the CLI generates it and prints it to stderr before the request. A split needs at least one identity, assignment, or external UID.

docbank stat

docbank stat <path-or-id> [--json]

Inspects one document or directory. Human output shows its stable id:N selector, live or trashed state, quoted live path and name, kind, revision, and timestamps. Files also show the current immutable version ID, SHA-256 content identity, raw size, and recorded MIME type.

A path resolves only a live node. A stable ID can inspect the same node after it is moved, renamed, or trashed. Trashed output has no path because the node has no live coordinate. --json returns the complete node object used by the HTTP API.

Process exit codes

CLI process codes are stable so shell automation can branch without parsing stderr. Human error text remains explanatory and may change.

Code Meaning Typical action
0 Success, including an empty result or a dry run that found nothing Continue
1 General operational failure, such as local I/O, transport, daemon, or an otherwise unclassified conflict Report or inspect stderr
2 Invalid command usage, arguments, flag combinations, values, or request validation Correct the invocation
3 The daemon returned not_found for the requested vault object Refresh names or identities
4 Stale optimistic state: a revision or audit enrollment preview no longer matches Re-read, reconsider, and retry deliberately
5 Vault maintenance is active, or a vault, backup repository, or physical pack resource is busy or locked Wait and retry, or release the known owner; do not blindly force-unlock
6 A completed verification reported integrity findings, or a content stream failed terminal size/hash/digest proof Do not trust or publish the affected bytes

Integrity commands may write their complete human or JSON report before exiting 6. The report is evidence, not a success indication. Failures that prevent verification from completing, such as an unreachable daemon, use 1. HTTP clients should continue to branch on the API's problem code rather than translating process exits back into HTTP status.

docbank add

docbank add <path>... [--dest <virtual-dir>] [--include <pattern>]... [--exclude <pattern>]... [--replace] [--progress auto|bar|plain] [--json]
docbank add <path>... --preflight [--include <pattern>]... [--exclude <pattern>]... [--json]

Imports files or directory trees into the vault. Sources are copied, never modified or deleted.

Flag Default Meaning
--dest /inbox Virtual destination directory; created (with parents) if missing
--include none Select files matching a basename or source-relative path.Match pattern; repeatable
--exclude none Exclude files or prune directories matching a basename or source-relative path.Match pattern; repeatable
--replace false Replace the live file at each destination path, or skip it when its bytes are unchanged
--preflight false Inventory source metadata without opening file content or changing the vault
--json false Emit only the terminal preflight or ingest report as JSON; suppress progress
--progress auto Human ingest progress: auto, bar, or durable plain lines
  • A directory argument imports recursively: its basename becomes a directory under --dest and relative structure is preserved.
  • An explicitly named directory symlink is followed as the import root. Docbank keeps the supplied basename and source-path spelling.
  • Selected symlinks within the tree, file symlinks, and other non-regular files are skipped and reported as failures. They do not abort the run.
  • Entries removed by include filters are excluded without failure.
  • Include and exclude patterns use / separators on every platform. A backslash in a pattern is rejected.
  • Name collisions with different content auto-suffix: report.pdf → report (2).pdf.
  • --replace records the destination node revision before reading the source, then replaces that exact live file when the bytes differ.
  • --replace skips unchanged bytes without changing the stored MIME type or creating a content version.
  • With --replace, a live directory fails the file. A destination created after the initial read also fails with an exact-name conflict. Docbank does not add a suffix. Without --replace, ordinary suffixing still applies.
  • Without --replace, a rerun skips content that already exists under a candidate name in the destination. An interrupted bulk import can be rerun. See Importing documents.

Preview an import

Run --preflight before a large import. It cannot be combined with --replace. The report counts files, directories, and logical bytes. It separates pack-eligible files, larger loose-only files, files above the ingest limit, exclusions, non-regular entries, and filesystem errors. It also summarizes the largest extension groups.

On macOS, preflight counts cloud placeholders whose bytes are not local. Importing those files downloads them through the provider. Preflight itself reads only filesystem metadata. It does not open placeholders, create the destination, record an ingest, or write blobs. --json includes a bounded set of detailed findings and file-type groups.

Select files with patterns

Preflight and import share these selection rules:

  • A pattern without /, such as *.pdf, matches a basename at any depth.
  • A pattern with /, such as project/*.pdf, matches a source-relative path.
  • * and ? do not cross /; ** is not a recursive globstar.
  • Include rules filter regular files without pruning directories.
  • Exclusions win. Excluding a directory prunes its subtree.
  • Absolute patterns and .. escapes are rejected.
  • Commas are ordinary characters. Repeat the flag for multiple patterns.
  • Patterns are case-sensitive on every platform, including Windows.

Watch configuration uses separate literal exclusion rules.

Read progress and failures

An ordinary import first scans source metadata for file and byte totals, then shows ingest progress on stderr. auto uses a redrawable bar on a terminal and durable periodic lines when redirected. --progress plain forces durable lines. The scan is advisory because sources may change before they are opened. The command ends with a one-line stdout summary plus one stderr line per failed file:

added: 12  skipped: 3  excluded: 2  failed: 1
failed: /src/broken.pdf: opening /src/broken.pdf: permission denied

Exit is non-zero if any file failed. A missing or unreadable top-level source is reported as a failure and the command continues with remaining source arguments, just as it does for failures inside a directory tree. --json suppresses progress and returns the same terminal report shape as the HTTP JSON endpoint, so stdout remains safe for automation.

docbank provenance

docbank provenance <path-or-id> [--limit <n>] [--offset <n>] [--json]

Shows the immutable origin facts retained for one file, newest ingest first. Each result includes its SHA-256 identity, whether it is the active fact, the ingest UUID and time, source kind and description, original source path and modification time, and the identity it supersedes when applicable. A page holds 1–1,000 facts. Human output prints a continuation hint when more remain.

Paths resolve live files. A stable id:<node-id> may also inspect a trashed file. In that case the response has no live virtual path and the human output labels it as trashed. --json returns the complete node, path, page authority, and fact objects. The command is read-only and does not access or alter the original source.

docbank mkdir

docbank mkdir <absolute-virtual-path> [--json]

Creates one directory at the given virtual path and prints its stable id:N selector plus quoted canonical path. The parent directory must already exist. This command does not create missing parents. Existing names, /, relative paths, files used as parents, and . or .. path segments are rejected without creating anything.

The daemon resolves the parent and creates the directory in one transaction, so a concurrent ancestor move cannot redirect a path-based request. --json returns the complete directory node.

docbank ls

docbank ls [path-or-id] [--json]

Lists a virtual directory (default /). Columns: SELECTOR, KIND (dir/file), SIZE (bytes; 0 for directories), MODIFIED (UTC, RFC 3339 at second precision), NAME. Fails with not a directory when the path names a file.

--json returns the resolved directory under directory and its complete, ordered child list under items. Empty directories produce "items": []. JSON preserves the full-precision timestamps.

docbank tree

docbank tree [path-or-id] [-L <depth>] [--max-entries <count>] [--all] [--json]

Prints the subtree rooted at the path or stable node selector (default /), two-space indented, each entry suffixed with its id:N selector in brackets. Output is bounded by default to four levels and 1,000 nodes, so an exploratory command cannot flood a terminal or an agent's context. -L/--depth and --max-entries set narrower or wider bounds. --all restores an unlimited traversal and cannot be combined with either bound. Fails without output if path names a file.

When a bound hides entries, human output names every truncation boundary and the number of direct children omitted there. Narrow the root path or increase a bound before using --all on an unfamiliar archive.

--json returns the resolved root and a deterministic, pre-order items array. Each item contains the node, its absolute virtual path, and its depth beneath the root (direct children have depth 1). Always inspect truncated. When it is true, omissions contains the affected path, the depth_limit or entry_limit reason, and the number of direct children not returned at that boundary.

docbank cat

docbank cat <path-or-id>

Streams the file's stored bytes to stdout. Fails with not a file for directories.

docbank get

docbank get <path-or-id> <local-file> [--overwrite] [--progress auto|bar|plain] [--json]

Downloads one current document version to a local file. Docbank writes into an owner-private staging directory beside the destination, verifies the complete size, SHA-256 identity, and terminal HTTP digest, syncs and closes the file, then publishes it atomically. An interrupted or corrupt transfer never exposes a partial destination.

Existing files are preserved unless you pass --overwrite. Even then, Docbank verifies the replacement before atomically replacing the existing path. An existing symlink is replaced rather than followed. --json suppresses progress and returns the node ID, immutable version ID, hash, size, and absolute local output path. A trashed file remains retrievable by its stable id:N selector while its content version is retained.

docbank put

docbank put <source-file> <vault-path-or-id> [--mime-type <type>] [--progress auto|bar|plain] [--json]

Replaces one existing file's current content while retaining every prior immutable version. The source must be a regular file and is opened without following a final symlink. It is never modified.

put reads the source twice: first to compute the SHA-256 and exact size the daemon must independently verify, then to upload the bytes. Human mode shows separate hash and upload progress. auto uses a terminal bar or durable redirected lines, and plain always emits durable lines. --json suppresses progress and returns the new node, immutable version, and server-computed hash and size. --mime-type overrides extension/content detection.

The command hashes locally before starting or contacting the daemon. It then resolves the target's node ID and revision immediately before upload. Slow hashing therefore does not use the daemon's idle timeout.

The raw PUT sends the inspected revision as If-Match. If someone moves, trashes, or replaces the node before the write, Docbank returns stale_revision.

Success advances the node revision and creates a content_replace version. Older bytes remain available through docbank versions cat <id>. Even identical replacement bytes record a versioned operation, while sharing the existing blob.

docbank edit

docbank edit <vault-path-or-id> [--editor <command>] [--mime-type <type>] [--progress auto|bar|plain]

Downloads the current immutable version into a private temporary directory, verifies its version ID, size, SHA-256, and terminal digest, and opens the staged file in a blocking editor. --editor takes precedence over VISUAL, then EDITOR. The platform fallback is vi on Unix or Notepad on Windows. Editor commands use shell-style quoting on Unix and native Windows command-line parsing on Windows, but are executed directly without a shell. GUI editors must be configured to wait, such as VISUAL='code --wait'.

After a successful editor exit, Docbank hashes the staged file. If its bytes and media type are unchanged, it reports the existing version and does not write. Otherwise it preserves the current media type (or applies --mime-type) and uploads a verified content_replace using the revision inspected before the editor opened. Concurrent mutation fails with stale_revision. The command does not silently reopen or overwrite the newer state. Since editing may exceed the idle timeout, the daemon is reacquired after hashing. Human progress covers download, hash, and upload. This interactive command has no JSON mode.

Private staging is removed on every ordinary outcome. If cleanup fails after an update already committed, Docbank keeps the command successful, prints the new version, and emits a warning rather than encouraging a duplicate retry.

docbank versions

docbank versions <command>

Groups the list, show, cat, and prune operations for immutable document content versions.

docbank versions list

docbank versions list <path-or-id> [--limit <n>] [--offset <n>] [--json]

Lists the file's immutable content versions newest-first. The default limit is 100. --limit accepts 1–1000 and --offset continues through older records. Human output marks the node's current version. --json emits {"items": [...], "total", "limit", "offset"} so callers can distinguish a complete page from a prefix.

Every newly imported file has one revision-one content_create version. Each successful put adds a content_replace row and each revert adds a content_revert row naming its immutable source.

docbank versions show

docbank versions show <version-id> [--json]

Inspects one immutable version by stable UUID, independent of the file's current path. The human view prints node and node-revision identity, recording time, transition kind, blob hash, size, media type, and any reversion source. --json emits the typed record.

docbank versions cat

docbank versions cat <version-id>

Writes that version's bytes to stdout. It exits successfully only after the response version ID, byte count, SHA-256 identity, and terminal Content-Digest all agree. Output may already have reached stdout when verification fails, so scripts publishing a file should write privately and rename it only after a successful exit.

docbank versions prune

docbank versions prune <path-or-id> --version <version-id> [--version <version-id>...] [--run] [--json]
docbank versions prune <path-or-id> --keep-newest <n> [--run] [--json]
docbank versions prune <path-or-id> --older-than <age> [--run] [--json]
docbank versions prune <path-or-id> --all-prior [--run] [--json]

Selects prior versions to remove from one file. The command previews by default. --run applies removal. Choose exactly one selector:

Selector Selection
--version Exact version ID; repeat for multiple IDs
--keep-newest Keep at least this many newest versions, including the current one
--older-than Versions older than a Go duration or whole-day age such as 90d
--all-prior All prior version history

The current content is always retained. Ordinary selectors cannot select the current row. If one includes a source still required by a retained reversion, the report identifies and retains that source. --all-prior can replace a current reversion with a same-byte source-free checkpoint so the complete previous graph, including that superseded revert row, can be released safely. Execution uses the node ID and revision inspected immediately beforehand. A concurrent change fails with stale_revision.

Age previews report their evaluated cutoff. Wall-clock aging does not advance a node revision, so a later --older-than ... --run can also select versions that crossed the same age boundary after the preview. To execute the exact previewed set, pass its candidate IDs back through repeated --version flags. Explicit-ID requests accept at most 1,000 IDs. Re-read the node revision between batches when applying a larger exact set.

Pruning removes version records. It does not reclaim disk space. Human and JSON reports distinguish these storage effects:

  • Shared blobs remain reachable through other retained references.
  • Unreferenced loose blobs wait for docbank gc --run.
  • Dead packed content waits for GC, then docbank storage repack.

A blob can have loose and packed locations in different stores. The report identifies that overlap without counting the blob twice as releasable. Physical byte totals cover every affected authorized location.

Deleted version IDs stop resolving. Later backups preserve the pruned state. Earlier snapshots still contain their original history.

docbank email-documents

docbank email-documents show <operation-id>
docbank email-documents relations --parent-version <version-id> [--limit <n>]
docbank email-documents relations --child-version <version-id> [--limit <n>]
docbank email-documents release <operation-id> --request-digest <digest>

Inspects or releases email attachment receipts through the authenticated daemon. show returns the receipt as JSON. relations returns one JSON page for exactly one parent or child version. The default limit is 100 and the maximum is 250. Continue with --after-operation <next_operation_id> --after-order <next_order> from the previous page.

release requires the request_digest from the inspected receipt. It removes the receipt and its relationships, keeps child documents, and gives up the original operation's retry guarantee. See release email attachment references when a receipt blocks trash empty or version pruning.

docbank refs

docbank refs <sha256> [--limit <n>] [--offset <n>] [--json]

Finds every immutable content version that retains the canonical lowercase SHA-256 identity. Live current references sort first, followed by live prior versions and trashed references. Each result carries the stable version and node IDs, node revision, current/history state, size, recording time, and the node's current path when it is live. Human output renders the node as a copyable id:N selector. JSON keeps its numeric ID. Trashed nodes have no resolvable path.

The default limit is 100. --limit accepts 1–1000 and --offset continues a bounded result. --json emits the page envelope with items, total, limit, and offset. A cataloged physical blob with no retained content version is not a match. The command reports no authoritative references.

docbank revert

docbank revert <vault-path-or-id> <version-id> [--json]

Makes a prior version current by creating a new immutable content_revert history row. It never deletes or rewinds the current or intervening versions, and it does not read or copy the source blob. The selected source must belong to the target file and must not already be its current version.

The command inspects the target's stable node ID and revision, then sends both with the source version ID. A concurrent move, trash, replacement, or reversion fails with stale_revision. Human output identifies the source, new version, resulting revision, size, and hash. --json returns the node, new version, and complete source-version receipt. Repeating the same historical choice later is valid and records another operation.

docbank tag

docbank tag create <name> [--json]
docbank tag list [--limit <n>] [--offset <n>] [--json]
docbank tag show <name-or-id> [--json]
docbank tag rename <name-or-id> <new-name> [--json]
docbank tag delete <name-or-id> [--json]
docbank tag assign <name-or-id> <path-or-node-id> [--json]
docbank tag unassign <name-or-id> <path-or-node-id> [--json]
docbank tag nodes <name-or-id> [--limit <n>] [--offset <n>] [--json]

Defines stable tags and assigns them to live nodes independently of virtual paths. Every subcommand accepts the exact current tag name. Commands operating on an existing tag also accept its UUID. Names are Unicode NFC-normalized, case-sensitive, mutable, and cannot contain control characters. Renaming never changes the tag ID. Deleting a tag removes all assignments but does not delete nodes or content. Recreating the same name allocates a different ID.

A canonical UUID-shaped selector is always a stable ID, including after that ID is deleted. If a tag's display name itself looks like a UUID, address that tag through the different UUID returned when it was created. This prevents a mutable or reused display name from taking over a durable identifier.

tag list and tag show expose each tag's revision. Rename and delete first resolve the selector, then condition the mutation on that inspected revision. A concurrent rename or assignment change returns stale_revision instead of overwriting or deleting the newer state.

Assignment by path resolves that live coordinate and updates its tag inside one daemon/store transaction, so moving an ancestor cannot redirect the operation between separate requests. An id:N selector targets the stable node identity under its inspected revision. Repeated assignment and unassignment are idempotent and report changed: false without a revision bump. A real assignment change advances both the node and tag revisions. tag nodes includes live and trashed nodes, but omits a path for trash because it has no resolvable live coordinate. List commands return at most 1000 results per page and JSON output includes total, limit, and offset.

docbank audit

docbank audit enable <path-or-id> [--agent-label <label>] [--json]
docbank audit enable --node-id <id> [--agent-label <label>] [--json]
docbank audit enable --run --token <preview-token> --acknowledge-permanent-retention [--json]
docbank audit status [path-or-id] [--json]
docbank audit status --node-id <id> [--json]
docbank audit history <path-or-id> [--limit <n>] [--cursor <cursor>] [--json]
docbank audit history --node-id <id> [--limit <n>] [--cursor <cursor>] [--json]
docbank audit history --scope <scope-id> [--limit <n>] [--cursor <cursor>] [--json]
docbank audit verify [--expected <prior-json-report>] [--json]

audit enable permanently protects a directory scope and all retained content versions beneath it. You cannot disable enrollment.

  1. Run the default command to preview the protected set, storage impact, baseline digest, and vault-wide permanent metadata. Keep its one-use token.
  2. Review the retention effect. The first scope preserves enrollment-time names, tree structure, tags, assignments, ingests, and provenance across the whole vault, including outside the scope. Unrelated content does not become a scope member.
  3. Execute with the token and --acknowledge-permanent-retention. The execution command accepts no target selector.

The token expires after ten minutes, is consumed by one execution attempt, and does not survive daemon restart. The daemon recomputes the reviewed authority inside the mutation boundary. If metadata or allocator state changed, it returns audit_preview_stale without enabling the scope. Run a new preview.

audit status without a selector reports vault and scope evidence. A path or stable node ID additionally reports whether that node has sticky audit membership.

audit history reads canonical events for one protected node, newest first. Path events expose old and new coordinates with their live/trash state. Content events expose prior and resulting immutable version IDs. Tag and provenance events expose their stable identity and typed before/after state. The default and maximum page sizes are 50 and 500. next_cursor in JSON, or the next cursor line in human output, continues through older events without shifting when a newer operation is appended. A cursor is opaque and bound to its stable node. Use --node-id for a moved or trashed node. A protected enrollment-baseline member can have no node-specific events until its first later mutation. Use audit status to check membership.

audit history --scope <scope-id> reads the same canonical events across all members of one permanent scope. Human output names each event's copyable node selector. JSON includes the complete scope status alongside the page. Its cursor is bound to the stable scope rather than one node.

audit verify independently replays canonical history against current metadata, then re-hashes every unique blob retained by protected versions. Its terminal evidence contains the stable vault and allocation-lineage identities, allocation count/head, operation high-water mark, and every scope count/head. Human output reports the same evidence and protected-byte totals. JSON is suitable for external recording. Missing, corrupt, unreadable, or inconsistent authority exits non-zero. Use the top-level docbank verify when the decision requires every blob in the vault rather than only permanent audit content.

Save a successful active JSON report outside the vault, then pass it back with --expected. Verification proves that its allocation head and every recorded scope head remain exact prefixes of current authority. Equal or validly extended chains pass. A different vault/lineage, missing scope, shorter chain, or divergent head is reported with a stable problem code and exits non-zero.

The first scope creates the vault-wide genesis. Later audit enable commands can add disjoint directory scopes without duplicating that genesis. Overlapping or nested scopes are rejected. See Permanent audited history for enrollment, supported mutations, and maintenance behavior.

docbank mv

docbank mv <source-path-or-id> <dest-path> [--json]

Moves or renames a node. The move changes metadata only. No bytes move. The destination is interpreted like POSIX mv:

  • If dest-path names an existing directory, the source moves into it, keeping its name.
  • Otherwise dest-path's parent must exist, and its basename becomes the new name (rename, or move-and-rename).
  • If dest-path names an existing file, the move fails with name already exists. Docbank never overwrites.

Directory moves carry the whole subtree. A move that would place a directory under its own descendant fails with move would create a cycle. On success, human output prints moved [id:<id>] <new-path>. --json returns the complete resulting node, including its stable ID, revision, and new path.

docbank mv batch

docbank mv batch <plan.json|-> [--json]

Applies up to 1,000 moves as one all-or-nothing metadata transaction. A dash reads the plan from standard input. Each plan item has source (an absolute virtual path or id:<number>) and an absolute destination:

{"moves":[
  {"source":"/inbox/a.pdf","destination":"/filed/b.pdf"},
  {"source":"id:42","destination":"/inbox/a.pdf"}
]}

Sources are interpreted from the transaction's initial tree. A batch destination is always the exact final coordinate, and its parent is resolved in the planned final tree. Unlike ordinary mv, an existing directory does not mean “move into this directory.” To move into a directory, include the basename in the destination. The complete final tree is validated before anything moves, which supports file and directory swaps and nested reorganizations without temporary user-visible names. Any missing source or parent, stale ID revision, collision, or cycle rejects the entire plan. Human output reports the stable ID and quoted old/new paths in request order. --json returns the same bounded receipt set as structured data.

docbank rm

docbank rm <path-or-id> [--json]

Soft-deletes a node by moving it, and for a directory its entire subtree, to the trash. Nothing is permanently removed and no bytes are reclaimed. The freed name is immediately reusable. Prints:

trashed [id:15] /taxes/2024/return.pdf (restore with: docbank restore id:15)

--json returns the trashed node receipt. Its path is the pre-trash path shown for recovery context. It no longer resolves to that node. Keep the stable id and revision to identify the node.

There is no hard-delete flag. GC cannot collect a trashed document because the trash entry remains a restorable reference. Permanent metadata deletion, unreachable-content collection, and packed-space reclamation are the separate trash empty --run, gc --run, and storage repack operations.

docbank restore

docbank restore <id-or-selector> [--json]

Returns a trashed node (by id:N selector; see docbank trash list) to its original location, re-suffixing its name if a live node now occupies it. If the original parent directory was itself permanently deleted, the node is restored under /. Human output prints restored [id:<id>] <path>. --json returns the complete restored node with its resulting path and revision.

Selecting a photo member restores its whole group. Companions inside trashed folders also recover those folders and their other contents, including other photos. Output reports the selected node's path.

docbank search [<query>...] [--tag <name-or-id>] [--mime-type <type/subtype>] [--under <path-or-id>] [--modified-since <timestamp>] [--modified-before <timestamp>] [--limit <n>] [--json]

Searches live node names and verified extracted text with SQLite FTS5, its full-text search engine. Each whitespace-separated term matches as a prefix. Docbank escapes FTS operator syntax instead of interpreting it. Name matches use BM25 relevance ranking and appear before separately ranked content-only matches. The default limit is 50 and --limit accepts 1–1000. When more matches exist, the command says that the result is truncated. Output columns are SELECTOR, MATCH, and PATH. With no matches, it prints no matches.

--tag requires one current tag assignment. It accepts a tag's exact name or stable UUID using the same selector rules as docbank tag show. The CLI resolves names before searching, so the request is bound to stable identity.

--mime-type accepts one valid parameter-free media type and matches the current version's base type case-insensitively. Stored parameters do not affect the match: text/plain includes text/plain; charset=utf-8. MIME filtering excludes directories and retained non-current versions.

--under accepts an absolute virtual path or stable id:N selector for one live directory and searches its descendants. The CLI resolves paths before the request and the daemon uses the resulting stable directory ID. The directory itself is excluded. A file, missing node, or trashed directory is rejected.

--modified-since and --modified-before accept absolute RFC3339 timestamps and filter the live node's current modification time. The lower bound is inclusive and the upper bound is exclusive. Either may be used alone. When both are present, the lower bound must be earlier. Inputs are normalized to canonical UTC before the request.

The query can be omitted for a bounded filter page when --tag, --modified-since, or --modified-before is supplied. These results are ordered newest-first by current modification time and show filter in the MATCH column. --mime-type and --under narrow a query or an anchored filter page, but neither is an anchor by itself, so a blank search with only one of those options is rejected. Blank includes whitespace-only queries. Results include live files and directories, excluding the vault root. The limit bounds response size, not database work. Search has no continuation cursor: when truncated is true, narrowing time bounds cannot recover omitted nodes that share a timestamp with returned nodes, such as a restored subtree.

--json emits the typed search report with hits, the applied limit, and a truncated boolean. A filtered report also echoes the stable tag_id, normalized mime_type, stable under_node_id, and canonical modified_since / modified_before bounds when supplied. An empty result uses "hits": [].

The daemon indexes current UTF-8 text/*, JSON, and JSONL blobs up to 16 MiB after a complete verified read. It does not automatically run PDF, Office, or OCR extraction. Ordinary search uses words in names and indexed text. Processing search uses the separate form below. Saved queries and highlight sets use a separate HTTP API, with no CLI management command. See Searching.

docbank search <query> --mode <lexical|semantic|hybrid|auto> --profile <name> --source-version <uuid> [--source-version <uuid>...] [--binding <name>] [--limit <n>] [--rerank] [--explain] [--json]

Searches retained processing results for the source versions you list. That set is the source fence: results come only from those versions. --mode, an executable --profile, and at least one --source-version are required. Query text must not be blank. Supply at most 4,096 distinct canonical UUIDv4 version IDs. The CLI adds the selected daemon's vault UUID.

Flag or mode Contract
lexical Search retained rendition text locally
semantic Search the selected embedding binding
hybrid Combine lexical and semantic results
auto Use lexical retrieval and report the actual mode
--binding Select the semantic/hybrid embedding binding; required when the profile has several, inferred when it has one; rejected for lexical/auto
--limit 1–100 results; default 50
--rerank Opt into configured provider reranking for the source-fenced results
--explain Include bounded retrieval-stage codes and counts
--json Emit the processing search report, including modes, coverage, degradation, results, truncation, and trace

Processing search cannot be combined with --tag, --mime-type, --under, --modified-since, or --modified-before. Human output reports the mode, coverage, degradation, and ranked results inside the source fence.

Semantic and hybrid search require active query-text consent; lexical and auto do not. --rerank requires an active query-and-excerpt consent grant for all modes. Approving the profile's plan grants it together with the other configured operations. Human output prints the reranking outcome and bounded candidate count. Follow Consent before semantic or hybrid search to grant consent through a reviewed processing build or the HTTP consent API.

Find similar files

Use docbank search --similar-to id:42 --profile private_text with repeated --source-version <uuid> values to find files like one selected current version. Include that version in the source fence. --version <uuid> pins the selection; omission uses the node's current version. The fence accepts 1 to 4,096 versions. --binding, --limit from 1 to 100, and --json are supported. The default limit is 20 content groups.

Similarity uses stored embeddings locally. It excludes the source node, groups identical content, and reports how many other eligible copies each group has. Missing source embeddings return unavailable. Query text, --mode, --explain, --rerank, and lexical filters cannot accompany --similar-to.

docbank export

Exports original document versions as verified ZIP bundles through the daemon.

Command Purpose
preview --request selection.json Freeze and review up to 1,000 exact document versions.
start <plan-id> --fingerprint <sha256> --operation-id <job-id> Admit a job without waiting for completion.
show-plan <plan-id> Read the retained header, fingerprint, role policies, and admission deadline.
problems <plan-id> [--after N] Read one page of up to 50 frozen unavailable outputs.
status <job-id> Read the current job state once.
cancel <job-id> Request cancellation of active work.
download <job-id> <local-file> [--overwrite] Verify a completed ZIP before saving it locally.
release <job-id> Remove a finished job and its retained archive to free a slot.

Every command accepts --json. Download never releases automatically. See Verified export bundles for the request format, retry rules, publication behavior, and shared capacity limits.

docbank search-export

Exports dated search counts and retains the evidence needed to check them.

Command Purpose and options
create --input request.json --output search-export.zip Create an export through the daemon. Print the export ID if dates need review.
dates <export-id> [--cursor CURSOR] [--limit 50] Read frozen date candidates, up to 100 members per page.
revise <export-id> --choices choices.json --output reviewed.zip Apply a JSON array of reviewed date choices to the frozen observation.
verify <report.zip> Verify internal packet consistency offline.
csv <report.zip> --output search-export.csv Verify the packet and extract its CSV offline.
release <report-id> [--json] Free a live report slot and discard its retained evidence. Keep history, saved packets and child reports.
show <report-id> [--json] Inspect a live report summary, counts, coverage, and expiry.
history [--offset N] [--limit N] [--json] List recorded requests and outcomes; history does not guarantee live availability.
download <report-id> --output report.zip Save the existing verified ZIP without creating another report.

Commands with --output also accept --overwrite. Existing destinations are otherwise preserved. See Search exports for the version 1 request format, date choices, counts, and retention limits.

docbank processing

docbank processing profiles [--json]
docbank processing coverage <version-id> --profile <name> [--json]
docbank processing plan <path-or-id> --profile <name> [--json]
docbank processing build <path-or-id> --profile <name> --plan-fingerprint <sha256> --consent [--json | --ndjson]
docbank processing status <job-id> [--json]

profiles lists names the daemon can execute, their rendition and embedding bindings, and profile fingerprints. The default configuration lists none.

coverage inspects one UUIDv4 version under an executable profile. It prints rendition and embedding counters without starting processing. Stale or unavailable evidence is reported as diagnostic output, and the command still succeeds. JSON contains content_version_id and coverage. See Inspect evidence before reporting for profile restrictions and the distinction from report coverage.

plan resolves a live file's current version and reports its provider flows, disclosed and retained classes, estimates, consent state, and backup effect. Review the complete plan before running build. A changed source or profile requires a new preview and its lowercase SHA-256 --plan-fingerprint.

build requires --consent, even when consent is already active. It grants ongoing permission for this profile's document and query operations to the daemon operator across documents and searches, with no expiry. It then runs the reviewed work and prints the durable job ID and aggregate status. --json emits the job record. --ndjson emits a job event followed by a terminal status event. These output flags are mutually exclusive. A failed required operation returns a nonzero exit code and includes an accepted job ID when available. Preserve that ID after an interrupted response.

status accepts a lowercase SHA-256 job ID and reports aggregate state, phase, completed embedding bindings, and any failure code. It does not start new work. See Document processing for the full workflow and HTTP consent for grants with expiry or revocation.

docbank rendition

docbank rendition get <attachment-id> [--max-bytes <n>]
docbank rendition window <path-or-id> --version <version-id> --profile <name>
  [--attachment <attachment-id>] [--offset <n>] [--max-chars <n>] [--json]

get writes an active retained sanitized-Markdown attachment to stdout only after verifying the complete stream. The attachment ID must be lowercase SHA-256. --max-bytes accepts 1–67,108,864 and defaults to 67,108,864 (64 MiB). Missing, oversized, incomplete, or invalid renditions return a nonzero exit code. The output includes the Markdown envelope and body-relative navigation.

window reads bounded Markdown from the named executable profile's active rendition. It requires an explicit current version and prints a pinned continuation command. It does not verify the complete artifact. See Read and continue a text window for offsets, limits, JSON fields, and discovery costs.

docbank tui

docbank tui

Opens an interactive terminal browser over the authenticated daemon API. It navigates the live virtual tree, searches names and extracted text, shows the selected node's stable authority, and can move one inspected revision to recoverable trash or restore one inspected trash root. It loads at most 1,000 directory entries, search results, or trash roots and reports truncation. K opens the load-file package browser, which lists at most 250 packages or members and looks up exact Bates labels inside the selected package.

Trash and restore require explicit revision-bound confirmation. The TUI does not expose permanent deletion, enroll permanent audit scopes, or run backup and storage maintenance. See the interactive terminal browser for navigation keys and the capability boundary.

docbank web

docbank web [--no-browser]

Opens the embedded web application, starting or reconnecting to a compatible daemon for the selected vault. Use the application to browse, search, inspect, download verified documents, and upload files into the current folder. See the web application guide for all available workflows.

The CLI transfers a daemon-issued browser session through an owner-private launch file, without putting it in a child-process argument. The master API key stays on the CLI's connection to the verified daemon and never enters the browser. Each daemon uses its own temporary loopback origin, even when the API port is fixed. The application removes its scoped session token from the address bar before requests and keeps it only in page memory.

--no-browser prints that authenticated URL instead of opening it. The output contains a live scoped browser session and must be handled as a secret. See the web application guide for its capabilities and trust boundary.

docbank mcp

docbank mcp [--transport stdio|http] [--listen <loopback-ip:port>]
            [--allow-processing] [--allow-package-writes] [--allow-export-writes]

Runs the selected vault's exact MCP 2026-07-28 server as another client of the local daemon. --transport defaults to stdio. Stdio accepts one JSON-RPC message per line, reserves stdout for protocol frames, and writes only redacted diagnostics to stderr. --listen is invalid for stdio.

HTTP requires --transport http, an explicit IPv4 or IPv6 loopback --listen, and [mcp.http] credential_binding in $DOCBANK_HOME/config.toml. The binding resolves one fixed bearer from its named environment variable when the MCP process starts. It must differ from the daemon's effective API key. There is no token flag, remote-daemon option, or non-loopback listener.

The catalog contains 20 read tools by default, including get_photo_asset. --allow-processing adds only the guarded start_processing tool. The agent must first retrieve the plan from the same process, and the operator must already have consented to that unchanged disclosure. The flag does not let MCP grant consent. The supported CLI consent path is docbank processing plan, followed by docbank processing build --plan-fingerprint <fingerprint> --consent. The build command also starts the reviewed work. See Document processing for the full flow.

--allow-package-writes separately adds load-file preflight, package import, and package custodian assignment and resolution. These tools can read local sources and change the vault without using the processing consent flow.

--allow-export-writes separately adds native export previews, start, cancellation, local download, and release. Status is available without write flags. See the MCP export workflow for selection and recovery.

--allow-photo-edits separately adds guarded photo asset mutations. Each write uses an asset revision and one daemon request. Display and settings writes remain in the HTTP and CLI surfaces.

No flag enables another flag's tools; combine the flags to allow more than one kind of work.

See Model Context Protocol for client setup, tool and resource catalogs, transport limits, caching, and unsupported capabilities.

docbank trash

docbank trash list [--json]
docbank trash empty [--older-than <age>] [--run] [--json]

list shows restorable trashed nodes: SELECTOR, TRASHED AT, NAME. Only trash roots are listed: trashing a directory produces one entry, and restoring it brings the whole subtree back. Human output renders UTC seconds. --json preserves the full-precision timestamps.

empty reports how many trash roots are eligible but does not delete by default. Pass --run to permanently delete them. Their blobs then become gc candidates unless referenced elsewhere. --older-than accepts Go durations (12h, 30m) plus a day suffix (30d); negative ages are rejected. Without that filter, every trash root is eligible.

list --json emits {"items": [...]}. empty --json emits the same typed dry-run or execution report as the HTTP API: candidate_roots, retained_roots, held_roots, deleted, and run. Human status lines are suppressed so stdout contains one JSON document.

docbank gc

docbank gc [--run]

Garbage-collects unreachable blobs: content referenced by no live node, no trashed node, and no recorded prior version. Dry-run by default:

3 candidate blob(s), 0 untracked file(s), 1204882 loose byte(s) reclaimable
dry run — pass --run to delete

Packed candidates are reported separately as stored bytes pending repack. Removing their catalog authority does not reclaim the space inside an immutable pack. With --run, loose blob files are deleted first, then their metadata rows. Output separately reports removed blob records, reclaimed loose files, and reclaimed bytes. A crash mid-GC leaves rows without files, which the next gc --run reconciles and verify reports in the meantime. The daemon's maintenance gate rejects new mutations with the retryable busy exit code 5 while gc --run runs, so it never races a concurrent import (see Ownership and concurrency). GC does not invoke repack, and no automatic GC/repack scheduler exists today.

docbank storage

docbank storage list [--refresh] [--json]
docbank storage status [store] [--refresh] [--json]
docbank storage add <name> --binding <profile> [--takeover]
docbank storage add --run --token <preview-token>
docbank storage place <path|id:N> --to <store> [--from <store>] [--move]
docbank storage place --run --token <preview-token>
docbank storage evacuate <store>
docbank storage evacuate --run --token <preview-token>
docbank storage repair <sha256> --store <store>
docbank storage repair --run --token <preview-token>
docbank storage salvage <sha256> --store <store>
docbank storage salvage --run --token <preview-token>
docbank storage detach <store>
docbank storage unregister <store>

Secondary-store registration, placement, evacuation, repair, and salvage use preview tokens before starting durable jobs. Canonical UUID selectors are identity-exclusive. Bindings come from daemon-startup configuration and never expose paths, endpoints, credentials, or ownership epochs to browser sessions. See Multi-store storage for lifecycle, fencing, audit pinning, remote-only acknowledgement, and recovery behavior.

docbank storage status

docbank storage status [store] [--refresh] [--json]

Reports the daemon's physical storage inventory: logical loose blob count and physical loose bytes (raw and zstd files), live packed blobs and their stored/raw bytes, pack count, and immutable packed bytes pending repack. It also reports each store's role, kind, observed state, catalog-authorized objects, sole copies, affected live documents, and objects whose every authorized location is currently offline. The command is read-only. --json emits the same fields as the authenticated GET /api/v1/storage endpoint.

docbank storage pack

docbank storage pack [--max-bytes <bytes>] [--json]

Converts authorized loose blobs into immutable Kit pack files. The operation runs through the authenticated daemon and holds the vault maintenance gate. Reads remain available, while imports and other mutations receive the retryable busy exit code 5. Packing does not change document identity or blob read authority, and mixed loose and packed storage remains valid after an interruption.

--max-bytes is a soft raw-byte work budget. The blob that crosses the budget is committed before the operation stops, and output says the budget was exhausted. Check storage status and rerun if loose blobs remain; crossing the budget does not itself prove that more eligible work exists. Zero (the default) is unlimited. --json includes packing, repair, deferral, and reconciliation counters from the shared Kit lifecycle engine.

docbank storage repack

docbank storage repack [--min-age <duration>] [--min-dead-bytes <bytes>]
                       [--max-bytes <bytes>] [--json]

Rewrites eligible sparse packs with only their live blobs, atomically changes catalog authority, and retires the old immutable pack files after active readers release them. Packs with no live mappings are retired regardless of age. A partially live pack is eligible when at most half its entries remain and it satisfies both selection thresholds. Defaults are --min-age 24h and --min-dead-bytes 8388608. Use smaller positive values for immediate manual compaction.

--max-bytes is a soft live raw-byte budget. Zero is unlimited and makes a source-content error fail the operation immediately. A positive budget lets Kit continue with independent eligible source packs and return their combined errors after committed work. The report's bytes_repacked is live raw content rewritten, not a claim about filesystem bytes reclaimed. Compare storage status before and after when exact inventory change matters.

Pack retirement can be deferred when another process holds a source pack open, most commonly through a Windows handle that does not permit deletion. The repack response then uses pack_retirement_deferred: replacement catalog authority has already committed, so do not restore the old mapping or assume the rewrite rolled back. Release the external file lock and run docbank storage pack; its reconciliation pass removes the orphaned source pack.

docbank transfer

docbank transfer verify

docbank transfer verify <package> [--archive-id <archive-id>] [--json]

Verifies a transfer package from a local directory, ZIP file, or legacy Msgvault JSONL file without opening a vault or starting the daemon. The command reads only the named path. See Verify transfer packages for the integrity checks and legacy compatibility limits.

Flag Default Meaning
--archive-id <archive-id> none Bind a legacy msgvault-message-export/1 JSONL file to the registered archive ID that will own it. The flag is required for legacy JSONL and ignored for directory and ZIP packages. Verification checks the ID's syntax but cannot confirm vault registration.
--json false Write the complete machine-readable verification report to stdout.

Human output is one valid <format> package <package-id> for archive <archive-id> (<package-authority> authority) line for a complete valid package. A valid partial package starts with valid partial and includes a second line, next_cursor: "<continuation>". An invalid package starts with invalid <format> package: <n> finding(s), followed by each retained finding as <path>: <detail> (<code>).

The JSON report contains format, package_id, archive_id, next_cursor, valid, partial, findings_truncated, findings, findings_total, counts, bounds, integrity_authority, and package_authority. A legacy report also contains legacy_evidence, with format, sha256, and bytes, plus format_limitations. Each format limitation has capability, state, and reason.

Exit 0 means validation succeeded and the reader closed successfully. A bad invocation, including a missing or malformed --archive-id for legacy JSONL, exits 2. Invalid-package findings produce a report and exit 6. Operational failures, including cancellation, spool failures, and cleanup failures, report their cause and exit 1 without a validation report. Input-opening, legacy-normalization, and report-output errors also exit 1.

docbank verify

docbank verify

Validates logical metadata, including independent replay of any audit history, then re-hashes every stored blob against its recorded SHA-256. Reports metadata failures as metadata: <detail> and blob failures as missing: <hash> (row without file), corrupt: <hash> (hash mismatch), or unreadable: <hash> (I/O error), followed by <n> blob(s) ok, <n> problem(s). Exits non-zero if any problem was found.

docbank backup

docbank backup init [--repo <dir>] [--json]
docbank backup create [--repo <dir>] [--tag <label>] [--jobs <n>]
                      [--force-unlock] [--progress auto|bar|plain] [--json]
docbank backup list [--repo <dir>] [--json]
docbank backup verify [snapshot] [--repo <dir>] [--all] [--quick] [--jobs <n>]
                      [--force-unlock] [--progress auto|bar|plain] [--json]
docbank backup restore [snapshot] --target <dir> [--repo <dir>] [--overwrite]
                       [--store-map <owner-private-file>]
                       [--jobs <n>] [--force-unlock]
                       [--progress auto|bar|plain] [--json]

Creates, lists, verifies, and restores recovery points in a Kit backup repository. Supply --repo or configure [backup] repo; the flag takes precedence.

Command Behavior
init Initialize a repository
create Capture a verified snapshot using logical JSONL metadata
list List snapshot history
verify Check the latest snapshot, a named snapshot, or every snapshot with --all; --quick skips content reads
restore Restore the latest or a named snapshot to a separate --target

create pauses mutations briefly to fix the metadata view for the snapshot. It then streams loose or packed content while normal daemon work resumes.

A nonempty restore target requires --overwrite. Restore merges into it without clearing unrelated files. Compatible content is restored packed; the report identifies any verified loose fallback.

--jobs 1 serializes repository readers. Use --force-unlock only when the repository lock's owner is known to be gone.

create and verify show per-stage progress bars on a terminal and persistent lines when redirected. --progress chooses the format. Every subcommand supports --json; long-running commands suppress progress in that mode. See Backup and restore for the procedure.

docbank daemon

docbank daemon run
docbank daemon start
docbank daemon status [--json]
docbank daemon restart
docbank daemon stop
Command Behavior
daemon run Run in the foreground until signaled or stopped; log to stderr
daemon start Start detached in the background; write JSON logs to $DOCBANK_HOME/logs/
daemon status Report pid, address, version, and uptime without starting a daemon
daemon restart Stop a running daemon, then start it; also works when none is running
daemon stop Stop gracefully, or print no daemon running; never start a daemon

status --json emits {"running": bool, "pid", "address", "version", "started_at"}. Restart prints restarted: ... or started (was not running): ... according to the prior state.

Data commands start a daemon automatically when needed. Use daemon start for explicit control, such as inspecting logs before sending data commands. It normally invokes daemon run in the background; foreground use is useful for debugging.

Start, restart, and automatic startup also replace an incompatible daemon. If its version or API protocol differs from the invoking binary, the CLI stops it and starts the matching one. It prints replaced daemon <old> (pid N) with <new>: .... See Daemon.

docbank jobs

docbank jobs [--json]

Shows daemon-owned background tasks in stable name order, including status, start and finish timestamps, and the bounded error recorded for a failed task. Running tasks have no finish timestamp. Terminal task records remain visible until the daemon restarts. --json emits {"items": [...]} for automation. Every daemon registers extract:plain-text, extract:source-metadata, and maintenance:auxiliary-checksums; process:renditions appears only when a rendition provider is bound, telemetry:heartbeat appears while anonymous usage telemetry is on, and configured watched inboxes add watch:<name> tasks. See Daemon for what each job does.

docbank media

docbank media submit --file CALL.wav --operation-id UUID \
  --occurrence-ref REF --revision REV
docbank media list
docbank media status SOURCE_ID
docbank media operation OPERATION_ID
docbank media transcript SOURCE_ID --source-version-id SOURCE_VERSION_ID \
  --content-version-id CONTENT_VERSION_ID
docbank media import-artifact SOURCE_ID --kind media --file CALL.wav \
  --occurrence-id OCCURRENCE_ID --operation-id UUID
docbank media import-artifact SOURCE_ID --kind transcript \
  --file TRANSCRIPT.txt \
  --occurrence-id OCCURRENCE_ID --operation-id UUID
docbank media import-artifact SOURCE_ID --kind caption --file CAPTIONS.srt \
  --provider loom --occurrence-id OCCURRENCE_ID --operation-id UUID
docbank media retry SOURCE_ID --processing-profile supplied-transcript \
  --operation-id UUID
docbank media retry SOURCE_ID --processing-profile supplied-captions \
  --operation-id UUID
docbank media occurrences list [--source-id SOURCE_ID]
docbank media occurrences declare SOURCE_ID --operation-id UUID \
  --occurrence-ref REF --revision REV
docbank media occurrences revoke OCCURRENCE_ID --operation-id UUID --revision REV
docbank media origins

media origins prints each registered origin's ID, provider, acquisition_available value, adapter contract, operator-declared deployment revision, and startup probe result. The fields are adapter_contract, deployment_revision, probe_state, and probed_at. See the origin listing contract. Self-hosted Cap registrations report acquisition_available: false until a later acquisition owner exists.

media operation prints the saved receipt of a media submit --reference-file call by its operation ID, for use after a lost reply.

media submit accepts bounded WAV and MP3 files. It verifies the declared size and SHA-256 computed by the CLI, retains the original bytes, and records the caller occurrence separately. Repeating the same bytes reuses one source version while a different occurrence remains independently revocable. An empty processing profile means retention only.

Use media import-artifact --kind media to bind a supplied WAV, MP3, or remote MP4 to the exact visible occurrence of a remote source registered through the HTTP or embedded API. MP4 uses the .mp4 extension and video/mp4, with limits of 20 MiB, 2,088,960 coded pixels, 300,000 milliseconds, and 18,000 frames. The original must be retained before a caption or transcript can be imported. Use --kind caption --file CAPTIONS.srt --provider loom for SubRip input, or --kind transcript --file TRANSCRIPT.txt for supplied transcript text. The fixed upload table maps .mp4 to video/mp4 and .srt to application/x-subrip. The receipt returns the input ID. Pass that value with media retry --supplied-input-id INPUT_ID when more than one transcript exists for the recording. The selected input remains fixed for the job; importing another transcript does not change work already queued. Artifact imports retain inputs only. Use media retry to request processing after the import. Retry selects the caller's newest visible occurrence for the source; it cannot target an older occurrence. Use ordinary document processing with the older recording's node and current content version when needed.

Processing is explicit. The built-in supplied-transcript profile turns the selected retained transcript into the ordinary sanitized Markdown rendition used by search and export. The supplied-captions profile retains timed media-transcript/v1 evidence and supports lexical and auto search. Semantic and hybrid search are not configured for supplied captions. media retry queues work only when the exact processing consent is still valid, then returns without waiting for the provider. The daemon resumes queued work after restart. In media status, operation_id, operation_state, job_id, and supplied_input_id describe the newest processing attempt. To wait for a retry, match its operation ID and wait for its operation state to become succeeded or failed. The separate coverage_state preserves the last successful transcript's coverage while a retry is pending or fails. Revoking that transcript's occurrence makes its coverage stale. Before any successful processing, coverage describes the current attempt. Media processing requires a profile with a rendition provider. Profiles that only produce embeddings are rejected.

media transcript reads one retained transcript through the daemon. Both version flags are required so a newer recording cannot be accepted by accident. The JSON result keeps evidence_state, coverage_state, and operation_state separate. Only a ready evidence state includes transcript units. Units keep an optional time_span and speaker, and the origin identifies supplied versus generated evidence. Ready transcripts include build_id, and supplied transcripts also include supplied_input_id. See how to verify search attribution.

Remote references submitted by the CLI are read from --reference-file PATH, or from stdin with --reference-file -. They are never accepted as a command-line URL. CLI reference submission uses the configured-origin policy, performs no network access by itself, and rejects processing requests. The CLI has no canonical URL option. Submit a canonical URL for the generic manual path through the HTTP or embedded API, then use the CLI for --kind media, transcript import, and retry. Acquisition planning, grant, and revoke commands are available under media acquisition-plan and media consent. A daemon without a registered acquisition policy reports the capability as unavailable.

docbank watch

docbank watch list [--json]

Lists the daemon's effective watched-inbox configuration in stable name order: the machine-local source, virtual-tree destination, complete settle window, minimum source age (0s when disabled), scan interval, exclusion count, and current runner state. Human output quotes source and destination paths so terminal control characters cannot disguise them. --json includes the complete exclusion rules and the corresponding job record for agents and automation.

This command is inspection only. Edit config.toml and restart the daemon to change a watch.

docbank update

docbank update [--check] [--yes] [--force]

Checks GitHub for a newer release and installs it unless --check is set. During installation, the command stops a running daemon, replaces the binary, and restarts from the new executable. If installation fails, it restarts the old daemon.

  • --check prints the current and latest versions without installing.
  • --yes skips confirmation. It is required for noninteractive installation.
  • --force fetches release metadata again and permits replacing an unversioned development build. It does not reinstall an already-current release.

The command refuses a release without a published SHA256 checksum.

docbank openapi

docbank openapi

Prints the HTTP API's OpenAPI document as YAML. It needs no running daemon and no vault: routes are registered against an offline server instance and never invoked. Use it for agents and API client generation. See HTTP API.

docbank version

docbank version

Prints the build version and commit (dev (unknown) for untagged local builds; release builds inject both via -ldflags).

Environment variables

DOCBANK_HOME selects the vault (see Configuration). DOCBANK_LOG_LEVEL sets the daemon or MCP process log level (debug, info, warn, error; default info) for docbank daemon run, background-spawned daemons, and docbank mcp diagnostics.