← Todos os textos

A aplicação não precisa ser a casa dos dados

Uma hipótese para trocar de aplicativo sem reconstruir os dados, suas relações e as regras que permitem usá-los.

Imagine uma reforma acompanhada por um aplicativo. Ali estão os fornecedores, os orçamentos e as tarefas, cada uma ligada aos documentos correspondentes. Depois de algumas semanas, surge a necessidade de montar um cronograma. Outro aplicativo oferece uma visão melhor, mas usá-lo exige levar esse material junto.

Uma exportação pode entregar os valores de cada campo e perder os vínculos entre tarefas e documentos. Talvez seja preciso refazer relações à mão ou descobrir como o novo aplicativo interpreta os estados do anterior. A mudança de interface acaba exigindo uma migração.

Reunir telas, regras e armazenamento num produto tem vantagens: a equipe consegue desenvolver e distribuir o conjunto. Para o usuário, porém, essa organização pode tornar difícil trocar uma parte sem reconstruir as outras.

Se agentes de IA reduzirem o custo de criar ferramentas para tarefas específicas, esse problema pode ficar mais frequente. Uma interface feita para organizar orçamentos pode deixar de servir quando o trabalho passa a ser acompanhar prazos. Os dados da reforma continuam necessários.

Uma camada de dados do usuário

A hipótese que estou investigando é manter esses dados num ambiente independente dos aplicativos. O editor, o cronograma e uma ferramenta de linha de comando se conectariam a ele como clientes. Cada um ofereceria uma forma de trabalhar sobre os mesmos objetos.

Nesse desenho, o usuário escolheria quais clientes podem acessar o ambiente, concederia ou revogaria permissões e poderia exportar os objetos com os contratos necessários para usá-los. É nesse sentido técnico que falo em controle dos dados, sem entrar na questão jurídica de sua propriedade.

Editor ──────┐
Cronograma ──┼── API / runtime ── Ambiente de dados do usuário
CLI ─────────┘                    ├── objetos e relações
                                  ├── schemas e contratos versionados
                                  ├── identidade e permissões
                                  ├── registro operacional mínimo
                                  └── exportação e restauração

O runtime seria o serviço responsável por validar e executar as operações. Os aplicativos manteriam seu código de apresentação, suas consultas e integrações. As regras necessárias para interpretar e modificar os objetos ficariam no ambiente compartilhado, fora do código privado de cada cliente.

Esse ambiente poderia reunir componentes locais, cada um com seu schema e seus limites de acesso. Os objetos de referência, que chamo de canônicos, e seus contratos precisariam continuar disponíveis quando uma interface fosse removida.

Guardar os valores não preserva as regras

No domínio sintético proposto para o experimento, uma tarefa só pode ser concluída depois que todas as notas vinculadas a ela tiverem sido revisadas. O comando complete_task precisa verificar essa condição antes de mudar o estado para done.

Num banco compartilhado sem mediação, a regra poderia existir apenas no botão de concluir do aplicativo A. Um aplicativo B que escrevesse state = done diretamente conseguiria ignorá-la. Na proposta, os clientes solicitam comandos pela API, e o runtime executa a regra declarada no contrato, versionado junto ao schema.

A troca de cliente também precisa preservar a identidade dos objetos. Uma tarefa deve manter seu identificador, e as notas ligadas a ela precisam continuar apontando para a mesma tarefa. B precisa conhecer as operações disponíveis e as condições para executá-las, além de receber sua própria autorização de acesso.

O mesmo vale para exportação e restauração. Um pacote com os valores, mas sem relações, anexos e contratos necessários, pode servir como arquivo de consulta. Para continuar o trabalho em outro ambiente, é preciso preservar também essas dependências.

Retomar o trabalho de um agente seria uma exigência adicional. Se ele parar no meio da organização de documentos, outro agente talvez precise conhecer os comandos já tentados, os erros e os pontos de retomada. Isso pertence a uma camada de execução e fica fora do primeiro experimento. Guardar objetos e continuar uma atividade interrompida são problemas relacionados, com garantias diferentes.

O sentido de aplicação efêmera

Uso “efêmera” para falar de uma aplicação que pode ser substituída, mesmo que tenha sido usada e mantida por anos. Aqui, aplicação é o cliente e seu código privado. O runtime e os contratos compartilhados continuam no ambiente quando esse cliente é removido.

