La semana pasada borré mi base de datos de producción. Mi instancia de trabajo [Neotoma](https://neotoma.io) pasó de 6174 observaciones y 3862 entidades a 84 observaciones y 67 entidades en un comando. Meses de contactos, tareas, conversaciones, notas de comentarios, transacciones y reglas vigentes: se acabaron.

Lo recuperé. La base de datos final tiene 6.296 observaciones y 3.951 entidades que abarcan cinco semanas de actividad. La recuperación duró aproximadamente una hora. Esta publicación trata sobre cómo sucedió, por qué fue posible la recuperación y qué reveló la experiencia sobre la construcción de un sistema de memoria en el que realmente pueda confiar.

## ¿Qué pasó?

Estaba trabajando en Neotoma CLI, probando un flujo de trabajo de desarrollo. Ejecuté una secuencia de comandos que restablecieron el estado de la base de datos y la reinicializaron. La intención era borrar los datos de prueba de un entorno de desarrollo. El objetivo era la base de datos de producción.

El error fue mundano. Ejecuté `neotoma reset` mientras `NEOTOMA_ENV` estaba configurado en producción. Pensé que estaba apuntando a desarrolladores. Cuando me di cuenta, la base de datos activa tenía 84 observaciones nuevas del proceso de reinicialización y nada más.

## Encontrar las copias de seguridad

Lo primero que hice fue buscar todos los archivos Neotoma SQLite en mi máquina. Encontré diez copias dispersas en directorios de respaldo, carpetas de datos y artefactos de recuperación con marca de tiempo de un incidente anterior a principios de marzo.

| Archivo fuente | Observaciones | Entidades | Última actividad |
|---|---|---|---|
| `neotoma.prod.db.db` | 6.174 | 3.862 | 9 de marzo |
| `neotoma.prod 2.db` | 4.406 | 3.073 | 10 de marzo |
| Objetivo en vivo (después de la limpieza) | 84 | 67 | 11 de marzo |
| `neotoma.prod.db.recuperado-*` | 4.381 | 3.059 | 3 de marzo |
| `copias de seguridad de datos/copia de datos/` | 4.158 | 2.955 | 2 de marzo |
| Varias copias antiguas | 3.100 a 3.931 | 2.558 a 2.806 | 17 de febrero al 27 de febrero |

Las copias de seguridad existían porque había estado copiando manualmente el archivo de la base de datos a intervalos irregulares. No es un sistema de respaldo formal, solo comandos `cp` ocasionales cuando lo recordaba o me sentía nervioso. Una de esas copias, `neotoma.prod.db.db`, ​​contenía casi todo hasta el 9 de marzo. Una segunda copia, `neotoma.prod 2.db`, ​​tenía datos hasta el 10 de marzo que la primera copia omitió.

Entre estos dos archivos y las 84 observaciones supervivientes en la base de datos en vivo, tenía suficiente material para reconstruir la línea de tiempo completa.

## Cómo funcionó la fusión

Neotoma tiene un comando incorporado `merge-db` para combinar bases de datos SQLite. El proceso:

1. Haga una copia de seguridad de todos los archivos involucrados (tanto de origen como de destino) en un directorio con marca de tiempo. Ningún intento de recuperación debería poner en riesgo los originales.
2. Detenga el servidor Neotoma en ejecución para evitar escrituras simultáneas.
3. Ejecute en seco la combinación para ver qué conflictos existen.
4. Ejecute la combinación con `--mode keep-target`, que inserta filas del origen que faltan en el destino y conserva la versión del destino de cualquier fila que compartan ambas bases de datos.
5. Repita para la segunda fuente.
6. Verificar los recuentos de observaciones y entidades.
7. Reinicie el servidor.

La fusión principal aportó 6.174 observaciones de la copia de seguridad más grande. La fusión secundaria agregó aproximadamente 100 más desde la ventana del 10 de marzo. El recuento final: 6.296 observaciones, 3.951 entidades, actividad que abarca del 9 de febrero al 11 de marzo.

Después del reinicio, tomé muestras de entidades a través de Neotoma MCP para confirmar que todo era accesible. Contactos, tareas, conversaciones, registros de comentarios: todo presente y correctamente estructurado.

## Por qué fue posible esta recuperación

La recuperación funcionó gracias a tres propiedades de la arquitectura de Neotoma.

**Las observaciones son la fuente de la verdad.** Neotoma no almacena entidades sobrescribiendo una fila cuando algo cambia. Cada dato ingresa al sistema como una observación inmutable: "El correo electrónico de Alice es alice@example.com, observado el 3 de marzo desde Gmail". El estado de la entidad se calcula a partir del conjunto completo de observaciones. El registro de observación es sólo para anexar.

Esto significa que una copia de seguridad de la base de datos es una instantánea completa de cada hecho que el sistema haya visto alguna vez, no solo el estado más reciente. Cuando fusioné la copia de seguridad con la base de datos activa, no estaba restaurando "el último estado conocido de cada entidad". Estaba repitiendo la historia completa.

**Las instantáneas de las entidades son derivadas, no primarias.** Después de fusionar las observaciones, Neotoma vuelve a calcular las instantáneas de las entidades a partir del registro de observaciones. La instantánea de cada entidad es determinista: dadas las mismas observaciones, siempre se obtiene el mismo estado de entidad. Es por eso que el comando de combinación incluye un paso de recálculo de instantáneas. Una vez realizadas las observaciones, las entidades se reconstruyen correctamente.

**Fusión de clave principal con detección de conflictos.** El comando `merge-db` recorre cada tabla, inserta filas que existen en el origen pero no en el destino y maneja los conflictos por clave principal. En el modo "mantener objetivo", la versión del objetivo gana en cualquier colisión. El modo de ejecución en seco previsualiza exactamente lo que se insertará y lo que entrará en conflicto antes de confirmar. Realicé simulacros para ambas fusiones y revisé los informes de conflictos antes de ejecutarlas.

Estas tres propiedades juntas hacen que la base de datos se recupere automáticamente de una manera que no lo hacen las copias de seguridad tradicionales a nivel de fila. No necesita preocuparse por qué copia de seguridad tiene "la versión correcta" de una entidad. Fusionas las observaciones, vuelves a calcular y aparece el estado correcto.

## Lo que aprendí

La experiencia reforzó algunas cosas.

**Las copias de seguridad informales son mejores que ninguna copia de seguridad.** Mi hábito de copiar ocasionalmente el archivo de la base de datos me ahorró meses de trabajo. Pero las copias manuales ocasionales no son un sistema. Dejan huecos. Si hubiera borrado la base de datos el 7 de marzo en lugar del 11 de marzo, habría perdido datos desde el 28 de febrero hasta el 7 de marzo porque ninguna copia cubría esa ventana por completo. Ahora estoy configurando copias de seguridad diarias automatizadas con Time Machine en mi Mac.

**El error del indicador env es un clásico.** Cada sistema que opera en entornos de desarrollo y producción conlleva este riesgo. La mitigación son mensajes de confirmación para operaciones destructivas, mensajes de terminal codificados por colores o credenciales separadas por entorno. Después de este incidente, agregué una confirmación forzada a "neotoma reset" cada vez que detecta un entorno de producción. El indicador `-y` se ignora para la producción. Verá "Restablecimiento de Neotoma (PRODUCCIÓN)" y una advertencia antes de que suceda algo.

**La arquitectura basada en eventos da sus frutos en la recuperación.** Si Neotoma almacenara entidades sobrescribiendo filas en su lugar, un borrado de la base de datos sería un evento de pérdida de datos sin una ruta de recuperación limpia. Debido a que las observaciones son inmutables y se deriva el estado de la entidad, la recuperación es una operación de fusión y recalculo. El registro de observación es la verdad fundamental. Todo lo demás se puede reconstruir a partir de él.

**Probé las herramientas que estaba creando.** Escribí el comando `merge-db` hace meses para un caso de uso diferente: combinar datos de usuarios que ejecutan múltiples instancias de Neotoma. Nunca esperé usarlo en mis propios datos de producción. Pero debido a que la herramienta existía y manejaba la resolución de conflictos y el recálculo de instantáneas, la recuperación fue mecánica más que estresante.

## Tus datos deberían sobrevivir a tus errores

Este incidente expuso brechas que Neotoma debería cerrar para que los usuarios nunca tengan que hacer lo que yo hice manualmente.

**Instantáneas automáticas.** Neotoma debe tomar instantáneas de la base de datos según un cronograma y antes de cualquier operación destructiva. Un conjunto rotativo de copias con marca de tiempo, retenidas durante 30 días. Si ejecuta un reinicio en el producto por error, la instantánea previa al reinicio está ahí. La recuperación no debería depender de si se acordó de ejecutar "cp" esa semana.

**Detección de anomalías.** Una caída repentina de miles de observaciones a casi cero no es normal. Neotoma podría detectar este patrón y confirmarlo antes de comprometerse. Una simple heurística, "esta operación eliminaría más del 90% de las observaciones, ¿confirma?" habría impedido mi limpieza por completo.

**Recuperación impulsada por agentes.** Dado que los agentes son la experiencia de usuario principal de Neotoma, la recuperación también debería funcionar a través de agentes. Le dice a su agente "mi base de datos se ve mal, creo que perdí datos". El agente verifica los recuentos de observaciones, encuentra instantáneas disponibles, compara rangos de fechas y lo guía a través de la fusión a través del MCP. No se requiere espeleología CLI.

**Sincronización remota.** Las copias de seguridad locales protegen contra sobrescrituras accidentales, pero no contra fallas del disco. Neotoma debería admitir la sincronización del registro de observación con una ubicación remota: un depósito en la nube, una segunda máquina o un servidor autohospedado. Debido a que las observaciones se pueden agregar únicamente, el modelo de sincronización es simple. Envíe nuevas observaciones al control remoto. Reconstruya el estado de la entidad en ambos extremos.

La misma arquitectura que hizo posible esta recuperación hace que estas características sean fáciles de construir. Las observaciones de solo agregar, el estado derivado y el recálculo determinista no son solo propiedades de recuperación. Son la base para la copia de seguridad, la sincronización y la autorreparación como garantías de primera clase.

## Los números

| Métrica | Antes de limpiar | Después de limpiar | Después de la recuperación |
|---|---|---|---|
| Observaciones | 6.174 | 84 | 6.296 |
| Entidades | 3.862 | 67 | 3.951 |
| Rango de fechas | 9 de febrero al 9 de marzo | 10 de marzo al 11 de marzo | 9 de febrero al 11 de marzo |

El recuento final es mayor que el recuento previo a la eliminación porque la combinación combinó observaciones de las tres fuentes: los dos archivos de respaldo y los datos supervivientes posteriores a la eliminación. Algunas observaciones que existían sólo en la copia de seguridad del 10 de marzo o sólo en la base de datos en vivo no estaban en la copia de seguridad más grande original.

Si su sistema de memoria utiliza un estado mutable, el borrado es permanente. Si utiliza un registro de observación de solo agregar con estado de entidad derivado, un borrado está a una distancia de la recuperación completa. Esa diferencia es importante cuando los datos son sus contactos, sus compromisos, su historial con agentes a lo largo de cientos de sesiones.

Neotoma es [código abierto en GitHub](https://github.com/neotoma-app/neotoma). Si desea una capa de memoria donde sus datos puedan sobrevivir a sus peores errores, [pruébelo](https://neotoma.io/install).