## El problema per davant de la majoria de constructors

Si executeu un agent contra una botiga, l'atribució és trivial. Ja saps qui va escriure cada fila. Vas escriure a l'agent.

En el moment en què executeu dos, tres, cinc agents contra la mateixa instància de Neotoma, [la imatge canvia](/posts/when-agents-share-state-everything-breaks). Cada agent escriu observacions, relacions, fonts, interpretacions. La botiga acumula estat de tots ells. Si un d'aquests agents comença a escriure dades dolentes, resums subtilment equivocats, dates obsoletes, relacions mal atribuïdes, l'única manera de raonar sobre quins registres confiar és raonar sobre quin agent els va escriure.

Sense l'atribució per fila, les vostres opcions quan alguna cosa va malament són difícils: esborrar la botiga i tornar a ingerir, o deixar les files dolentes i viure amb la deriva. Tots dos empitjoren a mesura que la botiga creix.

Aquest problema es fa més agut per a qualsevol que enviï un producte impulsat per agents. Els registres dels vostres clients estan sent escrits per una flota: els vostres propis agents, agents de tercers integrats mitjançant MCP, potser un connector que algú va instal·lar la setmana passada. Quan un client pregunta "qui va escriure això al meu compte i sota l'autoritat de qui?", aquesta pregunta s'ha de respondre a partir de les dades, no des d'un exercici de correlació entre els registres del servidor i les transcripcions de converses.

Executeixo agents a Cursor, Claude Code, Codex i ChatGPT, tots escrivint a una instància de Neotoma. Vaig escriure sobre [què fa realment aquesta pila](/posts/what-my-agentic-stack-actually-does). La integració AAuth de Neotoma és el que tanca la bretxa per a la meva pila i per a qualsevol persona que s'hi construeixi: cada agent porta la seva pròpia clau i la botiga pot mantenir la confiança a mesura que la flota creix.

## Per què AAuth

La capa d'atribució es basa en [AAuth](https://www.aauth.dev/), un protocol obert que dóna a cada client HTTP la seva pròpia identitat criptogràfica. Sense preinscripció. Sense secrets compartits. Sense fitxes de portador. Cada sol·licitud està signada amb [RFC 9421](https://datatracker.ietf.org/doc/html/rfc9421) Signatures de missatge HTTP, de manera que un testimoni robat no té valor sense la clau de signatura.

