Skip to content

Backup & Recovery ​

Use config-derived paths, not hardcoded file locations.

Resolve Paths From Config ​

From workspace root:

bash
STATE_FILE=$(jq -r '.stateFile' orchestrator_config.json)
STATE_TARGET="$STATE_FILE"
STATE_FILE="${STATE_TARGET#sqlite:}"
LOGS_DIR=$(jq -r '.logsDir' orchestrator_config.json)
KP_DIR=$(jq -r '.knowledgePackDir' orchestrator_config.json)
CONFIG_FILE=orchestrator_config.json

What to Back Up ​

ItemPath SourceImportanceNotes
State target$STATE_TARGETCriticalLocal JSON, mongo:<key>, or sqlite:<path>
SQLite database${STATE_TARGET#sqlite:}Critical when selectedBack up with a SQLite-consistent snapshot, not a plain live copy
Config file$CONFIG_FILECriticalNeeded to restore correct paths/behavior
Knowledge packs$KP_DIRHighPreserves generated summaries
Logs directory$LOGS_DIRMediumUseful for forensic diagnosis

Daily Backup Script (Example) ​

Create /etc/cron.daily/backup-orchestrator:

bash
#!/bin/bash
set -euo pipefail

ROOT="/opt/orchestrator"
BACKUP_DIR="/backup/orchestrator"
STAMP="$(date +%Y%m%d_%H%M%S)"

cd "$ROOT"

STATE_FILE=$(jq -r '.stateFile' orchestrator_config.json)
STATE_TARGET="$STATE_FILE"
STATE_FILE="${STATE_TARGET#sqlite:}"
LOGS_DIR=$(jq -r '.logsDir' orchestrator_config.json)
KP_DIR=$(jq -r '.knowledgePackDir' orchestrator_config.json)

mkdir -p "$BACKUP_DIR/$STAMP"
case "$STATE_TARGET" in
  sqlite:*)
    sqlite3 "$STATE_FILE" "PRAGMA wal_checkpoint(PASSIVE); VACUUM INTO '$BACKUP_DIR/$STAMP/operator.sqlite';"
    ;;
  mongo:*)
    echo "Use an authenticated mongodump for the configured Mongo database; do not expose credentials in logs."
    ;;
  *)
    cp "$STATE_FILE" "$BACKUP_DIR/$STAMP/"
    ;;
esac
cp orchestrator_config.json "$BACKUP_DIR/$STAMP/"
cp -r "$KP_DIR" "$BACKUP_DIR/$STAMP/" 2>/dev/null || true
cp -r "$LOGS_DIR" "$BACKUP_DIR/$STAMP/" 2>/dev/null || true

tar -czf "$BACKUP_DIR/orchestrator-$STAMP.tar.gz" -C "$BACKUP_DIR" "$STAMP"
rm -rf "$BACKUP_DIR/$STAMP"
find "$BACKUP_DIR" -name 'orchestrator-*.tar.gz' -mtime +30 -delete

Manual Backup (Workspace Mode) ​

bash
STAMP="$(date +%Y%m%d_%H%M%S)"
DEST="$HOME/backups/orchestrator-$STAMP"
mkdir -p "$DEST"

case "$STATE_TARGET" in
  sqlite:*) sqlite3 "$STATE_FILE" "VACUUM INTO '$DEST/operator.sqlite';" ;;
  mongo:*) echo "Create an authenticated mongodump in $DEST" ;;
  *) cp "$STATE_FILE" "$DEST/" ;;
esac
cp orchestrator_config.json "$DEST/"
cp -r "$KP_DIR" "$DEST/" 2>/dev/null || true
tar -czf "$HOME/backups/orchestrator-$STAMP.tar.gz" -C "$HOME/backups" "orchestrator-$STAMP"

Recovery Scenarios ​

1) State File Corruption ​

  1. Stop runtime.
  2. Back up corrupted state file.
  3. Restore latest known-good state into $STATE_FILE.
  4. Validate JSON:
    bash
    jq empty "$STATE_FILE"
  5. Restart runtime and verify /health.

2) SQLite Corruption Or Rollback ​

  1. Stop the named runtime service so no writer remains.
  2. Preserve the failed database, -wal, and -shm files for diagnosis.
  3. Validate the selected backup with PRAGMA integrity_check and PRAGMA foreign_key_check.
  4. Restore the known-good database and keep stateFile on the same sqlite:<path> target, or restore the retained mongo:<key> target when a cutover rollback is explicitly approved.
  5. Start the service once and require /health plus /api/persistence/health to report healthy, with store: sqlite after a SQLite recovery.

For the 2026-07-16 host cutover, retain Mongo unchanged for at least 24 hours and until explicit retirement approval. Do not delete either backend during the rollback window.

3) Disk Pressure ​

  1. Inspect configured logs path:
    bash
    du -sh "$LOGS_DIR" "$KP_DIR"
  2. Archive old logs to backup storage.
  3. Keep recent knowledge packs and remove old ones by retention policy.
  4. Re-check free space: df -h.

4) Full Host Restore ​

  1. Restore backup archive.
  2. Restore orchestrator_config.json.
  3. Resolve paths from config again.
  4. Restore state to $STATE_FILE and packs to $KP_DIR.
  5. Rebuild/restart orchestrator, then verify health/state reads.

Verification ​

Run monthly in non-production:

bash
tar -tzf /backup/orchestrator/<latest>.tar.gz | head

Validate required artifacts exist in archive:

bash
tar -tzf /backup/orchestrator/<latest>.tar.gz | grep -E 'orchestrator_config.json|knowledge-packs'

Retention ​

  • Daily archives: 30 days
  • Weekly archives: 12 weeks
  • Monthly archives: 12 months

Notes ​

  • Do not assume a fixed logs/* state filename; runtime state target comes from stateFile in config.
  • A live SQLite database must be captured with a transactionally consistent SQLite backup (VACUUM INTO, .backup, or a verified filesystem snapshot). Copying only the main database while WAL is active is not sufficient.
  • Recovery instructions must be updated if config keys change.

Built from the canonical repo docs and generated site source.