Skip to content

Vault lifecycle

A docbank vault is deliberately low-maintenance: data commands start the daemon when needed, imports never alter their sources, deletion is staged, and integrity checks are explicit. This page connects those pieces into an operating routine.

Know what owns the vault

In standalone CLI mode, the daemon is the only process that opens docbank.db and the blob store. Embedded Go applications own separately rooted vaults in-process; they never share a root with a daemon. Ordinary commands are HTTP clients of it and start a compatible background daemon automatically.

docbank daemon status
docbank daemon start       # optional: data commands do this automatically
docbank daemon stop        # graceful; does not start a stopped daemon

Use docbank daemon run when diagnosing startup or configuration problems: it stays in the foreground and writes logs to the terminal. Background logs live under $DOCBANK_HOME/logs/.

A practical operating rhythm

As documents arrive

Import into /inbox, then file from there. Re-running an interrupted import is safe: matching content already present under a destination candidate is skipped.

docbank add ~/Desktop/scans
docbank tree /inbox
docbank mv /inbox/scans/tax-notice.pdf /taxes/2026/

The source files remain untouched. Keep them until your normal backup process has captured the vault.

Before removing anything permanently

Deletion and physical reclamation have separate gates:

  1. rm moves a node to recoverable trash.
  2. trash empty permanently removes old tree entries, but is a dry run unless --run is present.
  3. gc reclaims unreachable loose bytes, but is also a dry run unless --run is present. Packed bytes become logically dead and await repacking; they are not reported as physically reclaimed.
  4. storage repack rewrites eligible sparse packs and retires their old files.

There is no rm --hard, and none of these maintenance commands is scheduled automatically today. Running gc --run immediately after rm cannot reclaim the document because the recoverable trash entry still references it.

docbank rm /inbox/duplicate.pdf
docbank trash list
docbank trash empty --older-than 30d
docbank trash empty --older-than 30d --run
docbank gc
docbank gc --run
docbank storage status
docbank storage repack

Read each dry-run count before adding --run. If a document should return, restore its stable selector before emptying:

docbank restore id:42

On a schedule

Run verify after moving or restoring the vault, after storage trouble, and on a schedule appropriate for the archive. It reads and hashes every cataloged blob, so large vaults take time.

docbank verify

A clean result proves that each cataloged hash can be read and still matches its content. It does not replace a backup: verification can identify missing or corrupt bytes, but it cannot recreate them.

Upgrade without daemon drift

Check first, then install when ready:

docbank update --check
docbank update

An install stops a running daemon, replaces the binary, and starts the new daemon. If installation fails, docbank attempts to restart the old daemon. daemon start, daemon restart, and command auto-start also replace a daemon whose binary or API protocol is incompatible with the invoking CLI.

For unattended installation, use docbank update --yes; do not use --force as a routine upgrade flag. It exists to bypass cached release metadata and to allow replacing an unversioned development build.

Take a coherent backup

Docbank provides backup init, backup create, backup list, backup verify, and backup restore for incremental capture and proved recovery from an immutable Kit repository; see Backup. Those repositories are compressed but not encrypted.

A stopped-vault copy captures the SQLite database and built-in primary as a coherent local-state snapshot. It is not a topology-independent backup: any blob held only by a secondary store is absent. The live reports can help diagnose primary coverage:

docbank info --json
docbank storage list --json

Find the store whose role is primary. Its authoritative_objects can be compared with tracked_blobs from docbank info, but the reports are separate live snapshots. Watches, ingests, clients, and storage jobs can change either count between requests and before daemon shutdown, so matching values are not a backup-completeness proof. sole_authority_objects is weaker still: a blob held by two secondaries and absent from the primary is not a sole copy in either store.

Use docbank backup create for a complete recovery point. It reads one verified candidate for every logical blob and fails rather than publishing a partial snapshot. Merely copying config.toml preserves binding coordinates, not secondary bytes. See Understand primary coverage for the reporting boundary.

If you deliberately need a local-state snapshot, first stop every producer, watch, storage job, and client, then stop the daemon before copying so the SQLite database and primary catalog cannot change during the copy. Do not use this procedure as a complete backup when the vault has used secondary storage.

vault="${DOCBANK_HOME:-$HOME/.docbank}"
docbank daemon stop
tar -C "$(dirname "$vault")" -czf "docbank-$(date +%F).tar.gz" "$(basename "$vault")"
docbank daemon start

The whole directory is the simplest primary-complete snapshot. Its archive state is docbank.db plus blobs/; config.toml is worth retaining when customized. Logs, lock files, and stale runtime records are not archive data.

Protect the snapshot like the vault itself: document contents and a configured API key may both be present. Test restoration into a separate DOCBANK_HOME, then run docbank verify there.

export DOCBANK_HOME=/tmp/docbank-restore-test
mkdir -p "$DOCBANK_HOME"
# Restore the archived vault contents into this directory.
docbank verify
docbank tree /
docbank daemon stop

Never point the restore test at the live vault, and never copy a snapshot over a running vault. To replace a damaged vault, stop the daemon, preserve the old directory under another name, restore the snapshot, and verify before resuming normal use.

For routine recovery testing, prefer restoring the latest built-in snapshot to a separate target and inspecting it under a separate DOCBANK_HOME. Restore already verifies repository reads, SQLite integrity, and manifest statistics before it reports success; docbank verify then exercises the resulting live store through its normal daemon boundary.

Move a vault

The portable path is a verified backup restore:

  1. Create and verify a snapshot repository.
  2. Restore into a separate target on the destination machine.
  3. Point DOCBANK_HOME at that target.
  4. Run docbank verify, then docbank tree /.
  5. Start using the destination only after both checks succeed.

Default restore collapses every source location into a fresh local primary, so the destination does not inherit source paths, endpoints, credentials, or ownership epochs. Use an owner-private store mapping only when deliberately reconstructing selected placement; see Multi-store Storage.

For a primary-complete vault, a stopped directory copy is also valid: stop the source daemon, copy the complete vault directory, and run the same two checks. Linux, macOS, and Windows share the logical vault format. A copied customized config.toml may contain machine-specific watched paths, secondary bindings, or credential profiles; review it before starting the destination daemon.

When something looks wrong

Stop destructive maintenance, keep the original vault directory intact, and collect evidence before changing files by hand:

docbank daemon status --json
docbank verify
docbank daemon stop

Do not delete blob files, SQLite sidecars, lock files, or runtime records while the daemon is running. Continue with Troubleshooting for startup, import, integrity, and API failures.