## O problema que a maioria dos construtores enfrenta

Se você executar um agente em uma loja, a atribuição será trivial. Você sabe quem escreveu cada linha. Você escreveu ao agente.

No momento em que você executa dois, três, cinco agentes na mesma instância do Neotoma, [a imagem muda](/posts/when-agents-share-state-everything-breaks). Cada agente escreve observações, relacionamentos, fontes, interpretações. A loja acumula estado de todos eles. Se um desses agentes começar a escrever dados incorretos, resumos sutilmente errados, datas obsoletas, relacionamentos atribuídos incorretamente, a única maneira de raciocinar sobre quais registros confiar é raciocinar sobre qual agente os escreveu.

Sem atribuição por linha, suas opções quando algo dá errado são difíceis: limpar o estoque e ingerir novamente ou deixar as linhas ruins e conviver com a tendência. Ambos pioram à medida que a loja cresce.

Esse problema fica mais acentuado para quem envia um produto orientado por agente. Os registros de seus clientes estão sendo gravados por uma frota: seus próprios agentes, agentes terceirizados integrados via MCP, talvez um plugin que alguém instalou na semana passada. Quando um cliente pergunta “quem escreveu isso para minha conta e sob autoridade de quem?”, essa pergunta deve ser respondida a partir dos dados, e não de um exercício de correlação entre logs do servidor e transcrições de conversas.

Eu administro agentes em Cursor, Claude Code, Codex e ChatGPT, todos escrevendo para uma instância do Neotoma. Escrevi sobre [o que essa pilha realmente faz](/posts/what-my-agentic-stack-actually-does). A integração AAuth da Neotoma é o que preenche a lacuna para minha pilha e para qualquer pessoa que a desenvolva: cada agente traz sua própria chave e a loja pode permanecer confiável à medida que a frota cresce.

## Por que AAuth

