Skip to content

ops.backup

ops.backup

Encrypted backups — restic → S3 (BUILD-SPEC §16b, Phase 9).

Operational, NOT part of the sealed core. The scheduled OS-level job (launchd) reads data dirs and writes restic ciphertext to S3; the sealed core never runs backups. restic encrypts + deduplicates client-side, so the only bytes that cross the network are ciphertext — AWS never sees plaintext private data (the §16b backup boundary, analogous to the airlock's de-identification boundary).

BackupPlan dataclass

Everything needed to drive one backup of this host. paths are the roots restic walks; excludes are restic exclude patterns (basename globs, or absolute paths for a specific subtree — e.g. the live Vault raft dir, which is captured via a consistent snapshot instead). Retention drives forget --prune.

repository instance-attribute

paths instance-attribute

excludes = () class-attribute instance-attribute

tags = (DEFAULT_TAG,) class-attribute instance-attribute

keep_daily = 7 class-attribute instance-attribute

keep_weekly = 4 class-attribute instance-attribute

keep_monthly = 6 class-attribute instance-attribute

ResticRunner dataclass

Thin subprocess wrapper. env carries the secrets restic reads from the environment (RESTIC_PASSWORD, and for an S3 repo AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY) — merged over the process environment per call so they never touch argv. Methods return the CompletedProcess; callers inspect .returncode (kept un-raising so the runner can log and the test can assert).

env = field(default_factory=dict) class-attribute instance-attribute

available()

init(repository)

backup(plan)

forget(plan)

restore(repository, snapshot, target)

check(repository)

snapshots(repository)

backup_argv(plan)

restic backup of the plan's paths, tagged + excluded. Flags precede the paths.

build_backup_plan(config=None)

Assemble the host's BackupPlan from [backup] + the data/vault paths. Backs up the note vault + the data dir; EXCLUDES the live Vault raft store (<data>/vault) because it is captured separately as a consistent vault operator raft snapshot (the runner stages that snapshot inside the data dir, so it rides along in this same backup).

check_argv(repository)

restic check — verify repository integrity.

forget_argv(plan)

restic forget --prune scoped to this host's tag, applying the retention policy.

init_argv(repository)

restic init — one-time repo creation (idempotent-safe: errors if already initialized).

restore_argv(repository, snapshot, target)

restic restore <snapshot> --target <dir>snapshot may be an id or latest.

snapshots_argv(repository)

restic snapshots --json — list snapshots (machine-readable).

plan

restic command construction for the scheduled backup (BUILD-SPEC §16b, Phase 9).

The argv builders are pure and deterministic (unit-tested the same way core/sandbox/policy.py's argv is) — the what to back up and the restic flags are code-reviewed, not buried in a shell script. Secrets are NEVER on the command line: the restic repo password and the AWS key are passed to ResticRunner via the environment (RESTIC_PASSWORD, AWS_*), so they never appear in argv, ps, or a log. ResticRunner is the thin subprocess wrapper both the scheduled runner and the round-trip test drive.

DEFAULT_TAG = 'mind-palace' module-attribute

BackupPlan dataclass

Everything needed to drive one backup of this host. paths are the roots restic walks; excludes are restic exclude patterns (basename globs, or absolute paths for a specific subtree — e.g. the live Vault raft dir, which is captured via a consistent snapshot instead). Retention drives forget --prune.

repository instance-attribute
paths instance-attribute
excludes = () class-attribute instance-attribute
tags = (DEFAULT_TAG,) class-attribute instance-attribute
keep_daily = 7 class-attribute instance-attribute
keep_weekly = 4 class-attribute instance-attribute
keep_monthly = 6 class-attribute instance-attribute

ResticRunner dataclass

Thin subprocess wrapper. env carries the secrets restic reads from the environment (RESTIC_PASSWORD, and for an S3 repo AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY) — merged over the process environment per call so they never touch argv. Methods return the CompletedProcess; callers inspect .returncode (kept un-raising so the runner can log and the test can assert).

env = field(default_factory=dict) class-attribute instance-attribute
available()
init(repository)
backup(plan)
forget(plan)
restore(repository, snapshot, target)
check(repository)
snapshots(repository)

init_argv(repository)

restic init — one-time repo creation (idempotent-safe: errors if already initialized).

backup_argv(plan)

restic backup of the plan's paths, tagged + excluded. Flags precede the paths.

forget_argv(plan)

restic forget --prune scoped to this host's tag, applying the retention policy.

restore_argv(repository, snapshot, target)

restic restore <snapshot> --target <dir>snapshot may be an id or latest.

check_argv(repository)

restic check — verify repository integrity.

snapshots_argv(repository)

restic snapshots --json — list snapshots (machine-readable).

build_backup_plan(config=None)

Assemble the host's BackupPlan from [backup] + the data/vault paths. Backs up the note vault + the data dir; EXCLUDES the live Vault raft store (<data>/vault) because it is captured separately as a consistent vault operator raft snapshot (the runner stages that snapshot inside the data dir, so it rides along in this same backup).

run

CLI entrypoint for the scheduled backup — ops/backup/backup.sh drives it.

Builds the plan from config and runs restic via ResticRunner, which inherits RESTIC_PASSWORD and AWS_* from the environment the wrapper populated from Keychain (so no secret is ever on the command line). Subcommands: init | backup | forget | check | snapshots | restore .

main(argv)