> Audiencia: yo (Pedro) o cualquier persona técnica que tenga que rearmar el sistema cuando yo no esté disponible. > Fuente canónica de este documento: github.com/holaslagelse/slagelse-ops/RECOVERY.md > Versión: 1.0 — 2026-05-09 > Mantener también copia impresa en lugar físico seguro.
| Término | Qué es |
|---|---|
| Mac Mini canónico | Máquina principal macmini-justine (Tailscale 100.68.196.112). Hosting: en casa de Pedro. |
| Time Machine | Backup local horario en SSD Corsair montado como /Volumes/TimeMachine. |
| Drive | Cuenta Google hola.slagelse@gmail.com. Archivo histórico contable + facturas. |
| GitHub | Repos privados slagelse-ops (código + docs) y cowork-skills (skills empaquetados). |
| Keychain | Almacén nativo macOS de secrets. 12 entries justine-* y beyondpricing.com. |
| 1Password | Gestor de secrets recomendado como mirror del Keychain (pendiente de implementar). |
| USB RK_01 | Disco USB de disaster recovery con bootstrap completo. Skill: justine-recovery-remoto. |
| Justine-Backup-*.zip | ZIPs diarios runtime crítico generados a las 03:30. Local en ~/Library/Justine/backups/. |
| Escenario | Síntoma | Ir a sección |
|---|---|---|
| A | Mac Mini físicamente roto / robado / nuevo hardware | §3 |
| B | Mac Mini vivo pero código corrupto, scripts borrados | §4 |
| C | Datos operativos perdidos (slagelse/data/ borrado o corrupto) | §5 |
| D | Sin acceso a Mac Mini, recuperar desde otra máquina (emergencia) | §6 |
| E | Backup probado mensual (no es recovery real, pero hay que hacerlo) | §7 |
73.pedro@gmail.com (para GitHub) y hola.slagelse@gmail.com (Drive).justine-backup-encryption key.100.68.196.112).1. Instalar última versión estable de macOS desde Apple. 2. Crear usuario agent (mismo nombre crítico para que paths sigan funcionando). 3. Instalar Xcode Command Line Tools:
``bash xcode-select --install ``
4. Instalar Homebrew:
``bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``
5. Instalar paquetes base:
``bash brew install python@3.12 git gh node tailscale gitleaks pre-commit rclone gnupg brew install --cask google-drive 1password ``
sudo tailscale up --authkey="$(security find-generic-password -s justine-tailscale-authkey -w)" --hostname=macmini-justine
Si no tienes el authkey: entrar en https://login.tailscale.com/admin/settings/keys con la cuenta del owner y generar uno nuevo.
Conectar SSD Corsair, abrir Migration Assistant (/Applications/Utilities/Migration Assistant.app) y elegir "From a Time Machine backup". Seleccionar el último snapshot.
Esto recupera:
~/Documents/Claude/ (todo el código + datos antes del fallo)~/Library/Justine/ (runtime + backups locales)~/Library/LaunchAgents/ (todas las plists, hay que limpiar las .disabled después)~/Library/Keychains/ (todos los secrets, incluido justine-backup-encryption)~/.skills/, ~/.claude/Smoke test post-restore:
ls -la ~/Documents/Claude/slagelse/scripts/ | head -5 # debe haber Python files
security find-generic-password -s justine-smoobu-api -w | head -c 10 # debe devolver token
mkdir -p ~/repos
cd ~/repos
gh auth login # autenticar con cuenta GitHub
git clone git@github.com:holaslagelse/slagelse-ops.git
git clone git@github.com:holaslagelse/cowork-skills.git
El código en GitHub es canónico. Si Time Machine restauró una versión más reciente que GitHub, hacer commit del diff:
diff -r ~/repos/slagelse-ops/ ~/Documents/Claude/slagelse/ | head -40
# Si hay diff legítimo, commit en slagelse-ops
~/repos/cowork-skills/tools/install_skills.sh
(Este script copia los .skill y descomprime en ~/.skills/skills/.)
~/repos/slagelse-ops/projects/recovery/install_launchd.sh
(Este script copia plists desde slagelse-ops/projects/<proyecto>/launchd/ a ~/Library/LaunchAgents/ y hace launchctl load.)
launchctl load ~/Library/LaunchAgents/com.justine.scheduler.plist
launchctl load ~/Library/LaunchAgents/com.justine.scheduler-watchdog.plist
launchctl list | grep justine
Confirmar que el daemon scheduler arranca y empieza a refrescar datos cada 30 min.
Abrir Google Drive desktop con cuenta hola.slagelse@gmail.com. Esperar a que sincronice. Verificar que los symlinks de ~/Documents/Claude/Slagelse (1) y ~/Documents/Claude/_inbox_facturas apuntan correctamente.
cd ~/repos/slagelse-ops
python3 projects/recovery/verify_recovery.py
Esperado: OK en cada check (Time Machine, Drive, GitHub, Keychain, scheduler, pipeline banking dry-run).
A las 06:00 del día siguiente debe llegar email diario a 73.pedro@gmail.com. Si no llega, revisar:
tail -100 ~/Documents/Claude/slagelse/logs/daily_email.log
cd ~/repos/slagelse-ops
git status
git checkout main
git pull --rebase
git reset --hard origin/main # solo si confirmas que descartas cambios locales
~/repos/slagelse-ops/projects/recovery/verify_recovery.py
Si el script Python específico está corrupto, hacer git checkout HEAD -- projects/banking/src/compute_bank_reconciliation.py.
Fuente más reciente: Time Machine.
tmutil latestbackup
# Restaurar carpeta data/ desde TM:
sudo rsync -aH /Volumes/.timemachine/<latest>/<path>/Documents/Claude/slagelse/data/ ~/Documents/Claude/slagelse/data/
Verificar:
python3 -c "import json; d = json.load(open('~/Documents/Claude/slagelse/data/guests_data.json')); print(len(d), 'reservations')"
Si Time Machine está corrupto, ir al ZIP diario:
unzip ~/Library/Justine/backups/Justine-Backup-2026-05-05_0330.zip -d /tmp/restore/
Opción 1: USB RK_01. Conectar el USB a cualquier Mac, seguir skill justine-recovery-remoto.
Opción 2: Cualquier Mac + GitHub + Drive + Keychain backup.
# En Mac prestado o nuevo:
git clone git@github.com:holaslagelse/slagelse-ops.git
git clone git@github.com:holaslagelse/cowork-skills.git
# Importar Keychain desde backup (1Password si existe)
# Conectar Drive cuenta hola.slagelse@gmail.com
Esto te da código + secrets + facturas/docs. Faltarían los datos operativos, que no son críticos para responder huéspedes pero sí para facturar correctamente. Para datos operativos, esperar a recuperar Mac Mini original o restaurar Time Machine en máquina nueva (escenario A).
Cada primer sábado del mes, ejecutar:
cd ~/repos/slagelse-ops
./projects/recovery/test_recovery.sh
Este script:
1. Crea un Mac virtual mínimo (o carpeta sandbox). 2. Restaura Time Machine en él. 3. Clona GitHub. 4. Importa Keychain. 5. Corre verify_recovery.py. 6. Genera informe recovery_test_<fecha>.md. 7. Envía email con resultado.
Si el test falla, hay que arreglarlo ANTES del próximo backup probado.
Estas son las 15 plists activas que documenta MANIFEST.json. Cada una vive en slagelse-ops/projects/<proyecto>/launchd/:
| Plist | Frecuencia | Proyecto | Función |
|---|---|---|---|
com.justine.scheduler | always | data-refresh | Daemon principal Justine |
com.justine.scheduler-watchdog | every 5 min | data-refresh | Watchdog del scheduler |
com.justine.refresh-server | hourly | server-agent | Refresh agente server |
com.justine.refresh-ota | hourly | data-refresh | Refresh OTA reservations |
com.justine.verify-ota | daily | data-refresh | Verificación OTA |
com.justine.audit-facturas-canonical | daily | invoicing | Auditoría facturas |
com.justine.sync-facturas-canonical | daily | invoicing | Sync facturas |
com.justine.sync-canonical-to-mirror | daily | invoicing | Mirror facturas a Drive |
com.justine.monitor-gbp-listings | daily | web-seo | Monitor Google Business Profile |
com.justine.weekly-gbp-post | weekly | web-seo | Post semanal GBP |
com.justine.python-health-daily | daily | ops | Health check Python |
com.justine.python-health-monthly | monthly | ops | Health check mensual |
com.slagelse.clasificar-facturas | daily | invoicing | Clasificar facturas |
com.slagelse.pull-drive-inbox | hourly | invoicing | Pull inbox Drive |
com.slagelse.sync-facturas-email | daily | invoicing | Sync facturas vía email |
Las plists con .disabled o .bak son obsoletas y NO deben re-instalarse.
egb@clearcorp.es), Cristina (cvg@clearcorp.es)https://www.dondominio.com/ con cuenta del titularhttps://login.tailscale.com/admin/hola.slagelse@gmail.com73.pedro@gmail.com (o el handle definitivo)Última revisión: 2026-05-09 — Pedro Próxima revisión obligatoria: 2026-11-09
| Quién | Para qué | Dónde |
|---|---|---|
| Clearcorp · Eva | contabilidad Slagelse SL | egb@clearcorp.es |
| Clearcorp · Cristina | fiscal Slagelse SL | cvg@clearcorp.es |
| DonDominio | hosting + DNS justineapartments.com | dondominio.com (login con cuenta titular) |
| Tailscale | admin VPN mesh | login.tailscale.com/admin/ |
| Google Drive admin | cuenta Drive operativa | hola.slagelse@gmail.com |
| GitHub | repos privados slagelse-ops / cowork-skills | holaslagelse (73.pedro@gmail.com) |
| Cloudflare | Pages kintsugi + recovery, D1, DNS | dash.cloudflare.com (cuenta titular) |