AAuth in a Working Agent Fleet

Design and integration spec — 2026-08-31

Written both as feedback for Dick Hardt on the AAuth drafts and as our internal integration plan. It describes architecture at a level cleared for sharing outside our perimeter: no credentials, addresses, key locations, or personal data appear here, and specific hosts are named by role.

A machine-consumable companion — trust-surface inventory, flow traces, a deployment profile, and eleven numbered change requests with statuses reflecting the author's answers — is at notes.ito.com/b825c2689269bc3e38aa213d. Feed that one to your agent.

Both documents were compiled by agents in the fleet they describe, from a same-day survey of the running systems. One deployment, one operator: weight the feedback accordingly.

Revision note, 2026-08-31: revised twice since first publication — once after an independent-model review against draft -10, and again after author feedback read against the working draft (-11 in progress). Corrections are made in place and named where they matter; the largest was ours to make (see the policy-continuity warning in Phase 1).

1. What this is

We run a personal-scale agent fleet in production: an autonomous build pipeline that lands code overnight, a public community agent with its own wallet, grooming and review agents, and a human-approval loop that runs over a task tracker. Authentication inside the fleet is a mix of SSH keys, one shared bearer token, and self-asserted identity strings. We surveyed every trust surface in the system and mapped it against AAuth draft -10 (2026-08-06).

The short version: AAuth's agent identity mode directly replaces our weakest layer; missions are the same shape as a proposal-approval mechanism we converged on independently; and the person server is a protocol for the approval loop we currently run by hand. Section 5 is the phased integration design. Section 7 is the list of places where the drafts don't yet cover what we need — probably the useful part for Dick.

2. The system in one page

Six subsystems matter here.

Mujin (無人, "unmanned") — the autonomous build pipeline. Producers — interactive Claude Code sessions, a spec→plan→execute pipeline, a Codex lane, and an unattended overnight lane — write code on feature branches. An independent-model review gate (fresheyes: a second model family reviews the diff with zero conversation context) runs before handoff. A single lander, the merge-marshal, is the only writer of main on managed repos: producers hand off by posting a structured marker to the task tracker; the marshal pins the branch head, rebases, runs the repo's gate in a sandbox, and pushes with a per-repo deploy key. A post-commit review daemon patrols what landed. Volume is real: the marshal lands multiple handoffs a day, some produced entirely unattended.

kata — the coordination ledger. A task-tracker daemon everything talks to over HTTP. Issues, comments, labels, and claims are the fleet's coordination primitives, and some labels carry authority: designed-ready makes an issue executable by the unattended lane; handoff-to:merge-marshal requests a landing; joi-decision parks work on the human. The daemon lives on a VM reachable over a private overlay network.

Niwashi (庭師, "gardener") — the grooming lane. An unattended nightly agent that triages the backlog. It proposes and never disposes: its write set is closed (one comment, two specific labels), promotion to executable requires a human running a promote command under their own identity, and hygiene actions queue in a docket a human applies. Its model stages run as a separate credential-less OS user so a prompt-injected model cannot read fleet credentials.

The decision docket. The human-approval loop. Agents that stop on a decision only the human can make label the issue and park; the queue surfaces in a morning brief, an ops board, and a chat-tap approval surface on the phone. One operating ruling shapes it: approval is for judgment, not ritual — mechanical, reversible proposals get batch consent, judgment calls get per-item consent.

jilog and opsctl — the observation ledgers. Append-only event ledgers (segment files, CRC-checked, synced between machines) over agent session transcripts, with a nightly learning loop that detects corrections, errors, and patterns and files them as structured tracker issues. jilog is open source (github.com/Joi/jilog); opsctl is its private sibling and adds identity/membership claims that require human approval.

