#!/usr/bin/env bash set -euo pipefail # Creates a consistent SQLite backup and a secrets-excluded Leo/KB file archive # from the Teleo VPS. It writes local proof files but does not upload to GCP. TELEO_VPS_HOST="${TELEO_VPS_HOST:-root@77.42.65.182}" TELEO_SSH_KEY="${TELEO_SSH_KEY:-$HOME/.ssh/livingip_hetzner_20260604_ed25519}" TELEO_REMOTE_ROOT="${TELEO_REMOTE_ROOT:-/opt/teleo-eval}" REMOTE_BACKUP_ROOT="${REMOTE_BACKUP_ROOT:-/opt/teleo-eval/backups}" LOCAL_BACKUP_DIR="${LOCAL_BACKUP_DIR:-./outputs/gcp-infra-hardening-20260707/private-backups}" PROOF_DIR="${PROOF_DIR:-./outputs/gcp-infra-hardening-20260707/proofs}" TS="${TS:-$(date -u +%Y%m%dT%H%M%SZ)}" SQLITE_REMOTE_DIR="${REMOTE_BACKUP_ROOT}/pipeline" SQLITE_BASE="teleo-pipeline-sqlite-${TS}" KB_REMOTE_DIR="${REMOTE_BACKUP_ROOT}/kb" KB_BASE="teleo-leo-kb-files-${TS}" ssh_base=( ssh -i "$TELEO_SSH_KEY" -o BatchMode=yes -o StrictHostKeyChecking=accept-new ) scp_base=( scp -i "$TELEO_SSH_KEY" -o BatchMode=yes -o StrictHostKeyChecking=accept-new ) sha256_file() { if command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | awk '{print $1}' else sha256sum "$1" | awk '{print $1}' fi } mkdir -p "$LOCAL_BACKUP_DIR" "$PROOF_DIR" chmod 700 "$LOCAL_BACKUP_DIR" "${ssh_base[@]}" "$TELEO_VPS_HOST" "set -euo pipefail mkdir -p '$SQLITE_REMOTE_DIR' '$KB_REMOTE_DIR' chmod 700 '$SQLITE_REMOTE_DIR' '$KB_REMOTE_DIR' sqlite3 '$TELEO_REMOTE_ROOT/pipeline/pipeline.db' \".backup '$SQLITE_REMOTE_DIR/${SQLITE_BASE}.db'\" gzip -f -9 '$SQLITE_REMOTE_DIR/${SQLITE_BASE}.db' sha256sum '$SQLITE_REMOTE_DIR/${SQLITE_BASE}.db.gz' > '$SQLITE_REMOTE_DIR/${SQLITE_BASE}.db.gz.sha256' cd '$TELEO_REMOTE_ROOT' tar --warning=no-file-changed --exclude='secrets' --exclude='*.log' --exclude='logs' -czf '$KB_REMOTE_DIR/${KB_BASE}.tar.gz' \\ workspaces/main/agents/leo \\ workspaces/research-leo/agents/leo \\ agent-state sha256sum '$KB_REMOTE_DIR/${KB_BASE}.tar.gz' > '$KB_REMOTE_DIR/${KB_BASE}.tar.gz.sha256' ls -lh '$SQLITE_REMOTE_DIR/${SQLITE_BASE}.db.gz' '$KB_REMOTE_DIR/${KB_BASE}.tar.gz' " > "$PROOF_DIR/vps-backup-create-${TS}.txt" "${scp_base[@]}" "$TELEO_VPS_HOST:${SQLITE_REMOTE_DIR}/${SQLITE_BASE}.db.gz" "$LOCAL_BACKUP_DIR/" "${scp_base[@]}" "$TELEO_VPS_HOST:${SQLITE_REMOTE_DIR}/${SQLITE_BASE}.db.gz.sha256" "$LOCAL_BACKUP_DIR/" "${scp_base[@]}" "$TELEO_VPS_HOST:${KB_REMOTE_DIR}/${KB_BASE}.tar.gz" "$LOCAL_BACKUP_DIR/" "${scp_base[@]}" "$TELEO_VPS_HOST:${KB_REMOTE_DIR}/${KB_BASE}.tar.gz.sha256" "$LOCAL_BACKUP_DIR/" chmod 600 \ "$LOCAL_BACKUP_DIR/${SQLITE_BASE}.db.gz" \ "$LOCAL_BACKUP_DIR/${SQLITE_BASE}.db.gz.sha256" \ "$LOCAL_BACKUP_DIR/${KB_BASE}.tar.gz" \ "$LOCAL_BACKUP_DIR/${KB_BASE}.tar.gz.sha256" sqlite_expected="$(awk '{print $1}' "$LOCAL_BACKUP_DIR/${SQLITE_BASE}.db.gz.sha256")" sqlite_actual="$(sha256_file "$LOCAL_BACKUP_DIR/${SQLITE_BASE}.db.gz")" kb_expected="$(awk '{print $1}' "$LOCAL_BACKUP_DIR/${KB_BASE}.tar.gz.sha256")" kb_actual="$(sha256_file "$LOCAL_BACKUP_DIR/${KB_BASE}.tar.gz")" test "$sqlite_expected" = "$sqlite_actual" test "$kb_expected" = "$kb_actual" tmpdir="$(mktemp -d)" trap 'rm -rf "$tmpdir"' EXIT gunzip -c "$LOCAL_BACKUP_DIR/${SQLITE_BASE}.db.gz" > "$tmpdir/pipeline.db" { echo "sqlite_backup=$LOCAL_BACKUP_DIR/${SQLITE_BASE}.db.gz" echo "sqlite_remote=$SQLITE_REMOTE_DIR/${SQLITE_BASE}.db.gz" echo "sqlite_backup_size_bytes=$(wc -c < "$LOCAL_BACKUP_DIR/${SQLITE_BASE}.db.gz" | tr -d ' ')" echo "sqlite_db_size_bytes=$(wc -c < "$tmpdir/pipeline.db" | tr -d ' ')" echo "sqlite_sha256=$sqlite_actual" echo "sqlite_sha256_matches_vps=true" echo "sqlite_integrity_check=$(sqlite3 "$tmpdir/pipeline.db" 'PRAGMA integrity_check;')" echo "sqlite_user_table_count=$(sqlite3 "$tmpdir/pipeline.db" "select count(*) from sqlite_master where type='table' and name not like 'sqlite_%';")" echo "kb_backup=$LOCAL_BACKUP_DIR/${KB_BASE}.tar.gz" echo "kb_remote=$KB_REMOTE_DIR/${KB_BASE}.tar.gz" echo "kb_backup_size_bytes=$(wc -c < "$LOCAL_BACKUP_DIR/${KB_BASE}.tar.gz" | tr -d ' ')" echo "kb_sha256=$kb_actual" echo "kb_sha256_matches_vps=true" echo "kb_file_count=$(tar -tzf "$LOCAL_BACKUP_DIR/${KB_BASE}.tar.gz" | wc -l | tr -d ' ')" } > "$PROOF_DIR/vps-sqlite-kb-backup-proof-${TS}.txt" cat "$PROOF_DIR/vps-sqlite-kb-backup-proof-${TS}.txt"