Direct answer
AER-1 in TypeScript
TypeScript and JavaScript agents can work with AER-1 in both places they run. In Node, the kit's JavaScript and TypeScript runners exercise the full draft -24 corpus, 119 vectors and 122 checks. In the browser, the same verification procedure runs on a fetched receipt with no server and no account. The npm package aer-1 is the library path; the open kit is the source of truth.
Updated October 20, 2026.
Run the conformance runner in Node
The kit ships runners in 7 languages, including JavaScript and TypeScript paths that run under Node with the kit's own files:
git clone https://gitlab.com/rambozambodotdev/zambo.git
node aer-1/conformance.js
Feed the corpus to your own TypeScript verifier the same way: each vector carries the record, the context a checker is given, and the verdict the draft requires. Compare verdicts check by check. A disagreement names the rule your code reads differently, from the canonical byte construction to the draft -21 id-binding outcomes and the draft -23 anchor outcomes. The runners cross-verify at 52 agreements and 0 disagreements at kit 1.5.6, so matching the corpus puts your implementation in that agreement.
Verify a receipt in TypeScript
- Fetch or load the record as JSON: receipt id, tool, inputs reference, output hash, timestamps, and any anchors.
- Rebuild the canonical bytes from the record exactly as the draft specifies. Byte exactness is the whole game here: a near miss is a miss.
- Recompute the output hash over those bytes and compare it with the hash the receipt carries.
- Report the parts separately: the digest verdict, the id state (bound only via an expected id or Section 9 resolution with digest comparison, otherwise unverified), and each anchor outcome, including not checked for an anchor you did not evaluate.
Test the procedure against the live record at zambo.dev/run/28c79cde-20a0-48a3-b4ec-e5d0e3ac104d before trusting it on your own receipts: its canonical bytes recompute to exactly the output hash it carries.
Verify in the browser
Nothing in the procedure needs a server. A browser page can fetch a receipt, rebuild its canonical bytes, recompute the hash with the platform's standard digest tooling, and show the verdicts next to the record. That is how the public verifier at zambo.dev/verify works as an experience: the check happens in front of the person holding the receipt. Build your browser checker against the same test vectors, not against one happy-path receipt, so altered records and unbound ids fail in your UI the way the draft requires.
Emit receipts from TypeScript
When your Node or browser agent makes a tool call, capture it as it runs: tool name, inputs reference, saved result, and timestamps. Build the core fields, reduce them to canonical bytes, compute the output hash, and store the receipt with the hash committed and the receipt id as its locator. Emit from the execution layer around the call, not from the model's summary of the call, so the record covers what ran rather than what the agent says ran. The npm package aer-1 covers the library path for emitting and verifying; the kit repository carries the draft text, vectors, and runners the package is tested against.
Cite this draft
Cite AER-1 as the IETF Internet-Draft draft-zambo-aer1, current revision -24, posted October 20, 2026 and expiring April 23, 2027, at datatracker.ietf.org/doc/draft-zambo-aer1.
@misc{zambo-aer1,
author = {Brennan Zambo},
title = {AER-1: Agent Execution Receipt, version 1},
howpublished = {IETF Internet-Draft draft-zambo-aer1-24},
year = {2026},
url = {https://datatracker.ietf.org/doc/draft-zambo-aer1/}
}Honest limits
Browser verification depends on the bytes the page actually fetched: verify the record you display, from the source you display it from, and show the separate verdicts instead of one green badge. The npm package is a convenience, not the specification: where package behavior and draft text ever differ, the draft and the corpus govern. And the standing limit applies: a verified receipt proves the saved result was not changed after the fact, never that the work was correct.
Frequently asked questions
How do I use AER-1 in TypeScript?
Start from the open kit: clone gitlab.com/rambozambodotdev/zambo and run the Node runner, node aer-1/conformance.js, to see the corpus verdicts. For the library path in a TypeScript or Node project, the npm package is aer-1. Verify against the test vectors, 119 vectors and 122 checks at draft -24, before calling your implementation conformant.
Can I verify an AER-1 receipt in the browser?
Yes. The verification procedure needs no server and no account: fetch the receipt, rebuild its canonical bytes exactly as the draft specifies, recompute the output hash, and compare it with the hash the receipt carries. Report the digest verdict, the id state, and each anchor outcome separately, including not checked for an anchor that was not evaluated.
How do I emit an AER-1 receipt from Node?
Capture the tool call as it runs, in the execution layer around the call: tool name, inputs reference, saved result, and timestamps. Build the core fields, reduce them to canonical bytes, compute the output hash over those bytes, and store the receipt with the hash committed and the receipt id as its locator. Emit what ran, not the model's summary of what ran.
What test vectors should a TypeScript implementation pass?
The full draft -24 corpus in the kit: 119 test vectors exercised as 122 checks, covering valid receipts that must verify, altered receipts that must fail, the draft -21 id-binding outcomes, and the draft -23 anchor outcomes. The kit runners cross-verify at 52 agreements and 0 disagreements at kit 1.5.6.
What does a verified AER-1 receipt prove in TypeScript?
The same thing it proves in every language: the saved result was not changed after the fact, because the recomputed output hash over the canonical bytes matches the hash the receipt carries. It never proves the work was correct, and the language the checker is written in changes none of that.