CLI command

skarbiec backup

Keep copies of the vault on a disk or folder of the owner's choosing — once, or on every maintain pass — and know before the day they are needed that a copy would restore.

Invocation#

Shell
skarbiec backup <directory>
skarbiec backup check <file> [--open]
skarbiec backup diff <file>
skarbiec backup restore <file> [--yes]
skarbiec backup schedule [<directory>]
skarbiec backup unschedule

Purpose#

Keep copies of the vault on a disk or folder of the owner's choosing — once, or on every maintain pass — and know before the day they are needed that a copy would restore.

Required inputs and options#

  • backup takes one absolute directory that exists. check takes one copy's path; --open also decrypts every live item in it with the keys this machine holds. diff takes one copy's path. restore takes one copy's path and --yes to act. schedule takes one absolute directory that exists, or nothing to name the one scheduled; unschedule takes nothing. POST /v1/operator/backup takes directory, POST /v1/operator/backup/check takes file and open, POST /v1/operator/backup/diff takes file, POST /v1/operator/backup/restore takes file and yes, POST /v1/operator/backup/schedule takes directory or nothing, and POST /v1/operator/backup/unschedule takes nothing; all run on the machine serving the API, never forwarded, and refuse a path that is not absolute.

Output and state effects#

  • backup reads the vault as a vault first, then writes <vault file name>.<stamp> into the directory, owner-only, never over an existing file, syncs it, reads the copy back as a vault, appends a vault-backed-up audit entry naming the copy and its size, and prints ok, backup, bytes and holds (live_items, trashed_items). The copy is the same ciphertext as the vault, so it opens only with the vault's keys. check prints ok, backup and holds — live_items, trashed_items, opened and unreadable, each live item that would not decrypt with its error when --open asked — with ok false when any would not; it writes nothing. restore reads the copy as a vault and, without --yes, prints ok, confirmed false, backup, live_items and would_lose — the live items of the current vault the copy does not hold — and writes nothing; with --yes it keeps the current vault aside as <vault file>.pre-restore.<stamp>, owner-only, writes the copy over the vault file atomically, appends a vault-restored audit entry naming the copy, the file kept aside and the items lost, and prints confirmed true, live_items, lost and kept_aside, so restoring the file kept aside undoes it. schedule writes the directory, owner-only, to <vault file>.backup-directory beside the vault — this host's choice, never in the vault document replicas receive — appends backup-scheduled and prints ok, directory and copy: from then on every `skarbiec maintain` pass keeps <vault file name>.latest there, written beside it, synced, read back as a vault and only then renamed over the previous copy, and only when the vault changed since; each refresh appends a vault-backed-up entry with scheduled true, and maintain's answer carries backup (copy and refreshed). schedule alone prints the directory and copy, or null for both. unschedule removes the file and prints unscheduled, false when nothing was scheduled. A copy can also be read without replacing anything by pointing SKARBIEC_VAULT_FILE at it, or merged with migrate --from <copy>. Desktop's Settings → Policy shows all of them as Backups, Restore a backup… showing would_lose and asking first.

Refusals#

  • Another arrangement exits 2 with `usage: backup <directory> | backup check <file> [--open] | backup restore <file> [--yes] | backup schedule [<directory>] | backup unschedule`. A relative directory exits 2 naming it; a path that is not a directory fails with `<path> is not a directory here; nothing was copied` (schedule: `nothing was scheduled`); a vault or a copy that does not read as a vault fails with `<path> does not read as a Skarbiec vault` and the parse error (restore: `...; nothing was restored`), and a failed create, copy or sync names the copy's path. restore that cannot keep the live vault aside stops before writing anything. A maintain pass whose scheduled directory is gone fails naming it — a disk unplugged, a folder moved — and a rolling copy that does not read back is not put in place, so the last good one stays.

Examples#

skarbiec backup diff /Volumes/Backup/skarbiec/vault.json.latest | jq '{only_in_copy: [.only_in_copy[].item], changed: [.changed[] | {item, copy: .copy.revision, vault: .vault.revision}]}' # diff reads both files' envelopes and decrypts nothing: only_in_copy, only_in_vault and changed (each side's revision and updated_at), with same counting the items both hold alike