jibot and the agent economy. jibot is a community agent with a 23-year continuous identity (it started as an IRC bot on #joiito in 2003). Its site, jibot.md, serves raw markdown to agents by content negotiation and holds a wallet: an x402 v2 implementation with a self-hosted facilitator inline in a Cloudflare Worker, settling USDC on Polygon, Base, and Optimism. The Henkaku handshake quest had community members build an agent that completes a paid x402 handshake with jibot to earn a non-purchasable ERC-1155 challenge coin; identity in that flow is three mechanisms stitched together — platform identity (Discord), internal server-to-server authentication, and wallet-key possession proven by the x402 payment signature. Adjacent: trust402 (FRAME00's reference implementation; Joi is an outside director there) puts ZK identity, role, and spend-limit proofs on top of x402, with the proof generated before payment so a limit violation is rejected before money moves.

3. The trust model today

An honest two-column accounting.

Hard boundaries — these survive a hostile or buggy client:

Convention — cooperating clients police themselves:

The design philosophy behind this split is deliberate and has held up: guarantees live at the enforcement layer, and the failure mode of any single compromised component should be a wrong proposal in front of a human with an audit trail attached, never wrong work executing. But the two places that got hard enforcement got it reactively, after convention demonstrably failed. Everywhere else, requests are trusted by network position and actors are trusted by self-report.

That is the gap AAuth addresses.

4. What AAuth adds

The missing primitive is authenticated per-agent identity on every request. Agent identity mode provides it with nothing else attached: each agent holds a signing key and signs every request per RFC 9421; the agent's public key travels in the cnf.jwk of an AP-issued agent token, and what the well-known metadata publishes is the agent provider's verification key — the agents' own keys are never published. (Our first revision got that architecture wrong.) The resource verifies locally. Mapped onto our conventions:

Today (convention) With AAuth
Author = client-asserted string Author derived from the verified agent identity
Shared bearer = full access for everyone Per-agent policy enforced at the resource
"Two writers of designed-ready" = self-restraint Tracker-side policy: only those two identities may write it
Review honesty rests on the posting session Verdict signed by the reviewer identity, bound to the reviewed commit
Approval recorded as an env-var string Approval authenticated by the person server, recorded in a PS-signed token
Ledger provenance self-declared Segments signed by the emitting agent

The rest of the protocol matters to us for a different reason — and one correction from the author's reading: resource access modes are named, not numbered, and agent governance (missions, the mission log) is orthogonal to access mode, not a higher rung on a ladder. Our earlier framing treated person-server authorization and missions as one tier; they are two separate axes, and Phase 3 below uses both. Missions — content-addressed markdown proposals, approved by a person, immutable once approved, carried by reference in subsequent requests — are almost exactly our niwashi promotion cards and dispatch briefs, which we arrived at independently. Our promote flow even has the same immutability property: approval is invalidated if the card drifted since the human's acknowledgment. Watching that shape arrive as protocol is the main reason this document exists.

5. Integration design

Principle: adopt agent identity mode where convention is weakest, keep the hard boundaries we already have, prototype the person server against the existing decision docket, and use jibot's public surfaces as the interop bed.

Phase 1 — agent identity mode for the tracker

Five components, no changes to the tracker itself:

Acceptance: the shared bearer no longer exists on client machines; the daemon is reachable only through the sidecar; policy denials alert; a negative-path test suite (tampered bodies, expired tokens, replay, rotation, bypass attempts) passes before any lane arms. Rollback is a rehearsed operator procedure — re-open the daemon's prior listener and restore the prior credential in one step — not a client-side setting, since after cutover the clients no longer hold the old credential and the daemon no longer listens where they could point.

Policy continuity warning (the author caught this; neither of our first two revisions did). The per-lane policy table is keyed on the verified agent identifier. That works exactly and only in agent identity mode. An auth token deliberately carries no agent identifier and no delegation chain — cnf binds it to a key, and the resource enforces sub (the person) and scope. So the moment a tracker operation moves behind the person server in Phase 3, the per-lane label allowlist for that operation stops existing unless it is re-expressed as scopes or R3 operations. Our plan accordingly: authority-label writes stay in agent identity mode permanently (the lane, not the person, is the principal we are policing), and only operations whose natural principal is the person — approvals, promotions — move to auth tokens, with policy expressed as scope.

Phase 2 — signed provenance for artifacts at rest

Our highest-value assertions are not HTTP requests. They are artifacts: the handoff marker that binds a branch head, the review-evidence line, the promotion provenance comment, ledger segments moved by file sync. Phase 2 signs these artifacts under the same agent identities — though on reflection with separate durable-evidence keys, not the online request-signing key an internet-adjacent proxy holds — and verifies at the point of trust: the marshal drain verifies marker and review signatures at enqueue time and archives the evidence (the pattern the draft's own §14.16 recommends over trusting age-old signatures), ledger ingest verifies segments before committing. This is outside AAuth's HTTP scope as drafted; see question 2 below.

One claim we retract from an earlier framing: a signed review verdict proves that the reviewer identity signed a statement about a specific commit — it does not prove an independent review ran. Closing that gap needs the reviewing service itself to hold the key on an isolated uid and sign as part of producing the verdict, which is process engineering, not protocol. The protocol contribution is real but smaller than we first wrote: forging review evidence stops being a one-line text comment.

Phase 3 — person server backed by the decision docket

A minimal self-hosted person server whose backing store is the docket we already operate:

  1. An agent attempts a gated tracker operation; the sidecar requires a person token first (the draft is explicit that a resource MUST have verified a person token before issuing a resource token — our earlier flow skipped it), then answers with a resource token naming the needed scope.
  2. The agent posts to the PS token endpoint with a justification and receives 202 plus a poll URL.
  3. The pending approval renders in the surfaces the human already reads: the morning brief, the ops board, the phone approval taps.
  4. Approval issues an auth token bound to the agent's key; the sidecar honors it.

Missions slot in directly: dispatch briefs and grooming cards become mission proposals, with the approver URL pointing at the PS and the approved hash pinned at promotion.

Where our consent tiers actually live — another correction from the author's reading: not in mission syntax. The resource declares which operations require per-call consent (R3's operation annotations already carry exactly that split), and the standing rule "mechanical batch, judgment per-item" is the person server's governance policy. The drafts define where the PS decides but not how — what a governance policy is has no definition and no companion document yet. That gap is the interesting one for us: a personal PS without a decision procedure is a queue with a protocol on it; with one, it is a decider that answers routine requests without waking the person. Given our approval queue runs about a hundred deep, the governance policy is the difference between this phase reducing consent fatigue and formalizing it.

The Events draft matches a pattern we hand-roll today: watchers that poll a condition and ping a phone-visible channel when a wait completes. AP-mediated delivery for agents without public endpoints fits our constraint exactly — the fleet machines sit behind NAT and most agents are ephemeral sessions.

Phase 4 — the agent economy: jibot, x402, Budgets, Henkaku

6. Sequencing and effort (internal)

Phase 1 is modest but not small — we wrote "verification against published JWKS is the whole job" in an earlier revision and were wrong. The sidecar owes the draft's full verification checklist (§5.2.4 token validation, §12.8.4 signature checks, §12.9 fetch discipline), the signing proxy owes local caller authentication, the AP owes automated renewal, and none of it arms without a negative-path test suite. Call it a few weeks of careful sessions, not one. The policy rows iterate in production; the verifier does not. Phase 2 rides the same identities with separate evidence keys. Phase 3 is the research phase and the place we most want spec guidance — the draft is explicit that a PS is a high-value target with authenticated approval endpoints (§14.10–14.12), and a single-person self-hosted PS that meets that bar is the open design problem. Phase 4 is public-facing and waits for the drafts to settle, unless the Henkaku community wants to play early, which historically it does.

Once the sidecar has proven real policy shapes, we would propose native HTTPSig/AAuth verification upstream to the tracker's maintainer rather than keep the proxy pair forever.

7. Questions and feedback on the drafts

Status note: this section has now been through three states — written against -10, corrected after an independent-model review, and settled after the author read the middle version against the working draft (-11 in progress). Items his reading answered are marked withdrawn rather than deleted, because the trail is part of the feedback: where two careful passes still misread the drafts is a signal about what the documents could surface earlier.

  1. Pending grants across key rotation — open, and sharper than we first asked it. Our first two framings were wrong twice: the 5-minute figure bounds the resource token, not the pending approval, and "let any caller with the same sub key collect" names a thing that does not exist — pending state, resource tokens (agent_jkt), and auth tokens (cnf) bind to keys, not to sub, and honoring sub would demote proof-of-possession to identity-level. Fresh-resource-token-at-collect is also already normative, twice (Resource Token; Deferred Delivery). Our own architecture dissolves most of the successor problem anyway: the lane key lives in the signing proxy, which outlives sessions, so a successor session is not a successor principal. What survives, and what we now ask: the pending record's lifetime has no stated relationship to the token lifetimes flowing through it, and under the bootstrap two-key refresh pattern an agent token can rotate to a fresh ephemeral key while a grant is pending against the old one. Day-scale consent makes that the normal case, not the corner. Either pending state binds to the durable key, or rotation across a pending grant is forbidden, or re-presentation under a new key needs defined behavior.

  2. Artifacts at rest — open, home corrected. Half our trust surfaces are not HTTP: git handoff markers, review verdicts, ledger segments moved by file sync. We want an interoperable detached-signature envelope under AAuth identities. We first pointed this at the HTTP Signature Keys draft; that was wrong — a detached JWS over an artifact is not an HTTP message signature. It is a separate small companion document: domain separation from request signatures, artifact typing and canonicalization, verify-while-live-and-archive semantics, and durable-evidence keys kept apart from online request keys. Would a contributed draft be welcome?

  3. Custody for one operator, many agents — open, and smaller than we first thought. The bootstrap draft's self-hosted section assumes one agent per domain; our shape — one self-hosted AP, ten lane agents, dozens of ephemeral sessions a day — is the common self-hosted shape and is uncovered. What it needs is mostly the AP-key/agent-key distinction stated plainly: one AP key in the JWKS, N agent identities with distinct sub and cnf keys, agent keys living in their signing components and never published, and a sentence that for a self-hosted AP the parent can self-issue sub-agent tokens. Plus custody hygiene: per-uid isolation of signers, local caller authentication for anything that signs, rotation cadence.

  4. The proxy pair — open, narrowed to one hop. The roles section already permits the shape (roles are not deployment units; a signing proxy holding the lane key is the agent). Prior art exists on the resource side in our tracker's upstream (kenn-io/kata#58). The genuinely unspecified piece is the verifying-proxy-to-origin hop: how the proxy asserts the verified identity to the origin and the rule that the origin accepts it only from the proxy. One short section turns "AAuth in front of a legacy daemon" from folklore into a pattern — and it is how every single-static-token daemon will adopt this, if it adopts it at all.

  5. A personal person-server profile — open, mostly a floor statement. We twice misread the PS as heavier than it is: the callback is optional with polling as the completion signal, and a conformant PS is four metadata fields (issuer, auth_token_endpoint, person_token_endpoint, jwks_uri) with everything else OPTIONAL — but nothing says "this is the floor," so readers (we were two of them) infer the full surface is required. The asks: say the floor out loud in the PS metadata section; define out-of-band interaction completion (a PS completing consent on a channel it controls — a phone tap — and what happens to the single-use code in that case, since polling already carries the completion signal); and a personal-PS profile document, which is also the natural home for the pending-lifetime clarification in question 1.

  6. Budgets and payments — withdrawn, answered. The Budgets draft's scope section answers it exactly: not payment or settlement, no funds move, x402 and the commercial arrangement untouched — and it is denominated to compose with x402 (decimals, prior-art section). Deliberately payment-agnostic and deliberately composable is the unambiguous answer we asked for.

  7. Cross-namespace identity binding — open as a companion question. Out of scope for the protocol draft, agreed. The use case stands: an agent met over an x402 payment, recognized later by agent identity — our quest-enrollment plan. The ask reduces to: where would an attestation live by which an agent identity attests other keys it controls — AP metadata, an agent-token claim, or a companion document — designed pairwise/audience-scoped rather than as one public link-set, with consent and real revocation.

  8. The governance policy — new, and now our biggest question. The policy-evaluation section says the PS decides "based on user consent and … the mission's intent and prior log entries against the PS's governance policy," and no document defines what a governance policy is or how a PS reaches a decision; requirement=clarification exists on the wire with no described decision procedure behind it. This is where our consent tiers actually live (the resource declares per-call operations; the PS holds the standing rule), and it is what makes a personal PS worth building: without a decision procedure it is a queue with a protocol on it; with one it answers routine requests without waking the person. We run a hundred-deep human approval queue and a grooming lane that already tiers proposals into mechanical and judgment classes — if a governance-policy companion takes shape, we are a willing first deployment.

8. Tools and repos

AAuth itself: github.com/dickhardt/AAuth, aauth.dev, draft-hardt-oauth-aauth-protocol (-10, 2026-08-06).

Tool Role in the fleet Repo
kata Task-tracker daemon; the coordination ledger github.com/wesm/kata
jilog Session-transcript event ledger + nightly learning loop github.com/Joi/jilog
fresheyes Independent-model review gate github.com/Joi/fresheyes (upstream: danshapiro/fresheyes)
roborev Post-commit review patrol github.com/wesm/roborev
kwt Worktree/session manager for producer work github.com/wesm/kwt
NanoClaw Messaging-surface agent runtime (our cells run a pinned overlay) github.com/nanocoai/nanoclaw
Hermes Gateway runtime for the most-private surfaces github.com/NousResearch/hermes-agent
x402 Payment protocol our wallet implements (v2, self-hosted facilitator) github.com/coinbase/x402
trust402 / Lemma ZK identity + spend-limit proofs over x402 (FRAME00's) github.com/lemmaoracle/trust402, github.com/lemmaoracle/lemma
jibot The community agent; site serves markdown to agents site: jibot.md, quest: jibot.md/henkaku/ (repo private)
Producers Claude Code, Codex, and process skills claude.com/claude-code, github.com/openai/codex, github.com/obra/superpowers
Private opsctl, the marshal + niwashi + docket implementations, and the cell-fleet overlay private repos; architecture as described above, code shareable on request