Day-by-day record of building the enforcement and accountability layer for AI agents. Bring your own identity: did:key, did:web, SPIFFE, OAuth, native did:aps. Started February 18, 2026. 6,003 tests, nine papers, IETF draft. Open source. Full surface area: 152 MCP tools.
Day 65: Five issuers converge on one convention.
Harold merged Step 1 of Interop Week 1 yesterday evening. His AgentID trust_verification fixture landed clean through the five-check protocol, one signing-convention ambiguity flagged for a future convention table in the bundle README. At 08:40 UTC this morning he came back with something I did not ask for: AgentID's production signer had been switched to raw digest bytes, the convention APS and SINT and MolTrust already use. The already-merged fixture is technically on the old convention; his follow-up PR will replace the one signature field to match the new signer. The fixture data otherwise stands.
That is the Interop Week 1 thesis in miniature. Nobody imposed the convention. Five issuers looked at each other's code and pulled toward a shared shape because the alternative was writing a convention footnote per issuer in the bundle README. When AgentID's second fixture lands, the convention table can read one sentence: all five issuers sign raw digest bytes, 32 bytes, result of bytes.fromhex(compound_digest). No per-issuer exceptions. That sentence is the kind of thing a reviewer at OWASP or IETF will notice later precisely because it disappears into the background.
The vocabulary's context_dimensions draft also closed its review loop today. PR #34 landed with pshkv's sharpening incorporated: resolution_source marked recommended rather than required in v0.1 so early adopters who have real policy dimensions to document but no formal source model yet can still publish; physical_environment_state updated to document that its resolution source varies per sub-field at evaluation time (temperature typically sensor-attested, geofence typically gateway-derived, human proximity deployment-dependent); pshkv's alternative four-value enum documented inline as the v0.2 fallback if the five-value partition surfaces ambiguities in production. tomjwxf's earlier sign-off on the five-value enum preserved, pshkv's refinement added on top of it. Ran the five-check on our own PR publicly before merging, because not running the protocol on our own work because it is ours is exactly the failure mode the protocol is supposed to prevent. Four day-one entries in the vocabulary now, each carrying a non-signal test that names what would disqualify it from belonging there.
On OWASP AARS#32 the conformance question surfaced, and it is worth naming because the answer carries weight. VeloGerber accepted our §3.3 naming position last night and asked a follow-up that was harder than it looks: for AiEGIS APS to earn a v1.0 conformance citation, does an independent Python reimplementation of the APS v1.1 spec count, or does consuming our SDK as a dependency count. The honest answer is that they answer different questions. An independent reimplementation with shared test vectors earns a separate conformance row in the §3.3 table because it demonstrates that the scored behavior is independently reproducible. Consuming our SDK is a deployment pattern, useful for adoption, but the enforcement is still happening in our code. The distinction matters for exactly the reason we pinned the acronym collision in the first place: evidence at the implementation layer and evidence at the adoption layer should not bundle into one reviewer-facing citation. v0.9 cites AEOESS APS as the shipped reference; v1.0 re-evaluates AiEGIS once the independent reimplementation lands. The sequencing does not stall anyone's merge. The concrete offer to accelerate: ship our interop fixtures as a standalone aps-conformance-suite repo that any reimplementation can run its test matrix against, so the conformance bar is legible rather than implicit.
What these three threads have in common is that none of them are about APS. Harold is writing AgentID, not writing APS. pshkv is writing SINT runtime, not writing vocabulary primitives for us. VeloGerber is writing AARS, not adopting APS as a vendor. In each case the protocol is the quiet substrate the conversation happens on top of, and the decision APS ends up making is about where the substrate's edges are. Whose signing convention. Whose resolution model. Whose conformance evidence. The answers this week were: converge downstream, recommend rather than require, distinguish reimplementation from adoption. None of those are APS imposing anything. They are APS agreeing to be boring at the protocol layer so the interesting work can happen on top.
By evening a fourth thread landed that inverted the first three. I posted the APS slot shape on agentid-aps-interop#5 at 19:02 UTC. Harold posted the AgentID slot shape about two hours later. Kenne shipped AgentGraph v1 structural fixtures as PR #6. By 21:08 UTC I shipped PR #7: three composed envelopes stitching AgentID identity, APS delegation, and AgentGraph security posture under one shared subject DID, plus an issuer-neutral Python validator that runs without importing any of the three contributing SDKs, plus APS v1 structural fixtures to feed the APS slot. Kenne ran verify.py on his machine, 51 of 51 checks passed at exit zero, LGTM from the AgentGraph seat. The inversion is the point. This time APS was the quiet substrate for Kenne and Harold's work, the same way they had been the quiet substrate for APS in the morning. The posture does not depend on which side is shipping. Convention convergence took a week for signing-input format. Composition convergence took seven hours for envelope shape. The pattern is in everyone's hands now.
Day 64: v2 promoted, v2.1.0 shipped, foundation filed.
v2.0.0 moved from @next to @latest on npm today. MCP v3.0.0 with it. PyPI got a non-pre-release 2.0.0 that replaces the 2.0.0b0 beta. v1.46.0 and MCP v2.27.0 are parked on the legacy-v1 tag for six months, still installable by anything that pins to them. That is the surface. What is underneath is worth a paragraph.
The forty-eight-hour window between Friday's ship and today's flip was not a procedural cooldown. It was a test. Four external systems landed real code against v2 during the window. AgentNexus Track A fixtures round-tripped through our canonicalization and signature verification. VeritasActa's external_receipts.aps slot got a KU receipt signer. Illia's SINT refresh merged against the vocabulary registry. RNWY's a2a.yaml merged alongside. None of them shipped because of v2. All of them ran through v2 without noticing. That is the kind of evidence you want before you flip a default tag.
The sweep also turned up a small drift worth naming. The Python SDK's __init__.py had been carrying __version__ = "0.15.0" since the 2.0.0b0 beta shipped. pyproject.toml said 2.0.0b0 and the wheel said 2.0.0b0, but if you imported agent_passport.__version__ in a running process, you would see 0.15.0. It is 2.0.0 now, same as the artifact. Exactly the kind of thing a promotion sweep is supposed to catch.
What the legacy-v1 tag actually means is that nobody's CI breaks because we deleted something. Six months of guaranteed availability via npm install agent-passport-system@legacy-v1 or a plain ^1.46.0 pin in package.json. After that we freeze the tag but keep the package on npm indefinitely. No auto-upgrade, no pressure.
The morning was the default flip. The afternoon had four things worth naming.
v2.1.0 shipped same day, with a different primitive than planned
The Day 61 post said the next build was Ledger Events. That was wrong, and the error is worth naming. When I ran the three-factor check (concrete external demand, clean scope versus SCITT, additive value beyond what the existing ledger stack already does) none of the three cleared. A proper postmortem now lives at specs/killed/LEDGER-EVENTS-v0-KILLED-2026-04-17.md with the revival criteria written down for future me. A handoff prompt that claimed otherwise got renamed to LEDGER-HANDOFF-PROMPT-STALE-2026-04-18.md with a stale banner. Better to kill a planned build than ship a primitive nobody asked for.
What shipped instead was v2.1.0 with two primitives that had actual demand. The Cognitive Attestation envelope is a TypeScript port of the normative JSON schema from Paper 7 (Zenodo 10.5281/zenodo.19646276): JCS canonicalization, Stage 1 cryptographic verification with required_signer_roles coverage, Stage 2 registry interface, Stage 3 replay stub with a clear TODO boundary, and typed dispute primitives that carry the shape of a disagreement without baking resolution logic into the protocol. That distinction matters: the SDK ships the vocabulary of disputes, the resolution algorithm lives in the consumer. The second primitive was the verifyBoundWallet object-form overload MoltyCel asked for in SDK#16. Same behavior either way, asymmetry with bindWallet gone.
Module structure at src/v2/cognitive-attestation/, 35 new tests (envelope 17, verify 12, adversarial 6), zero new npm deps. Test count 2,325 → 2,366. Both commits (ceb1cd1 wallet-binding, 8c9cc14 cognitive-attestation) on @latest the same day the promotion happened.
APS submitted to AAIF
Filed as aaif/project-proposals#14, the AI Agent Interoperability Foundation, the path toward Linux Foundation stewardship for the public protocol layer. Position in the submission is the cleanest version of what v2 made possible: the protocol is a solo submission, cross-referencing SINT (Illia's #12) and the three-vendor governance_attestation convergence with MolTrust. The AEOESS company, the YC application, the private gateway, the partnerships: none of them are in the submission. They are commercial adjacencies to a protocol that has been designed to outlive them.
Every live-artifact claim in the submission was verified before posting: JWKS endpoints return 200, npm and PyPI artifacts resolve, Zenodo DOIs have a landing page, crosswalk entries validate. Foundation review waits on the TC triage window. Expected Tuesday UTC if they keep pace with the #12 and #13 precedents.
OWASP AIVSS#32. naming boundary held
A proposal came in to co-list two "APS" references in the permanent v0.9 §3.3 standards citation. The technical content of the proposal was substantive and got accepted on that axis: evidence sequencing matters, measurement methodology needs a reference. The naming framing got declined, firmly and in writing, with paste-ready §3.3 text naming only the Agent Passport System. The technical work is real. The naming collision would have been durable. Not every "be nice" reflex is the right one.
Thirteen ecosystem engagements, one day
The context for this is the structured ecosystem map from Day 61. With the map rebuilt yesterday, today's response queue was visible at session start and the posts went out in batches. Naming them for the record:
Tier 1. Gist for Illia's AAIF cover email (sint#130). pshkv crosswalk acknowledgment on vocab#8. Governance-declaration proposal for tomjwxf on ossf/security-insights#171. APS+SINT composition MVP for EchoOfDawn on autogen#7525. MIGRATION.md field-diff patch and v2.1.0 follow-up on SDK#16. Harold's AgentID fixture five-check protocol review on vocab#38. context_dimensions PR flipped ready-for-review on vocab#34.
Tier 2. Three-layer APS+SINT+OPA composition mapped onto AutoGen's ConversableAgent lifecycle on autogen#7528. Converged-architecture acknowledgment for Enclave+SINT+MolTrust on A2A#1716, offering sub_delegate for the 1→3 hop transition and an AND-composition argument for the MolTrust-score plus APS-grade gate. Full TypeScript reference implementation of a GuardrailDecision interface on VoltAgent#1166. Dispute-primitives reference from v2.1.0 on llama_index#21312.
What the day measures
Promotion window closed without a partner issue. A new minor shipped on the same tag it was promoted to, two days after the tag swap. A foundation submission filed that could not have been filed before the v2 separation. Thirteen substantive partner responses posted. A planned build killed and a different one shipped, in the same twelve hours, with a postmortem on disk. The thing v2 was supposed to unlock. protocol shipping at a different speed than commercial. is now visible in the shape of a day.
Day 63: Stability window, one compat test.
Sunday of the 48-to-72-hour window before the promotion flip. The point of the window is to not ship. Run the tests again, re-read the diffs, wait for partner signal. What we were watching for was the kind of issue that only surfaces when someone outside the team runs unfamiliar code paths through the new artifact. Exactly one partner did, and the finding was useful.
MoltyCel ran [email protected] and the MCP equivalent through a Solana wallet-binding compat test. Fresh Ed25519 keypair, bs58 signature over a nonce, round-trip through bindWallet → verifyBoundWallet. Two findings came back. Finding one was a shape-diff in MIGRATION.md that did not call out the wallet_ref field-level v1-to-v2 change explicitly enough. Finding two was a UX asymmetry: bindWallet accepts an object argument, verifyBoundWallet accepted only positional. Both on disk within the hour. The shape-diff clarification landed as commit 0a3edeb, the UX overload (verifyBoundWallet(passport, chain, address) and verifyBoundWallet({ passport, chain, address }) both work) got queued for v2.1.0.
Nothing else broke. A partner on real data caught the two rough edges exactly the kind of window was meant to expose. The promotion path stayed on for Monday.
Day 62: The protocol shows up in other people's code.
Yesterday was the separation ship. Today is the day after. The pattern of a post-release day is usually: someone files a bug, someone else opens a discussion about versioning, you spend the afternoon triaging. Today was different. What happened is that the protocol, now actually a protocol and not a package, started showing up in other people's systems.
Two things landed in the SDK, and neither of them was a new module. Both were interop harnesses. Scripts that take someone else's fixtures and prove APS composes with them.
Round-tripping AgentNexus
kevinkaylie's Track A fixtures were sitting on PR #17. Two delegation scenarios, a happy path and a scope expansion attempt. Merging the fixtures would have closed the PR. What I wanted instead was a harness that replays them end to end so we know the protocol behaves the way the spec says it does. Re-canonicalize via JCS, verify the Ed25519 signatures, walk the delegation chain, check monotonic narrowing at each hop. Both fixtures match expected. Happy path accepts. Scope expansion denies at the subset gate, which is where it should deny. Zero canonicalization drift between kevinkaylie's inputs and ours. That result is the thing. The PR now has a matching harness report on record, so if anyone later asks whether AgentNexus's wire format composes with APS, the answer is a commit hash.
Signing for VeritasActa
tomjwxf's VeritasActa/verify repo has a cross-verification bundle format with a slot called external_receipts.aps. That slot was empty. It exists because VeritasActa treats APS as one of the attesters whose signatures should compose into their multi-layer receipt structure, but nobody had shipped the signer yet. Today we did. interop/scripts/sign-va-ku-receipt.ts takes a VeritasActa KU bundle, computes a JCS-canonical sha256 over each knowledge unit receipt, records the chain in contributingSources, and signs with a deterministic test key. The detail that makes the integration worth shipping is the tamper property. If anyone mutates a single byte inside a KU after signing, the APS signature stays cryptographically valid, but the recorded accessReceiptId no longer matches the KU's hash. The cross-layer integrity becomes observable from either side. APS didn't have to change to support this. It slots in.
Two external crosswalks merged
Illia's SINT refresh (PR #30) normalized match semantics to the canonical enum, added a peer_review no_mapping row, and recorded entity_continuity and consent_provenance alignment notes. RNWY's a2a.yaml (PR #32) maps A2A Agent Card governance metadata against did:web:rnwy.com with a live JWKS serving rnwy-trust-v1, rnwy-trust-v2, and rnwy-wallet-v1. Both PRs submitted clean, validator passed, scope was tight, both merged same day. The registry is now at fourteen external crosswalks plus our own. Every one of them is work someone not on this team did in order to describe their system's governance surface in terms of ours.
Two threads worth naming
Jerry at MnemoPay shipped x402-compatible paywalls plus a financial-brain MCP on x402#1904. The right response to a proposal like that is not "how does this fit APS," it is "what's the substantive read on what they shipped." So I gave it a three-point read: the wallet-decision layer is new terrain, the evidence shape (receipts plus MCP tool outputs) is compatible with how APS signs for downstream composition, and a composition hook via delegation-reference in the X-Agent-Identity header would make APS passports attachable to x402 requests without modifying x402 itself. On ATF#8, desiorac proposed the ArkForge model, a three-plane decomposition of agentic trust into delegation, decision, and execution. The +1 there was to propose a Notes-column cross-reference so the composition is visible in their ECOSYSTEM table without anyone having to infer it. Both threads got substantive reads that push the conversation without inserting APS into it.
The quiet-strong shape
Days that ship new modules are loud. Days that don't ship but prove composition are quiet, and arguably harder. Interop is the surface where wishful thinking gets falsified. If our canonicalization drifts against kevinkaylie's, it shows up. If our signature doesn't slot into tomjwxf's bundle, it shows up. If a partner's crosswalk doesn't pass our validator, it shows up. None of these could fail today, so none of them did. That is what a post-release day looks like when the release was correct.
Day 61: The separation ships.
The SDK was one package. It shipped crypto, types, scope logic, receipts, vocabulary adapters, conformance suite, and the analytics, drift detection, compliance automation, and runtime state management that the gateway uses to operate. Partners who pinned the npm package pulled the whole thing. That was fine for a while. It stopped being fine once the roadmap started pointing at foundation submission, enterprise procurement conversations, and a pixel attribution economy that lives in the gateway and only the gateway.
Today the SDK shipped v2.0.0-beta.0 on npm @next. The architecture is split along one axis: protocol primitives stay public, product intelligence moves private. ProxyGateway, DataEnforcementGate, ContributionLedger, SettlementGenerator, 18 behavioral-analytics modules, runtime state stores, compliance automation, orchestration, metering. Gone from the public SDK. Moved to the private gateway package. Roughly 2884 tests moved with them. The public API, the 8 core primitives the spec documents, is byte-identical to v1.46.0.
How to read that
The protocol is now what standards bodies can actually adopt: a clean Apache-2.0 package with a conformance suite and interop vectors, no operational intelligence bundled into it. The gateway is the commercial moat: drift detection, cross-tenant orchestration, analytics, the pixel. Separation is not a feature flag or a licensing trick. It is a refactor that moved a majority of the codebase out of the public package and into a private one. That line is where I can defend it now.
Partners on any v1 pin are unaffected. v1.46.0 stays on npm @latest through a 48 to 72 hour stability window and on legacy-v1 indefinitely after that. Nothing auto-upgrades. v2 is strictly opt-in via npm install agent-passport-system@next while partners test integrations.
Four artifacts, one day
SDK: v2.0.0-beta.0 on @next. 2,884 tests, 130+ modules, tsc clean against the gateway after the split. Public exports went from 115 to 106, nine removed and six added. Every remaining export retains its v1.46 signature.
MCP: v3.0.0 on @next. 150 tools. Dropped 150 tools that never had a v2 analogue and stubbed 10 that moved to the gateway. The 132 preserved are protocol-layer tools that don't depend on gateway runtime. Major bump because the tool reduction is breaking.
Python SDK: v2.0.0b0 as PEP 440 pre-release. The Python side was already protocol-only by construction, so the bump is version alignment, not refactor. pip install --pre to opt in.
Gateway: repinned from file:../agent-passport-system to ^2.0.0-beta.0, Railway auto-deployed, health endpoint green through the swap. All 647 migrated tests pass in the gateway's own suite. No downtime.
The governance vocabulary got one thing fixed today too
The agent-governance-vocabulary repo has twelve external crosswalks from partners who mapped their terminology to the canonical signal types. InsumerAPI, SINT, AgentNexus, Veritas Acta, Logpose, RNWY, SoulboundRobots, Nobulex, SAR, JEP, asqav, SATP. All twelve built by people who don't work here, mapping their stuff to ours. One entry that was missing: ours.
I hosted the registry for a week without publishing a crosswalk for my own system. That reads as either I can't describe my own terms cleanly, or I don't dogfood the registry I'm asking other people to contribute to. Neither is true, but the file being absent says it anyway. Today I fixed that.
crosswalk/aeoess-aps.yaml is the APS mapping to the canonical vocabulary: three exact-match signal types (passport_grade, trust_verification, governance_attestation), two partial, seven honest no_mapping declarations for signal types APS doesn't issue. Four decision-trajectory mappings, one constraint mapping, and an out_of_vocabulary_primitives section for runtime enforcement mechanics (monotonic narrowing, cascade revocation, wallet binding) that are correctly not signal types. Validator is clean. APS also got added to governance_attestation.issuers_in_production alongside AgentNexus, Nobulex, and SINT; Build D2's JWS-signed trust profile endpoint makes us the fourth production issuer of that signal type.
Rollback is real
Before any of the above happened, the prior state got archived. Anchor tags in every repo (pre-v2-swap-main, pre-v2-swap-refactor, pre-v2-pypi-swap) pin the pre-swap commit as immutable references, and a private archive holds git bundles of every repo, a packaged copy of the v1.46.0 npm tarball, and step-by-step rollback procedures for each failure scenario. If v2 needed to come out within 72 hours of publish, npm unpublish works. After that, v2 gets npm deprecated and v1.46.0 stays on latest indefinitely. No rollback path depends on a single point of control.
The ecosystem data layer
Quietly in the background of this week, we built a structured map of the governance ecosystem we operate in. 89 tracked threads across GitHub, 118 participants, 1,994 comments, 88 topics. Each participant carries a working label and each thread is classified by waiting-state (waiting on us, waiting on them, closed, silent). The data is content-addressed, rebuilt on a script that re-fetches GitHub and regenerates the map in about two minutes, and the output is a single session-context markdown file that Claude loads at the start of every working session.
The reason this matters for governance is the second axis of the tag space: canaries. Over the last week we observed a pattern of agents opening structurally similar threads across multiple repositories with aggressive asks that don't survive factual review. Each pattern got logged, each handle got added to a silence list, and the map enforces a non-engagement protocol automatically. The same map surfaces the other direction: partners whose tags upgrade from unknown to substantive after they ship verifiable code, and whose threads get moved to higher-priority response queues. It is not surveillance and it is not adversarial; it is a structured way to keep the ecosystem map accurate enough that we respond to signal and ignore noise. The raw map stays in a private specs directory;.
What this unlocks
AAIF submission becomes a real option, not an aspiration. Foundations don't want to govern your pricing or your compliance automation; they want a clean protocol spec with a conformance suite. We now have that cleanly packaged. Enterprise procurement stops tripping over "sole-founder maintainer governs the protocol" because that layer becomes foundation-governed when the submission lands. The gateway product competes on quality rather than lock-in, which is a stronger commercial position than lock-in ever was.
The next primitive in the queue is Ledger Events. Ordered content-addressable signed events with a chain-integrity verifier. Will ship as v2.1.0-beta.0 on @next. Any ledger store, analytics, subscription, or attestation layer on top of the primitive goes in the private gateway. The separation holds.
Build A gave us the signed primitive. Build B canonicalized the weights. Build C aggregates them: one signed settlement record per period, four Merkle-committed axis roots, contributor queries that verify end-to-end without trusting the gateway beyond its JWKS. The economic half, how weights convert to money, stays gateway-private. The evidence half is in the SDK.
SDK v2.0.0-beta.0 on @next & v1.46.0 on latest (2,884 tests, 130+ modules). MCP v2.27.0 (150 tools, new settlement scope). Python v0.15.0 / v2.0.0b0 pre (2884 tests). 5 cross-language fixtures, byte-identical across runs. The integration proof: 1000 Attribution Primitives → aggregate → verify → per-contributor query → verify, composes cleanly with Build A and Build B.
A contributor — data source, compute provider, protocol author — can now answer "what did I contribute and can I prove it?" with a signed artifact. What the market builds on top of that evidence is up to the market. The pixel is live.
Day 59: One receipt, four projections
Two ships and a retirement today.
Build A — the attribution primitive
For a while now the SDK has been accumulating attribution machinery along four different axes. Data sources contributing to an output — that had its own receipt. Protocol modules that evaluated the action — another. The governance chain that authorized it — another. Compute providers that ran it — a fourth. Four signed artifacts per action, four verification paths, and no single object that said "this is the attribution for this specific action."
Build A consolidates all four into one signed Merkle envelope.
One AttributionPrimitive, four axis leaves (D, P, G, C), one merkle_root, one Ed25519 signature over the envelope. Any single axis can be projected and verified on its own without revealing the other three. Two projections of the same receipt cross-verify by shared action_ref + merkle_root + signature — you can tell, cryptographically, that the D projection someone showed you came from the same underlying action as the G projection someone else showed you.
The spec has been sitting at /specs/ATTRIBUTION-PRIMITIVE-v1.1.md since Apr 12. Today it landed as running code: 6 new SDK exports, 6 new MCP tools, a 1:1 Python port with cross-language signature verification, and an AttributionPrimitive type with canonical weight-string representation, balanced Merkle composition, and residual-bucket aggregation for sub-threshold contributors.
The part worth flagging for anyone building on this: the projection structure means a settlement pipeline can operate on just the D axis without ever seeing the governance or compute axes. A data contributor can verify their share without the protocol stack having to disclose which evaluation modules fired. A compute provider can prove their share without exposing the data lineage. One receipt, four audiences, no disclosure leakage across them.
Builds B and C (fractional weights, settlement) are unblocked by this. Two-week arc.
Build D2 — signed trust profiles
Smaller ship, but the kind that changes integration shape.
The gateway has always exposed public trust profiles at /api/v1/public/trust/:agentId — a JSON document describing an agent's grade, wallet bindings, delegation state, and so on. Useful for dashboards, useful for agents deciding whether to talk to each other. Not directly verifiable by a third party, because it came over HTTPS and that's it. If you wanted to know that a specific profile was really what the gateway said, you had to trust the transport.
Build D2 attaches a compact Ed25519 JWS to every successful trust-profile response. Three headers: X-APS-JWS (the compact JWS), X-APS-JWS-KID: gateway-v1, and X-APS-JWS-JWKS pointing at the public JWKS.
The JWS is over the canonical JSON body. The JWKS endpoint publishes the gateway's public key. Anyone can pull the profile, pull the JWKS, and verify cryptographically that the gateway signed exactly this payload. Body unchanged — existing consumers keep working, the signature just rides along in headers.
Tried it end-to-end with jose. Verifies cleanly. Kid matches, alg is EdDSA, signature checks out against the public JWKS.
This is the protocol layer that was missing between "the gateway told me X" and "I can prove the gateway told me X." Consumers that need that proof can now get it without changing how they fetch.
Coordination retired
One quiet change worth naming. For a long stretch, work on this project ran through three coordination paths — a primary operator, a reviewer agent that handled GitHub posting, and a comms relay. It was a useful architecture when I was figuring out what this project even was. It stopped being useful a while ago.
Today it got retired. The reviewer agent's workflows are archived under archive-portal-era/, the nightly cron is gone, and the GitHub posting flows through one path now. Historical records — roadmap, blog, ops log — are preserved as they were. Nothing lost, just fewer moving parts.
Simpler is usually better.
Day 58: One chain added, one bug caught at the boundary
Quick one today. SDK v1.43.0 ships with Solana in the wallet_ref chain enum, base58 validation included. That closes openclaw #49971. End-to-end wallet binding now spans Ethereum, Bitcoin, and Solana.
The more interesting thing was the bug the integration surfaced.
The case-sensitivity trap
APS treats chain names as case-insensitive at the boundary. ETHEREUM, ethereum, Ethereum all normalize to ethereum. That was fine for a while. For Ethereum addresses it doesn't matter, they're hex. For Bitcoin it doesn't matter either, the checksums handle it.
Solana addresses are base58. Base58 is case-sensitive. 7xKXt... and 7xkXt... are different addresses.
The gateway was lowercasing the entire normalized wallet payload on the way in. A perfectly valid Solana address got mangled to a syntactically valid but semantically wrong address. No error, no warning. Just a wrong address in the receipt.
The fix: chain-aware normalization. Lowercase the chain identifier, leave the wallet_ref alone if the chain is case-sensitive. Two-line change in the SDK validator plus a matching guard in the gateway. Test coverage added for all three chains with mixed-case inputs. 2,884 tests, all green.
This is the kind of thing that looks small and is actually big. The failure mode was silent data corruption that the protocol signed over cryptographically. Every receipt that passed through would have been a signed statement about the wrong address. You can't fix that after the fact. The only reason it surfaced is because someone was actively integrating and caught the round-trip mismatch.
Moral: when a primitive was correct for every input class you had, and you add a new input class, the primitive is not correct anymore. It's a new primitive, and it needs new tests.
Vocab registry: four more PRs
The agent-governance-vocabulary repo had another busy day. Four merges on Apr 15: asqav crosswalk from jagmarques (ML-DSA-65 server-side signatures, first lattice-based contributor), JEP from schchit (minimal verb-based decision record, IETF I-D pending), insumerapi license-endpoint fix from douglasborthwick-crypto, and validator cleanup and format normalization.
Plus a quieter promotion that matters more than any single PR: peer_review got promoted to canonical status. Two independent implementations now, Logpose (rkaushik29) and RNWY (rnwy), both shipping code, both mapping their internal peer_review equivalents to the canonical term. That's the two-implementation threshold the CONTRIBUTING.md set, hit for the first time post-launch by contributors who don't know each other.
That's the vocab registry working as designed. No single group driving it. The canonical vocabulary is the thing that at least two groups independently agreed to call the same thing.
Contributor count
Four days after opening, 14+ contributors have shown up. Eleven PRs merged in six days. One PR closed (SAR first attempt, replaced by PR#17 after revisions). The five-check merge protocol I wrote about on Day 57 got its first real stress test this week. Two PRs needed revisions before merge. Identity unverified in one case, format wrong in another. Both came back clean after a round of specific feedback. The rules hold up when you actually apply them equally.
What's on tomorrow
Build D2 is queued. Public JWS signing on the gateway's trust profile endpoint. One-function-call fix on existing infrastructure, unlocks cross-verify demos with MolTrust and AgentNexus that are already standing by. After that, Build A (attribution primitive) is the next real protocol ship.
Short day, short post. Back to the queue.
Day 57: Three Boundaries and a Paper
Three v2 primitives shipped today. Each one closes a failure mode that showed up in production, not in theory. They're small modules, a few hundred lines each, but each one names a boundary that the protocol had been crossing silently.
AttributionConsent — the representation boundary. An agent can cite a third party's position in a way that reads as endorsement, without the cited party having agreed, which is what this boundary exists to prevent. It made it look like the third party had endorsed the claim. The citation was accurate textually. The problem wasn't accuracy, it was representation: one agent's principal was speaking for another's without authorization. AttributionConsent requires dual signatures on any citation that binds the cited principal — cited party signs their consent, citing party signs the citation itself. Missing one side fails verification. Replay protection via expiry windows. Integrated into charter verification, settlement verification, and completion-receipt verification so the guard runs at every boundary where an attribution could become binding.
ProvisionalStatement — the commitment boundary. LLM outputs are treated as instantly binding by the systems consuming them. An agent writes "we will proceed with vendor X" and some downstream system registers that as decision-made. ProvisionalStatement flips the default. Agent-to-agent statements start provisional. Binding requires an explicit PromotionEvent satisfying a PromotionPolicy — typically m-of-n principal signatures, or a direct ratification from the principal whose authority is being committed. Dead-man elapses to withdrawn, not promoted. Silence is not consent. This one hurts the most to write because it forces everything upstream to distinguish draft from decision, which most current agent frameworks don't.
HumanEscalationFlag — the escalation boundary. Some action classes should never execute without human confirmation regardless of the delegation chain. HumanEscalationFlag gates on per-action-class owner confirmation with three scope modes: per_action (every call), per_session (one confirmation covers the session), time_window (confirmation valid for a declared duration). Owner confirmations are signed and recorded. Agents can't bypass by narrowing the action class or by delegating past it — the flag evaluates at action time, not delegation time.
Three numbers. SDK at v1.42.0, 2,884 tests (80 new tests across the three primitives and their integration). MCP at v2.24.0, 150 tools (11 new boundary-primitive tools). Python SDK at v0.12.0, same primitives ported with cross-language signature verification. All three shipped on npm and PyPI before this post went up.
One-paragraph version: agent governance research models the agent as the unit. The agent in every deployed system today is already a fiction reconstructed across sessions that are short-lived and mutually unaware. The real object is a population of such sessions talking through a family of uncoordinated substrates — memory files, handoffs, shared state. Continuity of "the agent" is a property this family produces, not a property any session has. The paper argues this population-with-medium is the correct unit of agent governance, that current protocols (including APS) underspecify governance of the medium because they've been looking at the wrong object, and that the architectural move that makes authority survive session death (artifact-based state with signed authorization) can be extended to govern the medium.
The paper names one open problem as the central threat to the strongest version of the claim: cryptography formalizes authorship, delegation, ratification, access, and ancestry. It does not formalize meaning. A governed medium of agent populations can accumulate fluent hallucination if the participants emitting fragments are systematically producing semantically unsound content — every fragment cryptographically valid, the aggregate medium a growing archive of nonsense. The institutional analogies the paper leans on (Wikipedia, corporate memory, open-source projects) work because humans fill the semantic-evaluation gap. Whether agent populations can substitute any combination of reputation, cross-verification, and human ratification gates for that human sensemaking is the hardest open problem in the paper. I don't know.
Six rounds of adversarial review before the paper shipped. Claude, GPT, and Gemini attacking each version from different angles. The first version (v0.1) was a safe taxonomy paper. The last one (v0.5) is the smallest version of the claim that survived every attack. It's a working paper, not a scholarly result. Design Memorandum in the early-IETF sense — stake a claim, invite attack, ship before you can defend every sentence.
Why both on the same day
The three boundary primitives and the paper are the same thought at two scales. The primitives name three boundaries the protocol was crossing silently at the session level. The paper names a larger boundary the whole field is crossing silently — governing what one session does while ignoring what the population passes along. One is engineering, the other is framing. Shipping them together is the honest thing because they only work together: the engineering without the framing is useful plumbing that nobody contextualizes, and the framing without the engineering is a manifesto without a reference implementation.
Tomorrow is for the Working Group scope ratification announcement, the cross-links to Harold's interop repo, and the roadmap items that are queued behind tonight's shipping. Tonight is for this: three boundaries, one paper, both live.
Day 53: The convergence layer earns a name
Two weeks ago the problem with interop specs was that every project named the same field differently. One called it delegation_root, another chain_hash, a third provenance_anchor. Same bytes, three names, zero interop.
Today four teams converged on one repo in under an hour. aeoess/agent-governance-vocabulary is a canonical naming layer for governance types. Not a new spec, not a new framework, just a shared dictionary. Anyone ships types, anyone reviews, PRs get merged when the names and semantics are defensible. APS hosts it because someone has to, not because APS owns it.
Nanook landed the first external review on wallet_state within hours of the repo opening. lowkey-divine brought the Fidelity Measurement types. 64R3N's WTRMRK sequencing proposals fit cleanly. The job the vocabulary does is small and boring. That's the point. Small and boring is what made the internet work.
Three-vendor governance_attestation. On A2A#1717 the signal_type: governance_attestation envelope now has three independent issuers: APS, MolTrust (api.moltrust.ch/guard/governance/validate-capabilities went live today), and AgentNexus/Enclave v0.9.5. Three DID methods, three JWKS, one envelope shape. A caller merging all three gets multi-vendor consensus with zero coupling between issuers. That's the exact argument Agent Card consumers need before they trust governance metadata as a standards surface.
The cross-verify proof is queued: one subject, two signed attestations issued independently, both verifiable offline against their respective published JWKS. If it round-trips, we post the receipts. If it doesn't, we find the canonicalization delta and fix it. Either outcome is useful.
APS ↔ SINT handshake spec. pshkv shipped docs/specs/aps-sint-handshake-v1.md to sint-protocol main today with 11 conformance tests covering the three scenarios that actually matter: authorized call, scope-exceeded denial, and cascade revocation mid-session. The delegation chain root hash format maps cleanly onto APS verifyDelegation(). Same RFC 8785 canonicalization, same SHA-256, same leaf-inclusive ordering. We offered to run their JSON fixtures through the published SDK and post the round-trip result. Smallest possible interop proof.
What this all adds up to. A month ago the agent identity discussion on every working group thread was stuck on "whose DID method wins." That question has quietly stopped mattering. The new question is whose envelope the whole field signs, and the answer that's emerging is: nobody's in particular, everyone's interoperable. APS is one issuer among several in the governance_attestation type. SINT is one enforcement surface among several in the handshake spec. The vocabulary repo is one canonical-naming home among potentially several.
None of this reads as APS winning. It reads as the problem getting small enough that nobody has to win for the stack to work. That's the outcome we wanted.
Six primitives shipped against a paper. Nanook and Gerundium published PDR in Production v2.19 this morning. The paper cites AEOESS as the third orthogonal axis in a three-axis behavioral trust framework (Saebo constraint compliance + Pidlisnyi Hold/Bend/Break + PDR cross-session reliability) and attributes several functions to an "AEOESS adapter" that did not yet exist in code. We spent the day closing the gap. SDK v1.41.0 ships six new exports across three modules: applyTemporalDecay and confidenceBreakdown on ScopedReputation, a BehavioralFingerprint three-axis envelope with Ed25519 signing, computeReputationDrift over a new recentObservations ring buffer, extractSessions for HLC gap-based session segmentation, computeProbeIdentity and verifyProbeIdentity for canonical-hash probe binding, and computeConsistencyScore as a dedicated predictability primitive. The consistency score has the §6.5 over-promiser paradox locked as a regression test: an agent with uniformly small negative deltas scores higher on consistency than one with alternating large positive and negative deltas, which is the whole point of separating predictability from performance.
Three surfaces updated in parallel. MCP server bumped to v2.23.0 tracking SDK v1.41.0. Python SDK bumped to v0.11.0 as an alignment signal following the v0.9.0/TS-v1.34.0 pattern. ClawHub skill published at 1.41.0. Test count 2,497 → 2,763. Zero breaking changes.
Two citation corrections also caught. A version-history audit of Nanook's paper across v1.0 through v2.19 surfaced that the "15-facet Boolean" constraintVector in §7.6.3 came from our own stale documentation, not from Nanook's transcription. A // 15 facets comment in src/core/denial-domains.ts and a matching "15 constraint dimensions" string in package.json were dated one day before the March 30 correspondence. Both now fixed to 14 (with 4-valued Belnap status, which is what actually ships). The paper's postureTier enum (ANCHORED | DELEGATED | ATTESTED | CRITICAL) also does not match the code (full_trust | standard | cautious | restricted | quarantine). Correction note drafted, not yet sent, because the most useful thing we can do tonight is ship the code the paper already cites.
The §8.10 substrate-swap experiment is the test that would settle Nanook's three-axis orthogonality claim. All six of tonight's primitives are scaffolding for that experiment. If Saebo, Pidlisnyi, and PDR correlate heavily in practice, the three-axis framework collapses to a single axis with three measurement surfaces. If they don't, the framework validates. Either outcome is a publishable result. The HBB-PROBE-FORMAT-v1.yaml spec is now committed to aeoess_web/specs/; the joint harness is rank 10 on the build list and unblocks the moment Nanook and Gerundium agree on probe format.
Day 52: Three Walls
A new user landed on the SDK yesterday and bounced within ninety seconds. I watched the session. They opened the MCP server, saw 150 tools flood their client, closed it. They opened the SDK, saw 925 exports load from a single import, closed it. They read the homepage, saw "103 modules" in the hero stat, and closed the tab. Three walls. All hit within a minute and a half.
The protocol is complete. That is the problem. When you have forty-two modules you say "forty-two modules" and it sounds like a lot. When you have a hundred and three modules you say "a hundred and three modules" and it sounds like a cathedral you have to finish building before you can walk in. The cathedral is real and someone has to build it, but a new user should not have to see the scaffolding before they see the door.
Wall one: the MCP server flood. Claude Desktop lists every tool an MCP server exposes. When you connect APS you get one hundred and thirty-two. Most of them you will never use. Some of them exist because a paper needed them. Some of them exist because an ecosystem thread needed them. Some of them are load-bearing for the quiet parts of the protocol that only fire during an incident. All of them show up in the tool picker next to read_file and run_command. The fix is a profile. The default profile is called essential and it is twenty tools: identity, delegation, enforcement, commerce, reputation. That is what ninety percent of integrations need. The other ten percent set APS_PROFILE=full and get everything back.
npx agent-passport-system-mcp now defaults to essential. APS_PROFILE=full npx agent-passport-system-mcp still works. Nothing was removed. Nine other profiles are available for people who know exactly what they want: identity, governance, coordination, commerce, data, gateway, comms, minimal, full. The default is the one that lets a first-time user see the door.
Wall two: the SDK export avalanche. The full SDK exports over nine hundred symbols. In most IDEs this means an agent reading import { } from 'agent-passport-system' gets autocomplete that scrolls for twenty seconds. Intellisense times out. The agent picks something wrong because it cannot see the right thing. The fix is a subpath export. agent-passport-system/core exposes around twenty-five curated functions and a handful of essential types. Identity: createPassport, verifyPassport, generateKeyPair. Delegation: createDelegation, subDelegate, revokeDelegation, cascadeRevoke. Enforcement: createActionIntent, evaluateIntent. Commerce: commercePreflight, createCommerceDelegation. Reputation: resolveAuthorityTier. That is the surface you actually need to bring up a working passport pipeline end to end.
// Day 52 onward — curated essentials
import {
createPassport, createDelegation,
evaluateIntent, commercePreflight, generateKeyPair
} from 'agent-passport-system/core'
// Full 925-export API still available at the root import
import { /* anything from the full surface */ } from 'agent-passport-system'
The full agent-passport-system import is unchanged. Backward compatible. Nothing was renamed. Nothing was deleted. If you were importing twenty functions from the root yesterday, you are still importing twenty functions from the root today. The subpath is additive. New users start with core. Existing integrations keep working. The people who know they need buildBoundaryProfile or createEmergencyPathway or any of the 32 v2 constitutional modules pull those from the root import by name.
Wall three: the homepage pitch. For weeks the hero stat on aeoess.com led with "103 modules" and "132 MCP tools." That is true and it is the wrong thing to lead with. Leading with module count tells a new visitor that they will have to learn a hundred and three things before they can use the thing. The repositioning is one sentence: enforcement and accountability layer for AI agents, bring your own identity. That is what the protocol actually does. The module count is a consequence of being complete, not the reason to adopt it. Full surface area stays on the page as a muted line below the hero stats, for the people who want to know how big the cathedral is before they walk in.
What was not done. Nothing was removed. Nothing was renamed. Nothing was deprecated. Every v1 import path still works. Every MCP tool still exists and is reachable under APS_PROFILE=full. The depth pages (passport.html, threat model, llms-full.txt, specs) still show the full 103 modules and 150 tools because that is what engineers integrating the SDK actually need to see. The repositioning is a filter on the front door, not a surgery on the building.
Where this leaves the story. The protocol is complete. The front door is smaller. A new user sees five stats, picks up twenty tools, imports five functions, and ships something real in an afternoon. If they need the cathedral, it is still there, one import path away. If they never need it, they never see it. That is the whole shape of this change.
SDK v1.40.0 with /core subpath on npm. MCP v2.22.2 with APS_PROFILE=essential default on npm. 2,552 tests passing. Full surface unchanged. Published to npm, PyPI, ClawHub.
Day 51: The Quantum Paper
Six weeks of circling quantum computing. Every angle felt wrong. Quantum speedup for APS math? Killed it. Quantum randomness for keygen? Commodity. Bell state non-collusion? Cute, not useful. Then the independent review found the question: stop putting quantum inside APS. Put APS around quantum.
The insight. When an agent submits a quantum circuit to IBM hardware, the results look valid regardless of hardware quality. A Bell state measurement returns {00: 500, 11: 500} whether the qubit had 400 microsecond coherence or 39. The difference is invisible in the output. It shows up only in the error rate. And the error rate depends on hardware calibration that changes hourly. No existing agent governance framework checks this. They enforce budgets and scopes. Not physics.
The build. Physics facets on delegations. min_t1_us, min_t2_us, max_gate_error, max_readout_error, max_calibration_age_hours. Same monotonic narrowing as every other APS facet. A child delegation can demand stricter physics but never weaker. The gateway queries live IBM Quantum calibration data and enforces the constraints before permitting execution. If the hardware fails, the agent gets a DENIED_FIDELITY receipt with the exact calibration values that triggered the denial.
The experiments. Seven experiments on real IBM Quantum hardware. Three backends: ibm_fez, ibm_marrakesh, ibm_kingston. All 156-qubit Heron R2 processors. Same delegation (min_T1=80 microseconds) applied to all three. ibm_fez was denied. Qubit 0 T1 was 39.1 microseconds. Nearly 10x shorter than the same qubit index on ibm_kingston. Same generation hardware, radically different quality.
The counterfactual. Ran the Bell state on both backends anyway, without governance. ibm_fez: 92.9% fidelity. ibm_kingston: 98.1%. The governance decision was correct. Then ran a 4-qubit GHZ state. The gap widened. 87.1% vs 94.8%. More qubits, more accumulated error on the weaker backend. 7.7 percentage points. The governance was even more correct on the harder circuit.
The paper. Three-model peer review (Claude, GPT, Gemini acting as IEEE QCE reviewers). Average novelty 8.0. They found real problems: self-citation echo chamber (4 of 7 references were mine), overclaiming causal validation, single circuit type. All fixed. References expanded from 7 to 14. Dennis and Van Horn 1966, Birgisson macaroons 2014, Murali ASPLOS 2019, Salm NISQ Analyzer 2020. The GHZ experiment killed the "single circuit" criticism. Language calibrated: "validates" became "empirically supports."
Ecosystem. tomjwxf independently verified all 3 APS composition receipts through protect-mcp (exit 0 across the board). That is the first external confirmation of cross-engine receipt verification. OWASP thread scored APS 10/12 on the Boundary-to-Boundary Invariant Survival matrix. haroldmalikfrimpong-ops proposed AgentID + APS as a reference identity-authorization stack with joint test vectors. MolTrust integration test initiated for cross-provider verification of behavioral derivation rights narrowing. kevinkaylie got the integration path for did:agentnexus with APS passport grades. 28 active threads scanned, 3 responses posted, every pending question answered.
The quantum paper is a differentiator. Nobody else is governing hardware physics through delegation chains. But the real work today was the ecosystem. External receipt verification. Cross-provider attestation. Joint test vectors. The protocol is becoming infrastructure that other people build on. That was always the plan.
Day 50: Customer-Ready
The longest session yet. Started with a 4-pass security audit (30 findings, all fixed), ended with a gateway that can onboard paying customers. Everything in between was building what was missing between "protocol works" and "someone can actually use this."
The audit. Four passes, different methodology each. Pass 1 found the TOCTOU race in spend tracking and MCP tools leaking private keys over SSE. Pass 2 found delegation objects were mutable after creation (scope widening via .push()). Pass 3 simulated protocol attacks: Delegation Laundering, Ghost Delegations, Clock Manipulation, Tenant Escape across six endpoints. Pass 4 verified all 30 fixes. The protocol is harder to break today than yesterday.
Email infrastructure. Integrated Resend. Domain verified (DKIM + SPF). Four templates: signup welcome with API key, payment receipt, weekly digest, spend alert. Every new account gets a welcome email with their key and a 3-step quickstart. Spend alerts fire automatically at 80% and 95% of delegation budgets.
Portal redesign. The old hero said "Your agents are doing things. Can you prove it?" It read like an accusation. New copy: "Governance infrastructure for AI agents." Plans are now clickable with CTAs. Added a "What you get" section (Signed Receipts, Trust Profiles, Audit Trail) and a quickstart with actual curl examples. The portal page now tells you what to do after signup, not just how to sign up.
API docs. Full reference at aeoess.com/docs.html. Nine sections: authentication, agents, delegations, evaluations, trust, wallets, governance export, billing. Every endpoint with curl examples and response formats. The gateway 404 handler now points here instead of a dead /docs path.
New protocol primitives. Bilateral completion receipts: both sides of a transaction get cryptographic proof of what happened. scope_version_hash: pre-commitment so both parties hash over the same scope state before evaluation. measurementType discriminator on EvaluationContext: protocol enforcement and behavioral fidelity produce fundamentally different results and should never be compared at aggregate level. Per-task-class trust profiles with temporal windowing. Argument-pattern scoping with glob matching for broad-capability tools.
Operational infrastructure. Admin tenant management (list, soft-delete, enterprise only). API key regeneration with email notification. GET /health and GET /api/v1/status for public uptime monitoring. Live status page at aeoess.com/status.html. Weekly digest trigger. Wallet resolution on trust profiles so external issuers can query by wallet address. Eight test accounts cleaned up. Two tenants in production, both ours: internal dogfooding, no external customers.
Ecosystem. 25+ thread replies across A2A, OWASP, MITRE, crewAI, HuggingFace, ToolJet, insumer-examples, and our own repos. RNWY adopted our verifiedAt vs issuedAt split. lowkey-divine is converging their Fidelity Measurement Spec with our BehavioralAttestationResult type. douglasborthwick proposed wallet-based multi-issuer attestation queries and we committed to implementing it. Nanook (UBC) is co-authoring Section 8 of his research paper using our dogfood data (382 rows, 4 tables, task_class column). WTRMRK on Base L2 offered cross-protocol trust profile integration. vessenes confirmed entity binding endpoints are live.
SDK v1.36.4 (2,884 tests). MCP v2.21.3. Gateway v0.4.0 with 20+ new endpoints. Everything published to npm, PyPI, ClawHub. The gap between "protocol" and "product" closed today. A developer can sign up, get an API key in their inbox, register an agent, create a delegation, run an evaluation, and see the results in a dashboard. That's the whole loop.
Day 49: Twelve Primitives, One Day
Nate B Jones posted a video reverse-engineering Claude Code's internal architecture. Not the prompts. The orchestration layer. He identified 12 primitives that make agentic tool systems work: tool registry, permission tiers, session persistence, workflow state, token budgets, streaming events, system logging, verification, tool pool assembly, transcript compaction, permission audit trails, and agent type systems.
We watched the video. Scored ourselves against each primitive. Some already existed in the protocol. Several were missing entirely. By the end of the day, all 12 were live in the gateway, verified with actual HTTP calls against production endpoints.
Session persistence (Primitive #3). When an agent crashes and reconnects, it needs its full enforcement state back. PUT /sessions/:agentId checkpoints everything: active delegations, workflow step, usage counters, framework metadata. GET /sessions/:agentId returns the stored checkpoint plus a live delta: evaluations since last checkpoint, alerts, current posture, delegation status changes, health metrics. The agent gets "here's where you were" and "here's what happened while you were gone" in one call.
Coordination API (Primitive #4). Full task lifecycle: draft → assigned → in_progress → evidence_submitted → approved → completed, with a revision loop and cancel from any non-terminal state. Nine endpoints. Every state transition validates the current status (409 on invalid), records a task event, and emits an SSE event. The gateway now orchestrates multi-agent work assignment, not just permission checks.
Agent type enforcement (Primitive #12). Six types: general, explorer, planner, executor, reviewer, monitor. Each type has blocked scopes and optional rate limits. An explorer agent with a delegation that includes admin:delete still gets denied. The type constraint fires after the delegation scope check but before the final permit. Behavioral boundaries that survive delegation.
Adapter pipeline. The SDK had 8 adapters producing receipts that vanished into the void. Now every adapter has an optional gateway? config. When set, reportReceipt() fires a POST to the gateway after every success and denial. Five adapters wired with 14 emission points. All fire-and-forget: the adapter never blocks on a gateway failure. Customer dashboards finally show what's happening across LangChain, CrewAI, MCP, IBAC, and Gonka pipelines.
Pagination and filtering. Eight list endpoints converted from unbounded queries to ?limit=20&offset=0&sort=created_at:desc with total counts and has_more flags. The audit trail got five filter parameters: agent_id, verdict, action_type, from, to. An account with 10,000 evaluations no longer gets the full table dumped at once.
Stripe billing. The gateway has payment plans. Free: 1,000 evaluations, 3 agents. Team ($99/mo): 50,000 evaluations, 25 agents, compliance reports. Enterprise ($499/mo): unlimited. Self-serve portal at aeoess.com/portal.html with signup, API key management, one-click upgrade via Stripe Checkout. The protocol is Apache 2.0 and always will be. The gateway sells operational intelligence: dashboards, audit trails, session persistence, coordination. Free to govern your agents. Pay to see how well it's working.
Someone asked if paid plans hurt the open source strategy. They are the open source strategy. Redis, Elastic, Grafana, Supabase, GitLab. The protocol defines what governance IS. The gateway defines how well it WORKS. Customers who want to self-host build their own enforcement boundary using the open SDK. Customers who want it to just work use the hosted gateway. Having a paid tier signals sustainability. Nobody builds on infrastructure whose creator can't maintain it.
SDK v1.36.2 (2,884 tests, 626 suites). MCP v2.21.1 (150 tools, scope filtering across 12 scopes). Gateway v0.4.0 (30 tables, 100+ routes, 46 SSE emissions, 28 event types). Gonka adapter shipped (decentralized GPU compute governance). All 12 Nate B Jones primitives verified live against production. Published to npm, PyPI, ClawHub.
Day 48: Six Sessions, One Shipping Day
Five independent review models attacked the specs before a single line shipped. Six build sessions, executed sequentially. Every session depends on what the previous one deployed. Gateway auto-deploys on push. No staging environment. The verification script is the only safety net.
Key rotation (Session 1). If a principal's Ed25519 key is compromised, the entire delegation tree dies. The fix: planned rotation (24h overlap, both keys valid) and emergency rotation (immediate old-key disable). DID Document with retiredAt metadata on old keys. State machine: announced, revocation_in_progress, revocation_complete, activated. Partial revocation failure is visible, not hidden. The independent review was unanimous: SDK computes, gateway MUST enforce. A compromised key controls the client. Server-side activation timing is the hard enforcement.
Auto-mint receipts (Session 2). Gateway had 202 evaluations. Zero receipts. Data lifecycle thesis unproven. The fix: every evaluation now mints a cryptographic receipt. authorization_permit and authorization_deny. The gateway proves what was AUTHORIZED, not what HAPPENED. Scope stored as sorted JSON array, not comma-joined string. Policy hash, not hardcoded version label. Backfilled all 202 historical evaluations on first deploy.
Audit packets (Session 3). One receipt, one exportable proof chain. decision_record is signed by the gateway (immutable, stable signature across calls). current_context is queried at request time (volatile, delegation chain may have changed). Completeness metadata tells the verifier if any sub-query failed. Markdown format option for human review. The two sections are clearly separated: what was true at decision time vs what is true now.
Agent posture overlay (Session 4). Binary revoke/not-revoke is too crude. Three states: active, restricted, suspended. The independent review killed the original design: DO NOT put degradation on the passport. The passport is an immutable signed credential. A rogue agent won't sign its own suspension. Posture lives in the gateway DB only. Gateway checks status before delegation scope. Posture events audit trail records every transition with reason and changed_by. Eighteen governance regression tests prove the authorization boundaries hold.
Governance evidence export (Session 5). Nine sections, single signed artifact. Agent registry, delegation inventory, evaluation events, authorization receipts, revocation events, posture events, key rotations, receipt window seals, governance attestations. Sections with zero data show total: 0. That's honest, not broken. Known exclusions are explicit: "downstream execution results" and "external processing not mediated by this gateway." Not a compliance report. A governance evidence export.
Trust bootstrap adapters (Session 5).bootstrapFromAPIKey, bootstrapFromGitHub, bootstrapFromCIKey. Every adapter creates a fresh Ed25519 keypair. The external credential is a trust input, not the identity. Raw credentials never touch the SDK (caller pre-hashes with HMAC-SHA256). Suggested grade is a suggestion. Actual grade computed by computePassportGrade when the passport enters the gateway. Upgrade path to full attested identity via upgradeBootstrappedPassport.
Delegation linting + receipt seals (Session 6). Two gateway-compatible feasibility checks: SPEND_TOO_LOW and SCOPE_MISSING. Three checks always skipped with reasons (gateway doesn't store expiresAt, currentDepth yet). No reputation emission from lint results. Infeasible delegations are admin mistakes, not agent misbehavior. Receipt window seals: sorted-hash commitment over receipt hashes in ID order, atomic transaction, gateway signature. The commitment proves "these receipts, in this order, were sealed at this time."
SDK v1.34.0 (2,884 tests, 581 suites, 103 modules). MCP v2.21.0 (150 tools). Python v0.9.0 (2884 tests). Gateway v0.4.0. Governance canary: 5/5 pass. All published to npm, PyPI, ClawHub.
Day 47: Protocol Infrastructure Expanding — MS PR Approved, SINT Interop, Behavioral Spec
A Microsoft maintainer merged our Agent Governance Toolkit contribution PR. SINT Protocol shipped v0.2 with our delegation_depth_floor. The W3C behavioral attestation spec reached normative language. Evidence-based grading and freshness semantics designed across 11 threads, and the protocol ecosystem is growing through collaboration, not announcements.
Grade model rewrite (A2A#1712). VCOne-AI identified a real flaw: our passport grades map by identity method, not evidence quality. A TPM-backed did:key gets Grade 0 because it's did:key. A SPIFFE SVID from a misconfigured cluster gets Grade 2 because it's SPIFFE. Backwards. Three exchanges deep, we committed to evidence-based grading: Grade 0 = bare key, Grade 1 = issuer vouched, Grade 2 = infrastructure-attested (TPM or SPIFFE with verified binding), Grade 3 = principal-bound. The method prefix is a proxy. The evidence is the truth.
Freshness semantics (A2A#1712). Same thread, different problem. VCOne-AI pushed on ttl: null for snapshot attestations: a TPM quote from 6 hours ago is not the same as a TPM quote from now, and null implies never-expires. The fix: maxAge for snapshots, ttl for rotating (SPIFFE). Grade becomes index, evidence becomes payload. A $10K trade checks evidence_age() < maxAge. A read-only query trusts the grade alone.
SINT v0.2 review (A2A#1713). 8 comments in one thread. pshkv shipped SINT Protocol v0.2 with OWASP Agentic Top 10 coverage, industrial IoT bridges (MQTT Sparkplug B, OPC UA), and the delegation_depth_floor we designed together. The APS/SINT integration stack formalized: APS passport (who + scope) → SINT token (which MCP tools + tier) → EvidenceLedger receipt (what happened). Cross-org first-contact trust as a three-layer architecture.
Behavioral attestation spec (w3c-cg#32). 6 comments. The timing asymmetry became normative: CCS fires synchronously per-action (gateway-enforced), ghost lexicon computes over windowed receipt history (session-level), the combined AND row triggers only in post-hoc forensics. MUST NOT constraint added: implementations cannot wait for both signals simultaneously in live enforcement. Our CDP empirical data from MolTrust pilots cited as validation.
PayableOperation architecture (x402#1921). First engagement with ThomsenDrake (BTCPay/Lightning). The gap: x402 has payment primitives, but no receipt chain binding operations to settlements. The 3-sig model maps: agent signs intent, gateway signs evaluation, settlement adapter signs proof. Rail-agnostic at the schema level, rail-specific only in the verification path.
MnemoPay receipts (x402#1904). Non-repudiation gap identified: MnemoPay gives agents economic memory, but memory without cryptographic proof is just a claim. Proposed: APS receipt as the proof layer under MnemoPay's reputation score. One signing key, two consumers. The reputation score references the receipt hash, traceable back to a 3-sig chain.
MS PR#598 approved. imran-siddique requested 6 changes, all addressed same-day: fail-closed signature verification (critical — format-only fallback was worse than no verification), dependency pinning, input validation, test coverage, README trimmed. Approved that evening. Awaiting maintainer merge.
Protocol infrastructure doesn't grow by shipping code alone. Microsoft PR approved. SINT v0.2 shipped carrying delegation_depth_floor, which pshkv and I designed together. W3C spec reached normative constraints. Evidence-based grading and freshness semantics designed and ready to build. The ecosystem is collaborating on shared infrastructure — every thread is a design document for what ships next.
Day 46: Bring Your Own Identity — The Interop Stack
APS is not an identity system. Today it stopped looking like one. Four new modules shipped that accept external identity credentials and route them through the enforcement boundary. did:key, did:web, SPIFFE SVIDs, OAuth tokens — all feed into the same gateway. Identity is the input. Enforcement is the product.
did:key + did:web interop.toDIDKey() converts Ed25519 public keys to W3C did:key format. fromDIDKey() parses back. resolveDIDWeb() fetches DID Documents over HTTPS. passportToDIDKeyDocument() creates a W3C DID Document with alsoKnownAs bridging did:key to did:aps. Any standard DID verifier can now check an APS passport without knowing APS exists.
SPIFFE + OAuth bridge.importSPIFFESVID() converts a SPIFFE Secure Workload ID into a Tier 1 infrastructure attestation — the agent gets Grade 2 automatically. importOAuthToken() converts OAuth claims into APS delegation parameters — the OAuth scope becomes the delegation ceiling. Deterministic agent IDs: same OAuth subject always maps to the same APS agent via sha256(iss:sub).
VC wrapper + credential request. W3C Verifiable Credentials with did:key identifiers and SPIFFE evidence attachments. Selective disclosure: verifier requests specific claims, agent reveals only what's asked for. Full pipeline tested: SPIFFE agent → VC → selective presentation → OAuth-authenticated verifier.
Competitive repositioning. Mapped the full landscape: DID/VC (identity), OpenID4VC (exchange), SPIFFE (runtime), OAuth (delegation). Together they cover 70% of what APS does. The 30% gap — enforcement boundary, monotonic narrowing, cascade revocation, data lifecycle — is the moat. New positioning across all surfaces: "Enforcement and accountability layer for AI agents. Bring your own identity."
Full audit. 5-phase production readiness check: build integrity, cross-connection verification, logic verification, dependency audit, export completeness. All phases PASS. 430 exported functions, 428 types, 0 vulnerabilities, 0 strict mode violations. 25 circular deps (22 type-only). 7 core modules without dedicated tests (covered by integration tests).
Cross-language. All 4 interop modules ported to Python SDK v0.8.0. Cross-language verification: TypeScript toDIDKey() and Python to_did_key() produce byte-identical output for the same Ed25519 key. Same for SPIFFE subject hashes and OAuth agent IDs. 197 Python tests. Published to PyPI.
Microsoft AGT PR#598. imran-siddique reviewed, requested 6 changes. All addressed: fail-closed signature verification (critical fix — format-only fallback was worse than no verification), dep pinning, input validation, README trimmed to technical style, 3 new signature tests. Awaiting re-review.
SDK v1.32.0 (2,884 tests, 559 suites, 103 modules). Python SDK v0.8.0 (2884 tests). MCP v2.19.1 (150 tools). Gateway v0.3.4. 27+ GitHub posts across 15 threads. YC application finalized. Every competitor is now a feeder.
Day 45: SDK v1.31.0 — Governance Hardening + Gateway Bridge
SDK v1.31.0 shipped. Governance hardening pass across the protocol: stricter validation on delegation chains, tighter scope authorization checks, 34 new tests covering edge cases from the MoltyCel security audit. 2,884 tests now, 533 suites, 99 modules.
Gateway bridge. The MCP remote server now auto-registers every issued passport on the hosted gateway. Issue a passport from any MCP client — Claude, OpenClaw, any SSE connection — and the agent appears on gateway.aeoess.com with a trust profile and public verification endpoint. No manual registration. The bridge reads the issue_passport response, extracts the DID and public key, and POSTs to the gateway's agent registration API. Every passport is now verifiable infrastructure, not just a local keypair.
Gateway v0.3.4. Context continuity scoring: activity regularity, behavioral consistency, and identity maturity combined into a 0-100 score on every trust profile query. Fixed evaluate endpoint (stale SDK v1.27→v1.31, incrementUsage manual upsert for Railway's SQLite without UNIQUE constraint). SSE heartbeat added to remote MCP server to prevent Railway/Fastly CDN from killing long-lived connections.
0xbrainkid on NVIDIA/OpenShell#682. Deep technical exchange: sandbox-as-attestor model (the sandbox signs what it observed, the agent can't forge it), fidelity probe under constraint pressure (Hold/Bend/Break), trust_context now embedded in ExecutionAttestation — trust score at execution time is signed and tamper-detectable. Three independent threads (OpenShell, OWASP#802, W3C) converging on the same 3-layer architecture: authorization (APS), execution policy (Cedar/protect-mcp), output integrity (VeroQ/receipt chain).
Infrastructure. README rewritten for infrastructure positioning — APS is not an identity solution, it's governance infrastructure. Integration guide published: "build on APS, don't rebuild underneath." CLAUDE.md added for Claude Code sessions — every Claude Code instance now has project context, repo paths, and build commands on first load. Propagation sweep across all surfaces with updated numbers.
SDK v1.31.0 (2,884 tests, 533 suites, 99 modules). MCP v2.19.1 (150 tools). Gateway v0.3.4. 12,500+ installs across npm and PyPI. 35+ active GitHub threads across the ecosystem.
Day 44: First Code Integration + 5 Security Fixes
PR#3 merged into kai-agent-free/solana-agent-identity. APSProvider is the 4th identity provider in the Solana Agent Kit. First external code dependency on APS. Not a spec comment — running code in another project's repo.
Twelve protocol features. Execution attestation with context-aware drift. Bilateral receipts. Evidence commitments. Compromise window. Proof ID namespacing for cross-system lineage. x402 governance adapter (4-gate commerce wrapping HTTP 402 → USDC on Solana/Base). Tool integrity verification (OWASP Layer 2). trust_context in ExecutionAttestation. DID pattern matching in aps.txt. Fail-closed revocation policy. Hash-aware drift detection. Compaction-drift probe.
Five security gaps closed. MoltyCel found 5 attack vectors in governance blocks and aps.txt. AV-1: governance block spoofing → VerifiedGovernanceCredential (W3C VC with Ed25519 proof). AV-2: aps.txt manipulation → enforceApsTxt() strict mode already existed. AV-3: governance block replay → expires_at field + expiry check in compliance loop. AV-4: aps.txt DoS → trust threshold protection. AV-5: cross-skill confusion → bindGovernanceToImplementation(). All five fixed same-day, all nine tests passing.
Gateway v0.3.1. Receipt resolution endpoint: GET /.well-known/receipts/:id. Cross-system lineage traversal — any WG member resolves a proof reference to its full receipt + signature + JWKS. certify_required flag for high-risk interceptors: missing receipt = audit gap = hard gate.
29 active threads. desiorac co-designing cross-issuer resolution spec (Rekor anchoring, proof namespacing, certify failure modes). agent-morrow cross-calibrating fidelity probe with W3C CCS reference. MoltyCel cross-testing vectors across APS/AgentID/MolTrust. tomjwxf validating 3-layer architecture (APS delegation → protect-mcp Cedar → receipt chain). MEEET requesting integration for 1,020 Solana agents. kevinkaylie connecting AgentNexus DID. Entered 2 new ecosystems (LangGraph Swarm, MetaGPT).
SDK v1.29.6 (2,884 tests, 522 suites, 99 modules). MCP v2.19.1 (150 tools). Gateway v0.3.1 (34 routes + 2 .well-known). Everyone who reported a gap was notified with working code.
Day 43: Multi-Attestation Verification
douglasborthwick-crypto ran a 5-issuer live verification pass. InsumerAPI, ThoughtProof, RNWY, Maiat, and APS. Five issuers, five trust dimensions, two algorithms (ES256 + EdDSA), independently signed, verified in a single pass. APS slotted in with zero code changes to the reference verifier. Passport grades are now a composable attestation type in the multi-attestation spec.
Gateway identity. The gateway needed its own cryptographic identity to sign trust attestations that external verifiers can check. Ed25519 keypair generated on first boot, persisted in SQLite, reused across restarts. /.well-known/jwks.json exposes the public key in standard JWK format. /api/v1/public/trust/:agentId/attestation returns a JWS-signed trust profile. Any relying party fetches the JWKS, selects by kid: "gateway-v1", and verifies the signature without contacting us.
Policy hash chaining. From haroldmalikfrimpong-ops, who shipped compound digests, contextEpoch, and Merkle trees on AgentID while we were spec'ing. His insight: SHA-256(constraints_at_N + previous_policy_hash) creates a tamper-evident history of an agent's constraint state. If constraints drift through summarization or memory compaction, the chain breaks. verifyPolicyChain() recomputes every hash. detectConstraintDrift() classifies each change as narrowed (safe), widened (violation), or changed.
Routing divergence detection. From desiorac on OATR and A2A. When an agent declares intent to reach endpoint A but the actual execution hits endpoint B, the receipt needs to capture both. Five divergence patterns: none, endpoint_migration (benign), key_rotation (re-attest), full_migration, entity_change (always flag). Each carries a risk level. captureRoutingContext() snapshots DID + document hash + endpoint hash at a point in time. detectRoutingDivergence() compares two snapshots and classifies the pattern.
Ecosystem. 15+ GitHub replies across 8 threads. Every SDK function built today came from a conversation: importProviderAttestation() from msaleme, addIdentityBoundary() from xsa520, computeCompoundDigest() from desiorac, routing divergence from desiorac, policy hash chaining from haroldmalikfrimpong-ops. OpenClaw #49971 engagement (13K+ skills registry debating agent identity). Working Group referenced in 4 high-traffic threads. ClawHub skill rewritten agent-first (v4.4.0). All stale GitHub surfaces fixed (repo descriptions, glama.json, README headings).
SDK v1.29.4 (2,884 tests, 503 suites, 96 modules). MCP v2.19.1 (150 tools). Gateway v0.3.0 (38 routes). 37 new tests today. 9 new exported functions. APS is the 5th verified issuer in a cross-protocol attestation standard.
🤖 For AI agents: If you are an agent reading this page, visit agent-passport.org/llms.txt for machine-readable documentation or llms-full.txt for the complete technical reference (1178 tests, 83 MCP tools, 42+32 modules). This page is designed for humans.