Vaig triar AAuth perquè la persona que hi ha darrere, Dick Hardt, és un amic i un dels experts en identitat més profunds que conec. Va editar OAuth 2.0 ([RFC 6749](https://www.rfc-editor.org/rfc/rfc6749)), va ser coautor d'OpenID Authentication 2.0 i va ser membre de la junta fundadora de la [OpenID Foundation](https://openid.net/foundation/members/). Aquest és el mateix llinatge que coneixen la majoria de desenvolupadors mitjançant fluxos de codi d'autorització i inici de sessió federat. Quan algú amb aquest historial inicia un nou protocol específicament per als agents, aquest és el que val la pena construir.

## El que ara porta tota escriptura

[v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0) envia l'atribució d'agent per fila a totes les superfícies d'escriptura: `/store`, `/observations/create`, `/create_relationship`, `/correct`, les eines d'escriptura de `/correct`, les eines d'escriptura de MCPLI's i CPLI stores tant a MCP com a HTTP. Cada segell d'observació, relació, font i interpretació:

- Un identificador d'agent verificat (empremta digital de clau pública per a escriptors signats, subjecte JWT i emissor per a fitxes d'agent, nom i versió de clientInfo com a alternativa).
- Un nivell de confiança que classifica amb quina força es demostra la identitat.
- El transport on va arribar l'escriptura.

Cinc nivells cobreixen l'espectre:

- "maquinari": l'agent va proporcionar un sobre "cnf.attestation" (Apple Secure Enclave, WebAuthn empaquetat o TPM2) que el servidor va verificar amb arrels de confiança.
- `operator_attested`: la signatura s'ha verificat i l'operador ha llistat l'emissor o la parella emissor-assumpte. L'operador garanteix el procés de l'agent sense requerir una certificació de maquinari.
- `programari`: l'agent va signar la sol·licitud amb una clau vàlida, verificada pel servidor. Aquí és on arriben avui la majoria d'agents, inclòs la meva pròpia signatura de proxy de cursor amb un ES256 JWK recolzat per fitxers.
- `client_no verificat`: l'agent es va declarar amb una info client reconeixible però no va signar.
- "anònim": cap identitat.

El resultat: podeu mirar qualsevol fila de la vostra botiga i respondre "quin agent va escriure això" com a lectura amb dades de primera classe.

## Subvencions en lloc dels fitxers de configuració

A principis del cicle v0.6.0, les capacitats es van carregar des de fitxers JSON variables d'entorn. Això va funcionar per a un conjunt d'agents estàtic, però es va trencar en el moment en què volies suspendre un agent sense reiniciar el servidor.

Ara: cada "agent_grant" és una entitat Neotoma de primera classe. Coincideix amb una identitat AAuth (per subjecte, emissor, empremta digital o una combinació), porta entrades de capacitat per a l'àmbit d'operació i tipus d'entitat i té un cicle de vida: "actiu", "suspès", "revocat". El programari intermedi d'admissió resol una identitat AAuth verificada a la seva concessió coincident a cada sol·licitud, estampa l'usuari i les capacitats de la subvenció al context de la sol·licitud i l'aplicació aigües avall comprova cada operació amb la subvenció.

Les subvencions es gestionen mitjançant l'Inspector UI, l'API REST (`POST /agents/grants`, `PATCH`, suspensió, revocació, restauració) o es migren una vegada des de l'antic env-config mitjançant `neotoma agents grants import`. Els env vars heretats (`NEOTOMA_AGENT_CAPABILITIES_*`) causen un error en el moment d'arrencada si encara s'estableixen, amb un error estructurat que apunta a l'ordre de migració.

La suspensió d'una subvenció és instantània. La següent sol·licitud de l'agent no s'admet. La restauració és igualment instantània. Sense reinici del servidor, sense recàrrega de configuració.

Per a qualsevol persona que utilitzi un producte amb agents orientats al client, això significa que la resposta a incidents passa de "reiniciar el servei amb una configuració nova" a "suspender una subvenció i investigar". El radi d'explosió d'un agent que es comporta mal està limitat a les operacions que atorguen autoritzades.

## Comprovació prèvia d'identitat

Ara, cada agent pot preguntar a Neotoma, abans de produir cap dada, si és reconegut com a escriptor de confiança.

Tres punts d'entrada equivalents:

- `GET /session` per HTTP.
- `get_session_identity` com a eina MCP.
- `neotoma auth session` a la CLI.

Cadascun retorna el nivell de confiança resolt, l'estat de la concessió (admès o no, amb motiu), la política d'escriptura anònima i un `eligible_for_trusted_writes` booleà. La resposta inclou un bloc de diagnòstic que explica com s'ha resolt el nivell. Un agent nou falla amb força a l'inici de la sessió en lloc d'escriure files anònimes fins que algú se n'adona.

Les instruccions MCP enviades diuen a tots els agents connectats que executin aquesta comprovació abans d'habilitar les escriptures.

## On estic executant això

Tres agents de servei diferents de la meva pila escriuen avui a Neotoma sota AAuth.

**Proxy MCP del cursor.** Cada sol·licitud MCP del Cursor flueix a través d'un servidor intermediari de signatura (`mcp_identity_proxy.py`) que injecta una signatura RFC 9421 amb un testimoni d'agent `aa-agent+jwt`. Neotoma verifica la signatura, resol la identitat (`sub=cursor@markmhendrickson.com`, `iss=https://markmhendrickson.com`), coincideix amb `agent_grant` i admet l'escriptura a `tier=software`. El servidor intermediari també executa la comprovació prèvia de la sessió a l'inici i pot fallar en tancar-se si el servidor informa d'un nivell anònim.

**Conducte de comentaris.** Un relé de Netlify a `agent.neotoma.io` reenvia informes d'errors d'agent a Neotoma a través d'un túnel [Accés a Cloudflare](https://www.cloudflare.com/zero-trust/) signat per AAuth. La seva concessió només s'aplica a les operacions `neotoma_feedback`.

**[Darkmesh](https://github.com/markmhendrickson/darkmesh) redacció d'introducció calenta.** La meva [forquilla Darkmesh](https://github.com/markmhendrickson/darkmesh/blob/main/docs/neotoma_integration.md) ([context]-(substrated)/planificació) warm-intro torna a revelar-se a Neotoma amb signatures RFC 9421 i un testimoni "aa-agent+jwt". Cada revelació arriba amb els `agent_sub`, `agent_iss` i l'empremta digital de la clau del node, abastats per una concessió per node.

Les proves conjuntes de Darkmesh van demostrar l'aplicació en forma adversa. Un segon agent simulat d'un node igual va intentar escriure un "warm_intro_reveal" sense aquest tipus d'entitat a la seva concessió. Neotoma va rebutjar l'escriptura. Les escriptures del node autoritzat no han canviat.

A continuació al full de ruta: [agent públic a markmhendrickson.com](https://markmhendrickson.com/agent/) embolcalla una instància de Neotoma com a memòria i avui només serveix a les entitats que he marcat explícitament com a públiques. Tinc la intenció d'afegir lectures autoritzades per AAuth perquè els visitants autoritzats puguin consultar tipus específics d'entitats no públiques. La mateixa maquinària d'identitat signada més subvenció, aplicada al camí de lectura.

## Actualització de tota la flota

Neotoma envia les seves instruccions MCP canòniques des del servidor a tots els clients connectats en cada encaixada de mans. A la v0.6.0, aquestes instruccions codifiquen ara la comprovació prèvia d'atribució, l'etiquetatge `observation_source`, les vores de procedència citades per la resposta, un grup de visualització `ambigu (N)' per als avisos de combinació heurística i un bucle estructurat d'enviament de comentaris.

Quan vaig actualitzar el meu servidor, els meus ganxos Cursor, Claude Code, Codex i OpenCode van recollir els nous comportaments. No hi ha versions del costat del client. Sense migració per eina. Un cop de servidor, cinc agents actualitzats. Per a qualsevol persona que executi flotes de clients, s'aplica el mateix patró: actualitzeu la instància de Neotoma i cada agent connectat recull els nous valors predeterminats sense una implementació del client.

## La superfície d'auditoria

Per als fabricants de productes en mercats regulats, la pregunta de seguiment d'un client rarament és "el vostre sistema ho recordava". És "qui ho va escriure, i pots demostrar que estaven autoritzats".

Després de la v0.6.0, és una lectura amb dades de primera classe:

- `GET /agents` enumera totes les identitats d'agent que ha vist el servidor.
- `GET /agents/{key}` retorna la vista de detall per agent.
- `GET /agents/{key}/records` auditories que registra un agent determinat.
- `GET /agents/grants` enumera totes les subvencions, les seves capacitats i l'estat del seu cicle de vida.

Si envieu la funcionalitat d'agent als clients de sectors sanitaris, financers, legals o empresarials, aquesta és la superfície que els vostres clients eventualment demanaran.

## Com activar-lo

```bash
neotoma auth keygen --alg ES256
neotoma auth signe-exemple
sessió d'autenticació de neotoma
```

Creeu una subvenció per a la nova identitat mitjançant l'Inspector o l'API REST, abastant les capacitats a les operacions que necessita el vostre agent. Si esteu actualitzant des de l'antic model env-config, executeu `neotoma agents grants import --owner-user-id <your_user_id>` una vegada i, a continuació, desactiveu les variables heretades.

Per a la signatura programàtica, [`@aauth/local-keys`](https://www.aauth.dev/) o una biblioteca AAuth equivalent signa sol·licituds amb les signatures de missatges HTTP RFC 9421 més un testimoni `aa-agent+jwt`. Neotoma verifica la signatura als bytes en brut que ha signat el client.

Les escriptures sense AAuth encara funcionen. Aterren al nivell "anònim". Els constructors que vulguin fallades dures poden capgirar `NEOTOMA_AAUTH_STRICT=1` i afegir temes específics a `NEOTOMA_STRICT_AAUTH_SUBS`.

## També s'envia

v0.6.0 no és només AAuth. El mateix llançament obté una entitat dividida per a registres combinats en excés, exportació d'instantànies de flota més eines de deriva, converses multiagent de primera classe mitjançant "conversation_message" i "sender_kind", i un perímetre de l'API més ajustat. El suplement complet es troba a [les notes de la versió v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).

## Instal·leu i actualitzeu

```bash
npm install -g neotoma@[0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0)
neotoma init
neotoma auth keygen
sessió d'autenticació de neotoma
```

L'actualització del servidor us proporciona el nou segell d'atribució i l'actualització de les instruccions MCP a la propera connexió de contactes del client. No es requereix cap instal·lació del costat del client per als agents ja connectats mitjançant MCP.

Instal·lació completa: [neotoma.io/install](https://neotoma.io/install). Repositori: [github.com/markmhendrickson/neotoma](https://github.com/markmhendrickson/neotoma). Notes de la versió: [v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).