A backup orchestrator built entirely in .aux4 — pure command composition over existing aux4 packages. It never touches the backup bytes itself: it builds destination paths, runs a provider through aux4/jobs, and catalogs every target and run in aux4/repository.
aux4 aux4 pkger install aux4/backup
aux4/backup glues together four building blocks:
aux4/jobs — runs the provider asynchronously, captures its output, and fires an --onComplete hook.aux4/repository — the catalog: two repositories, backups (targets) and runs (executions).aux4/cron — optional scheduling: a backup-<name> task that runs aux4 backup run <name> on a recurring schedule.backup and restore as sibling subcommands.The orchestrator is byte-free: the provider owns all I/O to the artifact path and prints a small manifest.
A backup provider is any command exposing backup and restore subcommands that:
--config <profile> (and optionally --configFile <path>) — connection details come from config, not the catalog, keeping secrets out of the catalog.--path <path> — where the artifact is read from / written to. The provider owns its own I/O to that path. {
"path": "/backups/db-20260720T120000Z.sql",
"bytes": 20480,
"checksum": "3421689",
"status": "success",
"format": "sql"
}
# Define your backup policy in a YAML file and apply it
aux4 backup apply backup-policy.yaml
# Or register targets individually
aux4 backup register mydb \
--command "aux4 db mysql" \
--config prod \
--configFile ./db.yaml \
--dir /var/backups/mydb \
--retain 7
# Run a backup (async — enqueued as a job), or block until it finishes
aux4 backup run mydb
aux4 backup run mydb --wait true
# Run every registered target
aux4 backup run all
# List registered targets, and list runs (filterable)
aux4 backup targets
aux4 backup list --target mydb --status success --limit 5
# Per-target health: last success, age, last run state
aux4 backup status
# Inspect a run's job (status, stderr, stdout)
aux4 backup logs mydb
aux4 backup jobs status mydb-20260720T120000Z
# Verify the latest artifact still exists on disk with the recorded size
aux4 backup verify mydb
# Finalize stale 'running' runs after a crash (job died without its onComplete)
aux4 backup reconcile
# Restore the latest successful backup
aux4 backup restore mydb
# Restore a specific run
aux4 backup restore mydb --at mydb-20260720T120000Z
# Keep only the last N artifacts, delete older ones (one target or all)
aux4 backup prune mydb --retain 3
aux4 backup prune all
# Schedule a daily backup (requires the cron daemon)
aux4 cron start
aux4 backup schedule mydb --every "1 day" --at 02:00
aux4 backup unschedule mydb
# Remove a target (and optionally purge its runs + artifacts)
aux4 backup deregister mydb --purge true
| Command | Description | |---------|-------------| | apply <file> | Converge targets from a policy file (register new, update changed, deregister removed) | | register <name> | Register a backup target in the catalog | | deregister <name> | Remove a target (and optionally purge its runs with --purge) | | targets | List registered backup targets | | run <name> | Run a backup for a target (or run all); --wait to block | | list | List backup/restore runs (filter by --target/--status/--limit) | | status | Per-target health: last success, age, last run state | | restore <name> | Restore from the latest successful backup, or a specific run with --at | | verify <name> | Check a backup artifact exists on disk with the recorded size | | prune <name> | Keep the last N successful artifacts, delete older ones (or prune all) | | reconcile | Finalize stale running runs whose job has finished or died | | logs <name> | Show a run's job status, stderr, and stdout | | jobs <sub> | Inspect the underlying jobs (list, status, tail, logs) | | schedule <name> | Add/replace a cron task that runs the backup on a schedule | | unschedule <name> | Remove the cron task for a target |
aux4 backup apply <policy-file>
Converges backup targets from a declarative YAML policy file. The file uses the config.targets format:
config:
targets:
prod-db:
command: aux4 db postgres
config: prod
configFile: ./db.yaml
dir: /var/backups/db
schedule: 1 day
at: "02:00"
retain: 30
Targets in the file but not in the catalog are registered. Targets with changed values are updated. Targets in the catalog but not in the file are deregistered (run history is preserved). Unchanged targets are skipped. The file is the source of truth — run apply after editing to converge.
aux4 backup register <name> --command "<provider>" --config <cfg> [--configFile <f>] --dir <local-base> [--retain <N>]
Writes a backups record: { command, config, configFile, destination, retain, createdAt }. destination is the local base directory where artifacts are written (stored as an absolute path).
aux4 backup deregister <name> [--purge true]
Removes the target's backups record and, best-effort, its backup-<name> cron task. With --purge, also deletes every runs record for the target and its artifact files on disk.
aux4 backup targets
Lists the registered targets (id, command, config, destination, retain, schedule). JSON by default; a table on a TTY.
aux4 backup run <name> [--wait true]
aux4 backup run all
Builds a run id (<name>-<timestamp>) and artifact path (<destination>/<name>-<timestamp>.sql), writes a runs record with status: running, then enqueues the provider's backup subcommand as a job. When the job completes, an --onComplete hook finalizes the run record with status, bytes, checksum, exitCode and finishedAt parsed from the provider manifest. Because the record is written at start, in-flight and crashed runs are visible in list. --wait blocks until the run finishes and prints its final status (useful in CI).
aux4 backup list [--target <name>] [--status <status>] [--limit <N>]
Lists the runs (id, type, status, bytes, startedAt), newest first. JSON by default; a table on a TTY. Filter with --target, --status (running/success/failed), and --limit. Use aux4 backup targets to see the registered targets.
aux4 backup status
Per-target health summary: for each target, its last successful backup, how many hours ago (ageHours), and the state of its most recent run. lastSuccess is never when a target has no successful backup yet. JSON by default; a table on a TTY.
aux4 backup restore <name> [--at <runId>] [--config <override>]
Picks the run to restore (the latest successful backup by default, or the run named by --at), reads its artifact path, and enqueues the provider's restore subcommand. A restore run is recorded in the catalog. Use --config to point the restore at a different provider profile (e.g. restoring into a staging database).
aux4 backup verify <name> [--at <runId>]
Checks that the target's latest successful backup (or the run named by --at) still exists on disk and its byte size matches what was recorded. Reports MISSING or SIZE MISMATCH on failure. Checksum re-verification is not done here — the checksum algorithm is the provider's, so verify stays provider-agnostic and checks presence and size only.
aux4 backup prune <name> [--retain <N>]
aux4 backup prune all
Keeps the last N successful backups (newest first) and deletes the older artifacts from disk along with their runs records. When --retain is omitted, the target's registered retain value is used. prune all prunes every registered target.
aux4 backup reconcile
Finalizes stale running runs. A run is written running at start and finalized by its job's onComplete hook; if that hook never fires (killed monitor, host reboot, scheduler down), the record stays running forever. reconcile scans every running run, finds its job in aux4/jobs (matched by the job's onComplete, which carries the run id), and finalizes it: success/failed from the exit code if the job finished, or failed if the job is gone/dead. Runs still genuinely in-flight are left alone. Run it after a crash or on a schedule.
aux4 backup logs <name> [--run <runId>]
Resolves the run's jobId and prints its job status, stderr, and stdout from aux4/jobs. Defaults to the target's latest run; pass --run for a specific one.
aux4 backup jobs list
aux4 backup jobs status <runId>
aux4 backup jobs tail <runId>
aux4 backup jobs logs <runId>
Inspects the underlying aux4/jobs execution. list shows all jobs; status, tail and logs map a run id to its job and forward to aux4/jobs.
aux4 backup schedule <name> --every "<expr>" [--at HH:MM] [--max <N>] [--port <port>]
aux4 backup unschedule <name> [--port <port>]
Scheduling wires aux4/cron to the orchestrator. schedule creates (or replaces) a cron task named backup-<name> whose command is aux4 backup run <name> with the catalog --db and --jobsPath baked in as absolute paths, so scheduled runs always hit the same catalog regardless of the scheduler's working directory. --every accepts expressions like 30s, 15 min, 1 day, monday; --max auto-removes the task after N executions. register --schedule "<expr>" is a shortcut that registers a target and schedules it in one step.
The cron scheduler daemon must be running (aux4 cron start, default port 8421) for schedule, unschedule and register --schedule to reach it.
Stored in aux4/repository (default database ~/.aux4.config/backup/catalog.db):
backups (targets): id = name, data = { command, config, configFile, destination, retain, schedule, at, createdAt }runs (executions): id = <name>-<timestamp>, data = { target, type: backup|restore, path, status: running|success|failed, startedAt, finishedAt, bytes, checksum, exitCode, jobId }destination is a local directory. Remote targets (s3://, gs://) are a provider concern and come later.aux4/cron. The scheduler daemon must be running (aux4 cron start) for schedule/unschedule/register --schedule to reach it on --port (default 8421).