## El problema que afrontan la mayoría de los constructores.

Si ejecuta un agente en una tienda, la atribución es trivial. Sabes quién escribió cada fila. Le escribiste al agente.

En el momento en que ejecutas dos, tres, cinco agentes contra la misma instancia de Neotoma, [la imagen cambia](/posts/when-agents-share-state-everything-breaks). Cada agente escribe observaciones, relaciones, fuentes, interpretaciones. La tienda acumula el estado de todos ellos. Si uno de esos agentes comienza a escribir datos incorrectos, resúmenes sutilmente erróneos, fechas obsoletas, relaciones mal atribuidas, la única manera de razonar sobre en qué registros confiar es razonar sobre qué agente los escribió.

Sin atribución por fila, sus opciones cuando algo sale mal son difíciles: limpiar la tienda y volver a ingerir, o dejar las filas malas y vivir con la deriva. Ambos empeoran a medida que la tienda crece.

Este problema se agrava para cualquiera que envíe un producto impulsado por agentes. Los registros de sus clientes los escribe una flota: sus propios agentes, agentes de terceros integrados a través de MCP, tal vez un complemento que alguien instaló la semana pasada. Cuando un cliente pregunta "¿quién escribió esto en mi cuenta y bajo la autoridad de quién?", esa pregunta debe responderse a partir de los datos, no de un ejercicio de correlación entre registros del servidor y transcripciones de conversaciones.

Ejecuto agentes en Cursor, Claude Code, Codex y ChatGPT, todos escribiendo en una instancia de Neotoma. Escribí sobre [lo que realmente hace esa pila](/posts/what-my-agentic-stack-actually-does). La integración AAuth de Neotoma es lo que cierra la brecha para mi pila y para cualquiera que la construya: cada agente trae su propia clave y la tienda puede seguir siendo confiable a medida que crece la flota.

## ¿Por qué AAuth?