A condição que quero testar é esta: depois de revogar as permissões de A e removê-lo, B consegue encontrar os objetos e continuar as operações previstas pelos contratos, com uma autorização própria. Os dados e as regras permanecem; a permissão revogada de A não pode continuar valendo na API.

Revogar e desinstalar são ações separadas. A revogação também não apaga cópias que A já tenha obtido.

A dependência de software continua existindo. B precisa de um runtime e de um interpretador compatíveis com os contratos. Eles devem poder ser instalados e versionados sem o código privado de A. Se só A souber executar uma regra necessária, conservar sua descrição num arquivo não terá resolvido a dependência.

Quem pode alterar os dados

Um agente poderia consultar os objetos aos quais tem acesso, sugerir um schema ou montar uma interface. A permissão para executar uma operação viria de uma concessão do usuário, verificada pelo runtime. Gerar o código de uma tela não daria ao agente acesso aos dados que ela pretende mostrar.

As capabilities do desenho são permissões limitadas por recurso e operação. Um cliente poderia receber autorização para ler tarefas sem poder concluí-las. O runtime verificaria a concessão e as regras do contrato antes de executar o comando. O cliente não poderia ampliar suas próprias permissões nem apagar os registros protegidos pela política de acesso.

Há um limite de segurança importante: o primeiro experimento prevê clientes que usam a API publicada, mesmo que contenham bugs. Não pretende proteger os arquivos do ambiente contra um processo malicioso executado sob a mesma conta do sistema operacional.

O registro operacional também tem um alcance restrito. Ele registra a admissão das chamadas, não comprova que cada alteração foi confirmada no banco e pode ficar incompleto durante uma falha. Para verificar o desfecho de uma operação, o experimento precisa conferir a resposta e o estado persistido. Ações externas exigiriam outra verificação: escrever status = enviado não comprova o envio de um documento. Elas ficam fora do escopo inicial.

Referências para o desenho

O Solid é uma referência próxima: separa os aplicativos dos espaços de dados pessoais e permite controlar o acesso a esses dados. A proposta de software local-first trata da longevidade e do controle dos dados sem abrir mão da colaboração. Já o ensaio sobre malleable software discute como as pessoas podem adaptar suas ferramentas durante o uso.

A documentação do DBOS mostra outra parte do problema: como persistir checkpoints de workflows em Postgres para retomá-los depois de falhas. Essa referência ajuda a pensar na continuidade da execução, uma garantia diferente da troca de cliente avaliada aqui.

A pesquisa usa essas referências para formular um teste de substituição com contratos explícitos. Elas orientam o desenho, mas não são evidência de que a combinação proposta funcione.

O primeiro teste

O protótipo e os experimentos ainda estão por fazer. O plano começa com um ambiente local e dados sintéticos de tarefas e notas, sem sincronização entre dispositivos ou colaboração entre usuários. A sequência básica é:

  1. A cria tarefas e notas relacionadas.
  2. O usuário revoga as permissões de A; chamadas posteriores com essas permissões devem ser negadas.
  3. A é removido, incluindo seu código privado.
  4. B recebe uma concessão própria e descobre os objetos e contratos.
  5. B continua uma operação autorizada, respeitando a regra de revisão das notas.
  6. O ambiente é exportado e restaurado em outro diretório, onde os objetos e as operações são verificados novamente.

Os clientes desse primeiro teste serão determinísticos. A geração por IA motiva a pesquisa, mas o experimento não medirá produtividade nem autonomia de agentes.

Um resultado positivo mostraria continuidade naquele domínio e com aqueles contratos. Ainda seria preciso investigar o custo de manter o ambiente: quem evolui os schemas, como os clientes descobrem mudanças e o que acontece quando um contrato exige uma versão de runtime que deixou de ser mantida.

O risco é trocar a dependência de um aplicativo pela dependência de uma camada compartilhada mais difícil de substituir. Por isso, verificar a restauração sem o código de A faz parte do teste desde o começo. Na tarefa do exemplo, o teste precisa confirmar que B consegue concluí-la depois da revisão das notas e que o runtime rejeita a tentativa antes da revisão.