Na semana passada limpei meu banco de dados de produção. Minha instância de trabalho [Neotoma](https://neotoma.io) passou de 6.174 observações e 3.862 entidades para 84 observações e 67 entidades em um comando. Meses de contatos, tarefas, conversas, notas de feedback, transações e regras permanentes: acabaram.

Eu o recuperei. A base de dados final tem 6.296 observações e 3.951 entidades abrangendo cinco semanas de atividade. A recuperação demorou cerca de uma hora. Esta postagem é sobre como isso aconteceu, por que a recuperação foi possível e o que a experiência revelou sobre a construção de um sistema de memória em que você pode realmente confiar.

## O que aconteceu

Eu estava trabalhando na CLI do Neotoma, testando um fluxo de trabalho de desenvolvimento. Executei uma sequência de comandos que redefiniram o estado do banco de dados e o reinicializei. A intenção era limpar os dados de teste de um ambiente de desenvolvimento. O alvo era o banco de dados de produção.

O erro foi mundano. Executei `neotoma reset` enquanto `NEOTOMA_ENV` estava configurado para produção. Achei que estava visando o desenvolvedor. Quando percebi, o banco de dados ativo tinha 84 observações recentes do processo de reinicialização e nada mais.

## Encontrando os backups

A primeira coisa que fiz foi procurar todos os arquivos Neotoma SQLite em minha máquina. Encontrei dez cópias espalhadas em diretórios de backup, pastas de dados e artefatos de recuperação com carimbo de data e hora de uma situação anterior no início de março.

| Arquivo fonte | Observações | Entidades | Última atividade |
|---|---|---|---|
| `neotoma.prod.db.db` | 6.174 | 3.862 | 9 de março |
| `neotoma.prod 2.db` | 4.406 | 3.073 | 10 de março |
| Alvo ativo (pós-limpeza) | 84 | 67 | 11 de março |
| `neotoma.prod.db.recovered-*` | 4.381 | 3.059 | 3 de março |
| `backups de dados/cópia de dados/` | 4.158 | 2.955 | 2 de março |
| Várias cópias mais antigas | 3.100 a 3.931 | 2.558 a 2.806 | 17 de fevereiro a 27 de fevereiro |

As cópias de backup existiam porque eu copiava manualmente o arquivo do banco de dados em intervalos irregulares. Não é um sistema de backup formal, apenas comandos `cp` ocasionais quando eu me lembro ou fico nervoso. Uma dessas cópias, `neotoma.prod.db.db`, ​​continha quase tudo até 9 de março. Uma segunda cópia, `neotoma.prod 2.db`, ​​continha dados até 10 de março que a primeira cópia perdeu.

Entre esses dois arquivos e as 84 observações sobreviventes no banco de dados ao vivo, eu tinha material suficiente para reconstruir a linha do tempo completa.

## Como funcionou a mesclagem

Neotoma possui um comando `merge-db` integrado para combinar bancos de dados SQLite. O processo:

1. Faça backup de todos os arquivos envolvidos (de origem e de destino) em um diretório com carimbo de data/hora. Nenhuma tentativa de recuperação deve arriscar os originais.
2. Pare o servidor Neotoma em execução para evitar gravações simultâneas.
3. Faça uma simulação da mesclagem para ver quais conflitos existem.
4. Execute a mesclagem com `--mode keep-target`, que insere linhas da fonte que estão faltando no destino e preserva a versão do destino de qualquer linha compartilhada por ambos os bancos de dados.
5. Repita para a segunda fonte.
6. Verifique as contagens de observações e entidades.
7. Reinicie o servidor.

A fusão primária trouxe 6.174 observações do maior backup. A fusão secundária adicionou cerca de 100 a mais na janela de 10 de março. A contagem final: 6.296 observações, 3.951 entidades, atividade que vai de 9 de fevereiro a 11 de março.

Após a reinicialização, fiz uma amostragem de entidades por meio do Neotoma MCP para confirmar que tudo estava acessível. Contatos, tarefas, conversas, registros de feedback: todos presentes e corretamente estruturados.

## Por que essa recuperação foi possível

A recuperação funcionou por causa de três propriedades da arquitetura de Neotoma.

**As observações são a fonte da verdade.** Neotoma não armazena entidades substituindo uma linha quando algo muda. Cada fato entra no sistema como uma observação imutável: “O e-mail de Alice é alice@example.com, observado em 3 de março no Gmail”. O estado da entidade é calculado a partir do conjunto completo de observações. O log de observação é apenas anexado.

Isso significa que um backup de banco de dados é um instantâneo completo de todos os fatos que o sistema já viu, não apenas do estado mais recente. Quando mesclei o backup no banco de dados ativo, não estava restaurando "o último estado conhecido de cada entidade". Eu estava repetindo a história completa.

**Os instantâneos de entidade são derivados, não primários.** Após mesclar as observações, o Neotoma recalcula os instantâneos de entidade a partir do log de observação. O instantâneo de cada entidade é determinístico: dadas as mesmas observações, você sempre obtém o mesmo estado da entidade. É por isso que o comando merge inclui uma etapa de recomputação de instantâneo. Uma vez implementadas as observações, as entidades se reconstroem corretamente.

**Mesclagem de chave primária com detecção de conflitos.** O comando `merge-db` percorre todas as tabelas, insere linhas que existem na origem, mas não no destino, e trata conflitos por chave primária. No modo `keep-target`, a versão do alvo vence em qualquer colisão. O modo de simulação visualiza exatamente o que será inserido e o que entrará em conflito antes de você confirmar. Fiz testes para ambas as fusões e revisei os relatórios de conflito antes de executar.

Essas três propriedades juntas fazem com que o banco de dados se auto-recupere de uma forma que os backups tradicionais em nível de linha não conseguem. Você não precisa se preocupar com qual backup possui “a versão correta” de uma entidade. Você mescla as observações, recalcula e o estado correto aparece.

## O que aprendi

A experiência reforçou algumas coisas.

**Backups informais são melhores do que nenhum backup.** Meu hábito de copiar ocasionalmente o arquivo de banco de dados economizou meses de trabalho. Mas cópias manuais ocasionais não são um sistema. Eles deixam lacunas. Se eu tivesse apagado o banco de dados em 7 de março em vez de 11 de março, teria perdido dados de 28 de fevereiro a 7 de março porque nenhuma cópia cobria completamente aquela janela. Agora estou configurando backups diários automatizados com o Time Machine no meu Mac.

**O erro do sinalizador env é um clássico.** Todo sistema que opera em ambientes de desenvolvimento e produção apresenta esse risco. A mitigação consiste em prompts de confirmação para operações destrutivas, prompts de terminal codificados por cores ou credenciais separadas por ambiente. Após este incidente adicionei uma confirmação forçada ao `neotoma reset` sempre que detecta um ambiente de produção. O sinalizador `-y` é ignorado para prod. Você verá “Neotoma reset (PRODUÇÃO)” e um aviso antes que algo aconteça.

**A arquitetura baseada em eventos compensa na recuperação.** Se o Neotoma armazenasse entidades substituindo linhas no local, uma limpeza do banco de dados seria um evento de perda de dados sem um caminho de recuperação limpo. Como as observações são imutáveis ​​e o estado da entidade é derivado, a recuperação é uma operação de mesclagem e recálculo. O registro de observação é a verdade básica. Todo o resto pode ser reconstruído a partir dele.

**Testei as ferramentas que estava construindo.** Escrevi o comando `merge-db` meses atrás para um caso de uso diferente: combinar dados de usuários executando múltiplas instâncias do Neotoma. Nunca esperei usá-lo em meus próprios dados de produção. Mas como a ferramenta existia e cuidava da resolução de conflitos e do recálculo de instantâneos, a recuperação era mecânica e não estressante.

## Seus dados devem sobreviver aos seus erros

Este incidente expôs lacunas que o Neotoma deveria fechar para que os usuários nunca tivessem que fazer o que eu fiz manualmente.

**Snapshots automáticos.** Neotoma deve fazer snapshots do banco de dados de acordo com um cronograma e antes de qualquer operação destrutiva. Um conjunto rotativo de cópias com carimbo de data/hora, retidas por 30 dias. Se você executar uma redefinição no prod por engano, o instantâneo de pré-redefinição estará ali. A recuperação não deve depender de você ter lembrado de executar o `cp` naquela semana.

**Detecção de anomalias.** Uma queda repentina de milhares de observações para quase zero não é normal. Neotoma poderia detectar esse padrão e confirmar antes de cometer. Uma heurística simples, “esta operação removeria mais de 90% das observações, confirma?” teria evitado totalmente minha limpeza.

**Recuperação orientada por agente.** Como os agentes são a UX principal do Neotoma, a recuperação também deve funcionar por meio de agentes. Você diz ao seu agente "meu banco de dados parece errado, acho que perdi dados". O agente verifica as contagens de observações, encontra instantâneos disponíveis, compara intervalos de datas e orienta você na mesclagem por meio do MCP. Não é necessária espeleologia CLI.

**Sincronização remota.** Os backups locais protegem contra substituições acidentais, mas não contra falhas de disco. O Neotoma deve suportar a sincronização do log de observação com um local remoto: um balde de nuvem, uma segunda máquina ou um servidor auto-hospedado. Como as observações são apenas anexadas, o modelo de sincronização é simples. Envie novas observações para o controle remoto. Reconstrua o estado da entidade em cada extremidade.

A mesma arquitetura que tornou possível essa recuperação torna a construção desses recursos simples. Observações somente anexadas, estado derivado e recálculo determinístico não são apenas propriedades de recuperação. Eles são a base para backup, sincronização e autocorreção como garantias de primeira classe.

## Os números

| Métrica | Antes de limpar | Depois de limpar | Após recuperação |
|---|---|---|---|
| Observações | 6.174 | 84 | 6.296 |
| Entidades | 3.862 | 67 | 3.951 |
| Intervalo de datas | 9 de fevereiro a 9 de março | 10 de março a 11 de março | 9 de fevereiro a 11 de março |

A contagem final é maior do que a contagem pré-apagamento porque a mesclagem combinou observações de todas as três fontes: os dois arquivos de backup e os dados sobreviventes pós-apagamento. Algumas observações que existiam apenas no backup de 10 de março ou apenas no banco de dados ativo não estavam no maior backup original.

Se o seu sistema de memória usar estado mutável, uma limpeza será permanente. Se ele usar um log de observação somente anexado com estado de entidade derivado, uma limpeza será uma mesclagem da recuperação completa. Essa diferença é importante quando os dados são seus contatos, seus compromissos, seu histórico com agentes em centenas de sessões.

Neotoma é [código aberto no GitHub](https://github.com/neotoma-app/neotoma). Se você deseja uma camada de memória onde seus dados possam sobreviver aos piores erros, [experimente](https://neotoma.io/install).