La capa de atribución se basa en [AAuth](https://www.aauth.dev/), un protocolo abierto que proporciona a cada cliente HTTP su propia identidad criptográfica. Sin preinscripción. Sin secretos compartidos. Sin fichas al portador. Cada solicitud está firmada con firmas de mensajes HTTP [RFC 9421](https://datatracker.ietf.org/doc/html/rfc9421), por lo que un token robado no tiene valor sin la clave de firma.

Elegí AAuth porque la persona detrás de esto, Dick Hardt, es un amigo y uno de los expertos en identidad más profundos que conozco. Editó OAuth 2.0 ([RFC 6749](https://www.rfc-editor.org/rfc/rfc6749)), fue coautor de OpenID Authentication 2.0 y fue miembro fundador de la junta directiva de la [OpenID Foundation](https://openid.net/foundation/members/). Ese es el mismo linaje que la mayoría de los desarrolladores encuentran a través de flujos de códigos de autorización e inicios de sesión federados. Cuando alguien con ese historial inicia un nuevo protocolo específicamente para agentes, vale la pena construirlo.

## Lo que ahora lleva cada escritura

[v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0) envía la atribución de agente por fila en cada superficie de escritura: `/store`, `/observations/create`, `/create_relationship`, `/correct`, `/entities/split`, las herramientas de almacenamiento de MCP y escrituras CLI sobre MCP y HTTP. Cada observación, relación, fuente e interpretación marca:

- Un identificador de agente verificado (huella digital de clave pública para escritores firmados, sujeto JWT y emisor de tokens de agente, nombre de información del cliente y versión como alternativa).
- Un nivel de confianza que clasifica con qué fuerza se prueba la identidad.
- El transporte en el que llegó la escritura.

Cinco niveles cubren el espectro:

- `hardware`: el agente proporcionó un sobre `cnf.attestation` (Apple Secure Enclave, WebAuthn empaquetado o TPM2) que el servidor verificó con raíces confiables.
- `operator_attested`: la firma verificada y el operador ha incluido en la lista de permitidos al emisor o al par emisor-sujeto. El operador responde por el proceso del agente sin necesidad de certificación de hardware.
- `software`: el agente firmó la solicitud con una clave válida, verificada por el servidor. Aquí es donde llegan la mayoría de los agentes hoy en día, incluida mi propia firma de proxy de cursor con un ES256 JWK respaldado por archivos.
- `unverified_client`: el agente se declaró con una clientInfo reconocible pero no firmó.
- `anónimo`: sin identidad alguna.

El resultado: puede mirar cualquier fila de su tienda y responder "qué agente escribió esto" como una lectura de datos de primera clase.

## Concesiones en lugar de archivos de configuración

Al principio del ciclo v0.6.0, las capacidades se cargaron desde archivos JSON de variables de entorno. Eso funcionó para un conjunto estático de agentes, pero falló en el momento en que quiso suspender un agente sin reiniciar el servidor.

Ahora: cada `agent_grant` es una entidad Neotoma de primera clase. Coincide con una identidad AAuth (por sujeto, emisor, huella digital o una combinación), lleva entradas de capacidad con alcance por operación y tipo de entidad, y tiene un ciclo de vida: "activo", "suspendido", "revocado". El middleware de admisión resuelve una identidad AAuth verificada en su concesión coincidente en cada solicitud, estampa el usuario y las capacidades de la concesión en el contexto de la solicitud y la aplicación posterior verifica cada operación con la concesión.

Las concesiones se administran a través de la interfaz de usuario del Inspector, la API REST (`POST /agents/grants`, `PATCH`, suspender, revocar, restaurar) o se migran una vez desde la configuración de entorno anterior mediante la `importación de concesiones de agentes neotoma`. Las variables de entorno heredadas (`NEOTOMA_AGENT_CAPABILITIES_*`) causan una falla en el tiempo de arranque si aún están configuradas, con un error estructurado que apunta al comando de migración.

La suspensión de una subvención es instantánea. La siguiente solicitud del agente falla la admisión. La restauración es igualmente instantánea. Sin reinicio del servidor, sin recarga de configuración.

Para cualquiera que ejecute un producto con agentes de atención al cliente, esto significa que la respuesta a incidentes pasa de "reiniciar el servicio con una nueva configuración" a "suspender una concesión e investigar". El radio de explosión de un agente que se porta mal está limitado a las operaciones que le otorgan autorización.

## Verificación previa de identidad

Cada agente ahora puede preguntarle a Neotoma, antes de producir cualquier dato, si es reconocido como un escritor confiable.

Tres puntos de entrada equivalentes:

- `GET /sesión` a través de HTTP.
- `get_session_identity` como herramienta MCP.
- `sesión de autenticación de neotoma` en la CLI.

Cada uno devuelve el nivel de confianza resuelto, el estado de la concesión (admitida o no, con motivo), la política de escritura anónima y un valor booleano "eligible_for_trusted_writes". La respuesta incluye un bloque de diagnóstico que explica cómo se resolvió el nivel. Un nuevo agente falla estrepitosamente al inicio de la sesión en lugar de escribir filas anónimas hasta que alguien se da cuenta.

Las instrucciones de MCP enviadas le indican a cada agente conectado que ejecute esta verificación antes de habilitar las escrituras.

## ¿Dónde estoy ejecutando esto?

Tres agentes de servicio distintos en mi pila escriben a Neotoma bajo AAuth hoy.

**Proxy de Cursor MCP.** Cada solicitud de MCP de Cursor fluye a través de un proxy de firma (`mcp_identity_proxy.py`) que inyecta una firma RFC 9421 con un token de agente `aa-agent+jwt`. Neotoma verifica la firma, resuelve la identidad (`sub=cursor@markmhendrickson.com`, `iss=https://markmhendrickson.com`), coincide con `agent_grant` y admite la escritura en `tier=software`. El proxy también ejecuta una verificación previa de la sesión al inicio y puede fallar al cerrarse si el servidor informa un nivel anónimo.

**Canal de retroalimentación.** Una retransmisión de Netlify en `agent.neotoma.io` reenvía informes de errores del agente a Neotoma a través de un túnel [Cloudflare Access](https://www.cloudflare.com/zero-trust/) firmado por AAuth. Su concesión se limita únicamente a las operaciones `neotoma_feedback`.

**[Darkmesh](https://github.com/markmhendrickson/darkmesh) escritura retroactiva de introducción en caliente.** Mi [Darkmesh fork](https://github.com/markmhendrickson/darkmesh/blob/main/docs/neotoma_integration.md) ([context](/posts/the-substrate-plancast-needed)) registra revelaciones de introducción en caliente en Neotoma con RFC 9421 firmas y un token `aa-agent+jwt`. Cada revelación llega con el `agent_sub`, el `agent_iss` y la huella digital de la clave del nodo, dentro del alcance de una concesión por nodo.

Las pruebas conjuntas de Darkmesh demostraron que la aplicación se realiza en forma adversa. Un segundo agente simulado de un nodo par intentó escribir un `warm_intro_reveal` sin ese tipo de entidad en su concesión. Neotoma rechazó la escritura. Las escrituras del nodo autorizado se realizaron sin cambios.

Lo siguiente en la hoja de ruta: el [agente público en markmhendrickson.com](https://markmhendrickson.com/agent/) incluye una instancia de Neotoma como memoria y hoy solo sirve entidades que he marcado explícitamente como públicas. Planeo agregar lecturas controladas por AAuth para que los visitantes autorizados puedan consultar tipos de entidades no públicas específicas. La misma maquinaria de identidad firmada más concesión, aplicada a la ruta de lectura.

## Actualización de toda la flota

Neotoma envía sus instrucciones MCP canónicas desde el servidor a cada cliente conectado en cada apretón de manos. En v0.6.0, esas instrucciones ahora codifican la verificación previa de atribución, el etiquetado `observation_source`, los límites de procedencia citada por respuesta, un grupo de visualización `Ambiguous (N)` para advertencias de combinación heurística y un bucle estructurado de envío de comentarios.

Cuando actualicé mi servidor, mis enlaces Cursor, Claude Code, Codex y OpenCode adoptaron los nuevos comportamientos. No hay versiones del lado del cliente. Sin migración por herramienta. Un aumento en el servidor, cinco agentes actualizados. Para cualquiera que ejecute flotas de clientes, se aplica el mismo patrón: actualice la instancia de Neotoma y cada agente conectado adoptará los nuevos valores predeterminados sin implementar un cliente.

## La superficie de auditoría

Para los creadores de productos en mercados regulados, la pregunta de seguimiento de un cliente rara vez es "¿su sistema recordó esto?". Es "quién lo escribió y puede demostrar que estaban autorizados".

Después de v0.6.0, se trata de una lectura de datos de primera clase:

- `GET /agents` enumera cada identidad de agente que el servidor ha visto.
- `GET /agents/{key}` devuelve la vista detallada por agente.
- Auditorías `GET /agents/{key}/records` que registra la creación de un agente determinado.
- `GET /agents/grants` enumera todas las subvenciones, sus capacidades y su estado de ciclo de vida.

Si ofrece funcionalidad de agencia a clientes en los sectores vertical de atención médica, financiera, legal o empresarial, esta es la superficie que sus clientes eventualmente demandarán.

## Cómo encenderlo

```golpecito
keygen de autenticación de neotoma --alg ES256
ejemplo de signo de autenticación de neotoma
sesión de autenticación de neotoma
```

Cree una concesión para la nueva identidad a través del Inspector o la API REST, adaptando las capacidades a las operaciones que su agente necesita. Si está actualizando desde el antiguo modelo env-config, ejecute `neotoma Agents Grants Import --owner-user-id <your_user_id>` una vez, luego desactive las variables heredadas.

Para la firma programática, [`@aauth/local-keys`](https://www.aauth.dev/) o una biblioteca AAuth equivalente firma solicitudes con firmas de mensajes HTTP RFC 9421 más un token `aa-agent+jwt`. Neotoma verifica la firma en los bytes sin formato que firmó el cliente.

Las escrituras sin AAuth todavía funcionan. Aterrizan en el nivel "anónimo". Los constructores que quieran fallas difíciles pueden invertir `NEOTOMA_AAUTH_STRICT=1` y agregar temas específicos a `NEOTOMA_STRICT_AAUTH_SUBS`.

## También enviado

v0.6.0 no es solo AAuth. El mismo lanzamiento permite dividir la entidad para registros excesivamente fusionados, exportación de instantáneas de la flota más herramientas de deriva, conversaciones multiagente de primera clase a través de `conversation_message` y `sender_kind`, y un perímetro API ajustado. El suplemento completo se encuentra en [las notas de la versión v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).

## Instalar y actualizar

```golpecito
npm install -g neotoma@[0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0)
inicio del neotoma
keygen de autenticación de neotoma
sesión de autenticación de neotoma
```

La actualización del servidor le brinda el nuevo sello de atribución y la actualización de la instrucción MCP en el siguiente protocolo de enlace del cliente. No se requiere instalación del lado del cliente para los agentes que ya están conectados a través de MCP.

Instalación completa: [neotoma.io/install](https://neotoma.io/install). Repositorio: [github.com/markmhendrickson/neotoma](https://github.com/markmhendrickson/neotoma). Notas de la versión: [v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).