[CAP] Charter Agreement Protocol · the signer package
When two agents strike a deal, what evidence survives the handshake?
OAuth says who called. Even a signed contract only says what was promised on paper.
CAP is the missing evidence layer for bilateral agreements — including agent commerce: the
parties sign byte-exact descriptors, acceptances, and receipts, so “which terms
governed this action?” is answered by cryptography, not chat logs. CAP verifies. It never
authorizes. And the private keys never enter this library — this page generates both
parties’ keys in your browser.
A signed PDF proves someone agreed to some text. It does not prove which exact
revision governed a given action, that both parties accepted those bytes, or that the acting
key still belonged to its party.
Byte-exact agreements.
“Version 2 of the terms” is a dispute waiting to happen when two systems
hold two different version 2s.
Every revision is canonical JSON with a digest;
acceptances bind those exact bytes. Rewriting one character breaks the chain.
Bilateral, not self-said.
One party attesting to its own agreement is marketing, not evidence.
Acceptance is two signatures over the same
digest, each bound to the party’s key history via its descriptor.
It never decides for you.
“Verification” tools that whisper “valid — go ahead” are quietly making
your business decision.
CAP’s facts always carry a closed twelve-item
not_verified floor — authority, billing, legal validity — that no API can shrink.
You read the evidence; you decide.
The charter workshop
Everything is live: this page bundles the real signer and verifier packages. Two parties’
keys are generated in your browser; four real artifacts get signed, verified, and — if you
like — broken.
Form it step 1
each party signs
a descriptor pinning its key (cap+party)
the charter
a canonical revision: terms, parties, window
Accept + act steps 2–3
acceptance
both parties sign the revision digest
receipt
an action bound to exact revision coordinates
Verify anyone, offline
verify the set to see the structural facts
—
Tamper deckRewrite the past — every attempt fails closed.
Form, accept, and act first — then rewrite history.
Wire viewerClick any artifact to inspect its actual bytes.
nothing selected yet
The family lifecycle
Three protocols, one chain of evidence: what the agent is, what was agreed, what this call may do.
Agree the termsCharter revisions bind ABP release digests (abp_bindings); every receipt records the action’s deployment digest — signed by both parties
One handle, two callbacks — atomic key snapshot and sign. The private key never enters: not the library, not this page’s bundles.
Honest-signer refusals
R1–R3: the signer refuses to sign claims it cannot honestly make — wrong chain, mismatched digest — before the key is ever touched.
Wrong-key guard
Every signature is verified against the snapshot’s public key before the artifact leaves — a custodian misconfiguration fails loudly.
PQ-ready
Ed25519 today, ML-DSA descriptors from protocol revision 3 — the post-quantum lane is in the registry, not a promise.
The four signers
Function
Artifact
Post-sign verify
signDescriptor
party descriptor (cap+party) — key history, transitions, fork evidence
verifyDescriptor
signAcceptance
acceptance (cap+acceptance) — bilateral assent to exact bytes
verifyAcceptance
signTermination
termination notice (cap+termination) — closure at a pure UTC instant
verifyTermination
signReceipt
receipt (cap+receipt) — an action bound to revision coordinates
verifyReceipt
The key-handle contract
Two callbacks, both may be async — remote custodians (HSM, KMS) are first-class.
interface KeyHandle {
keyIdentity(handle): { kid, publicKey } | Promise<…> // ONE atomic snapshot
sign(message, handle): Uint8Array | Promise<Uint8Array> // the holder's job
}
// Framing, claims gates, and assembly all live in the verifier package's
// producer surface — exactly one implementation, shared with the reference.
npm i @charter-agreement-protocol/signer # one runtime dep: the verifier package