{ "schema_version": "backup_dr_target_inventory_v1", "generated_at": "2026-06-04T15:38:22+08:00", "source_refs": [ "docs/runbooks/BACKUP-STATUS.md", "docs/runbooks/OFFSITE-BACKUP-ESCROW-RUNBOOK.md", "scripts/backup/backup-all.sh", "scripts/backup/backup-status.sh", "scripts/backup/sync-offsite-backups.sh", "scripts/backup/verify-offsite-full-sync.sh", "scripts/backup/offsite-escrow-evidence-report.sh", "scripts/backup/mark-credential-escrow-verified.sh" ], "program_status": { "overall_completion_percent": 88, "current_priority": "P1", "current_task_id": "P1-101", "next_task_id": "P1-102", "read_only_mode": true }, "target_taxonomy": { "target_types": [ "database", "repository", "registry", "volume", "configuration", "route_evidence", "ai_artifact", "offsite_mirror", "credential_escrow", "k8s_resource", "status_check" ], "statuses": ["active", "partial", "blocked", "deferred"], "gate_statuses": [ "read_only_allowed", "backup_execution_blocked", "restore_approval_required", "offsite_sync_blocked", "credential_approval_required", "blocked_by_live_evidence", "deferred_until_service_active" ], "storage_classes": [ "restic_local", "restic_offsite", "file_export", "velero_minio", "evidence_marker", "read_only_metric" ] }, "rollups": { "total_targets": 17, "by_status": { "active": 14, "blocked": 2, "deferred": 1 }, "by_target_type": { "database": 5, "repository": 1, "registry": 1, "volume": 4, "configuration": 1, "route_evidence": 1, "ai_artifact": 1, "offsite_mirror": 1, "credential_escrow": 1, "k8s_resource": 1 }, "by_gate_status": { "backup_execution_blocked": 13, "offsite_sync_blocked": 1, "credential_approval_required": 1, "blocked_by_live_evidence": 1, "deferred_until_service_active": 1 }, "blocked_target_ids": [ "configs_capture", "credential_escrow_markers" ] }, "backup_targets": [ { "target_id": "gitea", "display_name": "Gitea DB + repository dump", "target_type": "repository", "status": "active", "risk_level": "critical", "owner_host": "110", "primary_script": "scripts/backup/backup-gitea.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/gitea", "offsite_policy": "sync-offsite-backups.sh 統一鏡像到 rclone remote;子腳本不直接 rclone sync。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "不輸出 Gitea app.ini secret;restore 前需人工批准。", "evidence_refs": ["scripts/backup/backup-gitea.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 讀取 freshness / integrity 指標,不直接觸發備份。" }, { "target_id": "momo_postgresql", "display_name": "MOMO PostgreSQL", "target_type": "database", "status": "active", "risk_level": "high", "owner_host": "110 pulls from 188", "primary_script": "scripts/backup/backup-momo.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/momo", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "PostgreSQL credential 保留在 188 momo-db container env;快照不得記錄 secret 值。", "evidence_refs": ["scripts/backup/backup-momo.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 對齊 freshness 與 last failure 指標。" }, { "target_id": "harbor", "display_name": "Harbor registry + DB", "target_type": "registry", "status": "active", "risk_level": "critical", "owner_host": "110", "primary_script": "scripts/backup/backup-harbor.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/harbor", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "harbor.yml 只進 encrypted restic;不在 API 顯示內容。", "evidence_refs": ["scripts/backup/backup-harbor.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 補 registry freshness / integrity surface。" }, { "target_id": "awoooi_postgresql_daily", "display_name": "AWOOOI PostgreSQL daily full", "target_type": "database", "status": "active", "risk_level": "critical", "owner_host": "110 pulls from 188", "primary_script": "scripts/backup/backup-awoooi.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h full backup", "storage_class": "restic_local", "storage_ref": "/backup/awoooi", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "舊腳本含 DB credential;新 API 只記 evidence ref,不複製 secret 值。", "evidence_refs": ["scripts/backup/backup-awoooi.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 對齊 awoooi_prod / awoooi_dev / k3s_datastore freshness。" }, { "target_id": "awoooi_postgresql_frequent", "display_name": "AWOOOI PostgreSQL frequent core", "target_type": "database", "status": "active", "risk_level": "critical", "owner_host": "110 pulls from 188", "primary_script": "scripts/backup/backup-awoooi-frequent.sh", "schedule": "08:00 / 14:00 / 20:00 或每 6 小時 cron", "rpo": "6h", "storage_class": "restic_local", "storage_ref": "/backup/awoooi", "offsite_policy": "由 offsite sync 按 repo 鏡像,不由高頻腳本直接上傳。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "舊腳本含 DB credential;不得把 secret 寫入治理快照或 API。", "evidence_refs": ["scripts/backup/backup-awoooi-frequent.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 6h RPO freshness。" }, { "target_id": "langfuse", "display_name": "Langfuse AI trace DB", "target_type": "database", "status": "active", "risk_level": "high", "owner_host": "110", "primary_script": "scripts/backup/backup-langfuse.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/langfuse", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "DB dump 只進 encrypted restic;API 不顯示 dump 內容。", "evidence_refs": ["scripts/backup/backup-langfuse.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 AI trace backup freshness。" }, { "target_id": "monitoring", "display_name": "Prometheus / Grafana / Alertmanager", "target_type": "volume", "status": "active", "risk_level": "high", "owner_host": "110", "primary_script": "scripts/backup/backup-monitoring.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/monitoring", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "Grafana / Alertmanager 設定只進 encrypted restic;不輸出 secret。", "evidence_refs": ["scripts/backup/backup-monitoring.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 對齊 monitoring repo freshness 與 alert rules visibility。" }, { "target_id": "signoz", "display_name": "SignOz ClickHouse + SQLite", "target_type": "volume", "status": "active", "risk_level": "high", "owner_host": "110", "primary_script": "scripts/backup/backup-signoz.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/signoz", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "腳本會短暫停 collector;Agent 不得任意觸發。", "evidence_refs": ["scripts/backup/backup-signoz.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 標出 service-disruptive backup 腳本,避免自動觸發。" }, { "target_id": "open_webui", "display_name": "Open-WebUI volume", "target_type": "volume", "status": "active", "risk_level": "medium", "owner_host": "110 pulls from 188", "primary_script": "scripts/backup/backup-open-webui.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/open-webui", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "volume 內容只進 encrypted restic。", "evidence_refs": ["scripts/backup/backup-open-webui.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 freshness 與 188 SSH reachability。" }, { "target_id": "clawbot_redis", "display_name": "ClawBot Redis volume", "target_type": "volume", "status": "active", "risk_level": "medium", "owner_host": "110 pulls from 188", "primary_script": "scripts/backup/backup-clawbot.sh", "schedule": "每日 02:00 via backup-all.sh", "rpo": "24h", "storage_class": "restic_local", "storage_ref": "/backup/clawbot", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "BGSAVE / volume export 不顯示 Redis payload。", "evidence_refs": ["scripts/backup/backup-clawbot.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 freshness 與 failure-only notification。" }, { "target_id": "configs_capture", "display_name": "Host / service / K8s configuration capture", "target_type": "configuration", "status": "blocked", "risk_level": "critical", "owner_host": "110 with SSH to 188 / 120 / 121 / 125", "primary_script": "scripts/backup/backup-configs.sh", "schedule": "納入 offsite expected repos;live status 顯示 120 target blocked", "rpo": "24h target but currently blocked by live evidence", "storage_class": "restic_local", "storage_ref": "/backup/configs", "offsite_policy": "rclone expected repo includes configs;config capture failure blocks full DR green。", "automation_gate_status": "blocked_by_live_evidence", "restore_gate_status": "restore_approval_required", "secret_policy": "Secret / ConfigMap 只進 encrypted restic;不得在 API 顯示內容。", "evidence_refs": ["scripts/backup/backup-configs.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 `120-k3s-host-configs` blocked status;不得自動重跑 restore。" }, { "target_id": "ai_artifacts", "display_name": "AI artifacts / Ollama manifests", "target_type": "ai_artifact", "status": "active", "risk_level": "medium", "owner_host": "110 pulls from 188", "primary_script": "scripts/backup/backup-ai-artifacts.sh", "schedule": "repo expected by offsite sync", "rpo": "24h evidence target", "storage_class": "restic_local", "storage_ref": "/backup/ai-artifacts", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "預設備份 manifests / Modelfile,不備份 large blobs;不輸出 secret。", "evidence_refs": ["scripts/backup/backup-ai-artifacts.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 manifest-only policy 與 freshness。" }, { "target_id": "public_routes", "display_name": "Public routes / DNS / TLS evidence", "target_type": "route_evidence", "status": "active", "risk_level": "high", "owner_host": "110 with public read-only probes", "primary_script": "scripts/backup/backup-public-routes.sh", "schedule": "repo expected by offsite sync", "rpo": "24h evidence target", "storage_class": "restic_local", "storage_ref": "/backup/public-routes", "offsite_policy": "sync-offsite-backups.sh 統一鏡像。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "不輸出 registrar / DNS provider token;TLS private keys 由 encrypted configs 備份處理。", "evidence_refs": ["scripts/backup/backup-public-routes.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 DNS / TLS evidence freshness。" }, { "target_id": "sentry", "display_name": "Sentry backup repo", "target_type": "volume", "status": "deferred", "risk_level": "medium", "owner_host": "110", "primary_script": "scripts/backup/backup-sentry.sh", "schedule": "deferred until service is active", "rpo": "not active", "storage_class": "restic_local", "storage_ref": "/backup/sentry", "offsite_policy": "included in offsite expected repos when local repo exists。", "automation_gate_status": "deferred_until_service_active", "restore_gate_status": "restore_approval_required", "secret_policy": "Sentry volume / env 不在 API 顯示。", "evidence_refs": ["scripts/backup/backup-sentry.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "服務重新啟動後再評估 freshness;目前不宣稱 active。" }, { "target_id": "offsite_rclone_full_sync", "display_name": "Google Drive / rclone offsite mirror", "target_type": "offsite_mirror", "status": "active", "risk_level": "critical", "owner_host": "110", "primary_script": "scripts/backup/sync-offsite-backups.sh", "schedule": "每日 03:00 sync;每日 07:20 verify", "rpo": "24h mirror target", "storage_class": "restic_offsite", "storage_ref": "gdrive:awoooi-backups/restic", "offsite_policy": "latest-only remote mirror;full sync 需 enable marker 與 resource preflight。", "automation_gate_status": "offsite_sync_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "不讀、不輸出 rclone token 或 provider credential。", "evidence_refs": ["scripts/backup/sync-offsite-backups.sh", "scripts/backup/verify-offsite-full-sync.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 offsite marker freshness 與 remote latest-only verify。" }, { "target_id": "credential_escrow_markers", "display_name": "Credential escrow evidence markers", "target_type": "credential_escrow", "status": "blocked", "risk_level": "critical", "owner_host": "110 + external human vault", "primary_script": "scripts/backup/mark-credential-escrow-verified.sh", "schedule": "人工審查後寫非 secret marker", "rpo": "manual review cadence", "storage_class": "evidence_marker", "storage_ref": "/backup/escrow-evidence/*.last_verified", "offsite_policy": "marker 只記非 secret evidence id;credential 本體不進 repo / API。", "automation_gate_status": "credential_approval_required", "restore_gate_status": "restore_approval_required", "secret_policy": "禁止 secret、URL、token、password 寫入 marker;只接受短 evidence id。", "evidence_refs": ["scripts/backup/mark-credential-escrow-verified.sh", "scripts/backup/offsite-escrow-evidence-report.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-105 起草人工 escrow review 批准包;目前 5/5 marker missing。" }, { "target_id": "velero_k8s_resources", "display_name": "Velero K8s resource snapshots", "target_type": "k8s_resource", "status": "active", "risk_level": "critical", "owner_host": "188 K8s / MinIO", "primary_script": "k8s/awoooi-prod/16-cronjob-backup-restore-test.yaml", "schedule": "每日 02:00 Velero / restore test path", "rpo": "24h", "storage_class": "velero_minio", "storage_ref": "MinIO bucket: velero", "offsite_policy": "MinIO 是備份的備份;仍需獨立 offsite 評估。", "automation_gate_status": "backup_execution_blocked", "restore_gate_status": "restore_approval_required", "secret_policy": "K8s Secret restore / readback 需人工批准;API 不顯示 Secret payload。", "evidence_refs": ["docs/runbooks/BACKUP-STATUS.md", "k8s/awoooi-prod/16-cronjob-backup-restore-test.yaml"], "next_action": "P1-102 顯示 Velero freshness;P1-105 才處理 restore drill 批准包。" } ], "readiness_surfaces": [ { "surface_id": "backup_status_daily_summary", "display_name": "每日備份心跳摘要", "script_or_metric": "scripts/backup/backup-status.sh", "mode": "read_only", "status": "active", "evidence_refs": ["scripts/backup/backup-status.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 將 freshness / integrity / restore drill 指標轉成準備度矩陣。" }, { "surface_id": "offsite_full_verify", "display_name": "Offsite latest-only 驗證", "script_or_metric": "scripts/backup/verify-offsite-full-sync.sh --write-textfile", "mode": "read_only", "status": "active", "evidence_refs": ["scripts/backup/verify-offsite-full-sync.sh", "docs/runbooks/BACKUP-STATUS.md"], "next_action": "P1-102 顯示 remote snapshots=1 與 verifier freshness。" }, { "surface_id": "escrow_evidence_report", "display_name": "Offsite / credential escrow evidence report", "script_or_metric": "scripts/backup/offsite-escrow-evidence-report.sh", "mode": "read_only", "status": "blocked", "evidence_refs": ["scripts/backup/offsite-escrow-evidence-report.sh", "scripts/backup/mark-credential-escrow-verified.sh"], "next_action": "P1-105 產出人工 escrow review 批准包;不得自動寫 marker。" } ], "operation_boundaries": { "read_only_api_allowed": true, "backup_execution_allowed": false, "restore_execution_allowed": false, "offsite_sync_execution_allowed": false, "credential_marker_write_allowed": false, "schedule_change_allowed": false, "destructive_prune_allowed": false }, "approval_boundaries": { "sdk_installation_allowed": false, "paid_api_call_allowed": false, "shadow_or_canary_allowed": false, "production_routing_allowed": false, "destructive_operation_allowed": false } }