checkId: check.storage.backup plugin: stellaops.doctor.storage severity: warn tags: [storage, backup, disaster-recovery]

Backup Directory Accessibility

Currency note (2026-08-18, verified against src/). Two things about this check were wrong or missing here and are load-bearing:

  1. It has no runtime host today. check.storage.backup ships in the mounted stellaops.doctor.storage bundle, whose only loader was doctor-web’s DoctorMountedRuntimePluginLoader. doctor-web was retired 2026-08-17 (SPRINT_20260722_009 DOC-5 stage 4), and the CLI — now the only live AddDoctorEngine() host — registers only the Core, Database and BinaryAnalysis plugins in-process. The bundle is still built, signed and packaged; nothing runs it. Needs an owner; see SPRINT_20260802_003 Decisions & Risks.
  2. It is not the missed-backup check. This one asks whether the backup directory is usable and whether some file in it is newer than a hardcoded seven days. Whether a backup that should have happened actually did is doctor.platform.backup.schedule(SPRINT_20260802_003 BRP-3), which judges a declared cadence and runs in platform-web’s live doctor-check/v1 surface.

The “How to Fix” commands below were also fiction — stella backup create/schedule/status/logs do not exist and there is no backup command group in the CLI — and have been replaced with the shipped tooling.

This Doctor check helps operators confirm that Stella Ops can write to its configured backup location and that recent backups exist, so the platform can actually be recovered after data loss.

What It Checks

Verifies backup directory accessibility and recent backup presence. The check:

The check only runs when a backup path is configured. When gated self-healing is explicitly enabled, Doctor can offer the non-destructive heal.storage.backup-directory.create action to create the configured directory idempotently. Auto-execution remains off by default and is subject to the Doctor remediation gate.

Why It Matters

Backups are the last line of defense against data loss. An inaccessible backup directory, missing backups, or stale backups mean the system cannot recover from database corruption, hardware failure, or accidental deletion. The 7-day staleness threshold ensures backups are kept reasonably current.

Common Causes

How to Fix

Docker Compose

environment:
  Backup__Path: "/var/backups/stellaops"
volumes:
  - backup-data:/var/backups/stellaops

Bare metal / the compose host

The backup tooling runs on the host, not inside a service container — pg_basebackup needs a replication connection from inside the postgres container’s network namespace.

# Create the backup directory
mkdir -p /var/backups/stellaops
chmod 750 /var/backups/stellaops

# Take an application-consistent backup (BRP-2)
BACKUP_DIR=/var/backups/stellaops \
  ./devops/compose/scripts/backup-postgres.sh --yes

# Declare the product-owned cadence and retention, then run the whole cycle (BRP-3)
./devops/compose/scripts/backup-schedule.sh declare \
    --interval-hours 24 --grace-hours 2 --keep-last 7 --keep-days 14 --min-keep 2
BACKUP_DIR=/var/backups/stellaops ./devops/compose/scripts/backup-schedule.sh run

Full procedures, the consistency model, and the measured recovery objectives: backup-restore-ops.md.

Verification

# Whether a backup that should have happened did (the live check)
curl -sS -H "Authorization: Bearer $STELLAOPS_TOKEN" \
  https://stella-ops.local/api/v1/platform/backup/schedule | jq .

# This check — only reachable from a host that loads the storage bundle (see the
# currency note above; no such host runs today).
stella doctor run --check check.storage.backup