A camada de atribuição é construída em [AAuth](https://www.aauth.dev/), um protocolo aberto que dá a cada cliente HTTP sua própria identidade criptográfica. Sem pré-registro. Não há segredos compartilhados. Sem tokens ao portador. Cada solicitação é assinada com [RFC 9421](https://datatracker.ietf.org/doc/html/rfc9421) assinaturas de mensagens HTTP, portanto, um token roubado não vale nada sem a chave de assinatura.

Escolhi o AAuth porque a pessoa por trás dele, Dick Hardt, é um amigo e um dos maiores especialistas em identidade que conheço. Ele editou o OAuth 2.0 ([RFC 6749](https://www.rfc-editor.org/rfc/rfc6749)), foi coautor do OpenID Authentication 2.0 e foi membro fundador do conselho da [OpenID Foundation](https://openid.net/foundation/members/). Essa é a mesma linhagem que a maioria dos desenvolvedores conhece por meio de fluxos de código de autorização e login federado. Quando alguém com esse histórico inicia um novo protocolo especificamente para agentes, vale a pena construir contra esse.

## O que cada escrita agora carrega

[v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0) fornece atribuição de agente por linha em cada superfície de gravação: `/store`, `/observations/create`, `/create_relationship`, `/correct`, `/entities/split`, as ferramentas de armazenamento MCP e gravações CLI em MCP e HTTP. Cada observação, relacionamento, fonte e interpretação carimba:

- Um identificador de agente verificado (impressão digital de chave pública para escritores assinados, assunto JWT e emissor para tokens de agente, nome e versão clientInfo como substituto).
- Um nível de confiança que classifica o grau de comprovação da identidade.
- O transporte em que a escrita chegou.

Cinco níveis cobrem o espectro:

- `hardware`: o agente forneceu um envelope `cnf.attestation` (Apple Secure Enclave, WebAuthn pack ou TPM2) que o servidor verificou em relação a raízes confiáveis.
- `operator_attested`: a assinatura foi verificada e o operador colocou na lista de permissões o emissor ou o par emissor-assunto. O operador atesta o processo do agente sem exigir atestado de hardware.
- `software`: o agente assinou a solicitação com uma chave válida, verificada pelo servidor. É aqui que a maioria dos agentes chega hoje, incluindo minha própria assinatura de proxy Cursor com um ES256 JWK baseado em arquivo.
- `unverified_client`: o agente se declarou com um clientInfo reconhecível, mas não assinou.
- `anônimo`: sem identidade alguma.

Resultado: você pode olhar qualquer linha em sua loja e responder "qual agente escreveu isso" como uma leitura em dados de primeira classe.

## Concessões em vez de arquivos de configuração

No início do ciclo v0.6.0, os recursos foram carregados a partir de arquivos JSON de variáveis ​​de ambiente. Isso funcionou para um conjunto estático de agentes, mas quebrou no momento em que você quis suspender um agente sem reiniciar o servidor.

Agora: cada `agent_grant` é uma entidade Neotoma de primeira classe. Ele corresponde a uma identidade AAuth (por assunto, emissor, impressão digital ou uma combinação), carrega entradas de capacidade com escopo definido por operação e tipo de entidade e tem um ciclo de vida: `ativo`, `suspenso`, `revogado`. O middleware de admissão resolve uma identidade AAuth verificada para sua concessão correspondente em cada solicitação, carimba o usuário e os recursos da concessão no contexto da solicitação e a aplicação downstream verifica cada operação em relação à concessão.

As concessões são gerenciadas por meio da IU do Inspector, a API REST (`POST /agents/grants`, `PATCH`, suspender, revogar, restaurar) ou migradas uma vez do antigo env-config por meio de `neotoma agents grants import`. Os env vars herdados (`NEOTOMA_AGENT_CAPABILITIES_*`) causam uma falha no momento da inicialização se ainda estiverem definidos, com um erro estruturado apontando para o comando de migração.

A suspensão de uma concessão é instantânea. A próxima solicitação do agente falha na admissão. A restauração é igualmente instantânea. Sem reinicialização do servidor, sem recarga de configuração.

Para qualquer pessoa que execute um produto com agentes de atendimento ao cliente, isso significa que a resposta a incidentes passa de “reiniciar o serviço com uma nova configuração” para “suspender uma concessão e investigar”. O raio de explosão de um agente malcomportado está limitado às operações que concedem autorização.

## Comprovação de identidade

Cada agente agora pode perguntar ao Neotoma, antes de produzir qualquer dado, se ele é reconhecido como um escritor confiável.

Três pontos de entrada equivalentes:

- `GET /sessão` por HTTP.
- `get_session_identity` como uma ferramenta MCP.
- `sessão de autenticação neotoma` na CLI.

Cada um retorna o nível de confiança resolvido, o status da concessão (admitido ou não, com motivo), a política de gravação anônima e um booleano `eligible_for_trusted_writes`. A resposta inclui um bloco de diagnóstico que explica como a camada foi resolvida. Um novo agente falha ruidosamente no início da sessão, em vez de escrever linhas anônimas até que alguém perceba.

As instruções do MCP enviadas informam a cada agente conectado para executar essa verificação antes de ativar as gravações.

## Onde estou executando isso

Três agentes de serviço distintos em minha pilha escrevem para Neotoma sob AAuth hoje.

**Proxy Cursor MCP.** Cada solicitação MCP do Cursor flui através de um proxy de assinatura (`mcp_identity_proxy.py`) que injeta uma assinatura RFC 9421 com um token de agente `aa-agent+jwt`. Neotoma verifica a assinatura, resolve a identidade (`sub=cursor@markmhendrickson.com`, `iss=https://markmhendrickson.com`), corresponde ao `agent_grant` e admite a gravação em `tier=software`. O proxy também executa a simulação de sessão na inicialização e pode falhar ao fechar se o servidor reportar um nível anônimo.

**Pipeline de feedback.** Uma retransmissão do Netlify em `agent.neotoma.io` encaminha relatórios de bugs do agente para o Neotoma por meio de um túnel [Cloudflare Access](https://www.cloudflare.com/zero-trust/) assinado por AAuth. Sua concessão tem como escopo apenas operações `neotoma_feedback`.

**[Darkmesh](https://github.com/markmhendrickson/darkmesh) writeback de introdução quente.** Meu [fork Darkmesh](https://github.com/markmhendrickson/darkmesh/blob/main/docs/neotoma_integration.md) ([context](/posts/the-substrate-plancast-needed)) registra introduções quentes reveladas de volta ao Neotoma com assinaturas RFC 9421 e um token `aa-agent+jwt`. Cada revelação chega com `agent_sub`, `agent_iss` e impressão digital da chave do nó, com escopo definido por uma concessão por nó.

Os testes conjuntos do Darkmesh comprovaram a aplicação de forma adversária. Um segundo agente simulado de um nó peer tentou escrever um `warm_intro_reveal` sem esse tipo de entidade em sua concessão. Neotoma rejeitou a escrita. As gravações do nó autorizado ocorreram inalteradas.

A seguir no roteiro: o [agente público em markmhendrickson.com](https://markmhendrickson.com/agent/) agrupa uma instância do Neotoma como sua memória e hoje atende apenas entidades que marquei explicitamente como públicas. Pretendo adicionar leituras controladas por AAuth para que visitantes autorizados possam consultar tipos específicos de entidades não públicas. O mesmo mecanismo de identidade assinada mais concessão, aplicado ao caminho de leitura.

## Atualização para toda a frota

O Neotoma envia suas instruções MCP canônicas do servidor para cada cliente conectado em cada handshake. Na v0.6.0, essas instruções agora codificam a simulação de atribuição, marcação `observation_source`, bordas de proveniência citadas por resposta, um grupo de exibição `Ambíguo (N)` para avisos de mesclagem heurística e um loop estruturado de envio de feedback.

Quando atualizei meu servidor, meus ganchos Cursor, Claude Code, Codex e OpenCode adquiriram os novos comportamentos. Nenhuma versão do lado do cliente. Nenhuma migração por ferramenta. Um aumento no servidor, cinco agentes atualizados. Para qualquer pessoa que execute frotas de clientes, o mesmo padrão se aplica: atualize a instância do Neotoma e cada agente conectado adotará os novos padrões sem uma implantação do cliente.

## A superfície de auditoria

Para fabricantes de produtos em mercados regulamentados, a pergunta de acompanhamento de um cliente raramente é “seu sistema se lembrou disso”. É "quem escreveu e você pode provar que foi autorizado".

Após a v0.6.0, essa é uma leitura de dados de primeira classe:

- `GET /agents` enumera cada identidade de agente que o servidor viu.
- `GET /agents/{key}` retorna a visualização detalhada por agente.
- Auditorias `GET /agents/{key}/records` que registram a autoria de um determinado agente.
- `GET /agents/grants` lista todas as concessões, suas capacidades e seu status de ciclo de vida.

Se você fornece funcionalidade de agente para clientes nos setores de saúde, finanças, jurídico ou empresarial, esta é a superfície que seus clientes eventualmente exigirão.

## Como ligá-lo

```bash
chave de autenticação neotoma --alg ES256
exemplo de sinal de autenticação neotoma
sessão de autenticação neotoma
```

Crie uma concessão para a nova identidade por meio do Inspector ou da API REST, delimitando os recursos às operações que seu agente precisa. Se você estiver atualizando do antigo modelo env-config, execute `neotoma agents grants import --owner-user-id <your_user_id>` uma vez e, em seguida, desmarque as variáveis ​​legadas.

Para assinatura programática, [`@aauth/local-keys`](https://www.aauth.dev/) ou uma biblioteca AAuth equivalente assina solicitações com assinaturas de mensagens HTTP RFC 9421 mais um token `aa-agent+jwt`. Neotoma verifica a assinatura nos bytes brutos que o cliente assinou.

Gravações sem AAuth ainda funcionam. Eles caem na camada `anônima`. Construtores que desejam falhas graves podem inverter `NEOTOMA_AAUTH_STRICT=1` e adicionar assuntos específicos a `NEOTOMA_STRICT_AAUTH_SUBS`.

## Também enviado

v0.6.0 não é apenas AAuth. O mesmo lançamento permite divisão de entidade para registros mesclados, exportação de instantâneos de frota mais ferramentas de desvio, conversas multiagentes de primeira classe via `conversation_message` e `sender_kind` e um perímetro de API restrito. O suplemento completo está nas [notas de versão v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).

## Instalar e atualizar

```bash
npm install -g neotoma@[0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0)
inicialização do neotoma
chave de autenticação neotoma
sessão de autenticação neotoma
```

A atualização do servidor fornece o novo carimbo de atribuição e a atualização da instrução MCP no próximo handshake do cliente. Nenhuma instalação no lado do cliente é necessária para agentes já conectados via MCP.

Instalação completa: [neotoma.io/install](https://neotoma.io/install). Repositório: [github.com/markmhendrickson/neotoma](https://github.com/markmhendrickson/neotoma). Notas de versão: [v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).