Protocol walkthrough
A tour of the three envelopes, two typical flows, and how they compose with the rest of the OrangeCheck stack. For the normative rules see the specification.
Three envelopes
OC Agent defines three envelope kinds. All three share the canonical-message / BIP-322 / Nostr publication discipline of the rest of the OrangeCheck stack.
| Envelope | kind | Nostr kind | d-tag prefix | Purpose |
|---|---|---|---|---|
| Delegation | agent-delegation | 30083 (co-claimed with OC Stamp; disjoint d-tag prefixes) | oc-agent-del: | Principal grants the agent scoped authority. |
| Agent-action | agent-action | 30084 (claimed exclusively; reuses OC Stamp envelope shape) | oc-agent-act: | Agent exercises the delegation. |
| Revocation | agent-revocation | 30085 (claimed exclusively) | oc-agent-rev: | Principal (or agent) burns the delegation. |
| Sub-delegation (v1.1) | agent-subdelegation | 30086 (claimed exclusively) | oc-agent-sub: | Agent grants a narrower slice of its delegated rights to another agent. See sub-delegation. |
Each envelope is independently verifiable:
- A delegation is authentic iff its BIP-322 signature verifies under the principal's address.
- An agent-action is authentic iff (a) its BIP-322 signature verifies under the agent's address, (b) the referenced delegation verifies, and (c) the exercised scope is within the granted scope set.
- A revocation is authentic iff its BIP-322 signature verifies under the principal's address (or, if the delegation granted it, the agent's).
Delegation — the grant
A delegation is a statement from a principal's Bitcoin address:
I,
bc1qprincipal…, authorizebc1qagent…to perform actions matching scope set S, bonded at 500,000 sats × 180 days under my OrangeCheck attestation, until Friday 2026-04-29T12:00Z.
That statement is serialized into a canonical message, hashed to produce an id, signed via BIP-322 by the principal, and written into a JSON envelope. The envelope travels over any medium that can carry bytes.
Scopes are not sentences — they are declarative strings like
lock:seal(recipient=bc1qalice) or ln:send(max_sats<=1000,node=03abc…).
Structured, human-legible, deterministically comparable. See the
scope grammar.
Agent-action — the exercise
An agent-action is structurally identical to an
OC Stamp envelope except for a different preamble
(oc-agent:action:v1) and two extra lines in the canonical message:
oc-agent:action:v1
address: bc1qagent…
content_hash: sha256:deadbeef…
content_length: 4096
content_mime: application/vnd.oc-lock+json
signed_at: 2026-04-22T12:05:00Z
delegation_id: <64-hex of the delegation envelope's id>
scope_exercised: lock:seal(recipient=bc1qalice)
The action commits to what the agent did (content.hash), when (signed_at
plus optional OTS anchor), which delegation authorized it (delegation_id), and
which granted scope it exercised (scope_exercised). A stamp verifier that
ignores the two extra fields still confirms authorship and priority correctly —
authority verification is additive.
Revocation — the burn
If the principal loses trust in the agent, or the agent's key is compromised, or the job simply concludes early, a revocation kills the delegation:
oc-agent:revocation:v1
address: bc1qprincipal…
delegation_id: <64-hex>
reason: agent key rotated
signed_at: 2026-04-22T14:00:00Z
Revocations are OTS-anchored when possible, so their effective time is provable against a specific Bitcoin block — which matters when an action and a revocation race on the same day and a third party has to decide which was first.
Flow 1 — delegate, act, verify
sequenceDiagram
autonumber
participant P as Principal wallet<br/>(bc1qprincipal…)
participant A as Agent process<br/>(bc1qagent…)
participant N as Nostr<br/>kind-30083
participant V as Verifier<br/>(offline)
participant C as Bitcoin chain<br/>(bond + OTS)
P->>A: delegation envelope<br/>(BIP-322 by principal · scopes · expiry · bond)
P->>N: publish delegation (optional, public)
A->>A: compose content, hash, anchor (optional OTS)
A->>V: agent-action envelope<br/>(BIP-322 by agent · cites delegation_id)
V->>N: fetch delegation by id (if not bundled)
V->>C: re-resolve bond attestation<br/>(if caller cares)
V-->>A: OK { principal, agent, scope, content, anchor }
- Principal picks scopes.
- Principal's wallet opens a signing prompt containing the canonical delegation message. Principal reviews (scopes, expiry, bond) and signs.
- Signed envelope is delivered to the agent over any transport.
- Agent stores the delegation. Optionally the principal publishes Nostr kind-30083.
- Agent composes its action, hashes content, signs the canonical action
message, produces an
.actionenvelope. Optionally anchors to OTS. - Verifier runs the algorithm in §SPEC 8 — purely locally, against envelope + Bitcoin headers.
Flow 2 — revocation and priority
flowchart LR
subgraph T0[t0 — delegate]
P0["Principal"] -->|BIP-322 delegate| D[("delegation<br/>envelope")]
end
subgraph T1[t1 — act]
D --> A1["Agent"]
A1 -->|action signed,<br/>OTS-anchored at <b>block X</b>| ACT[("action<br/>envelope")]
end
subgraph T2[t2 — revoke]
P2["Principal"] -->|BIP-322 revoke,<br/>OTS-anchored at <b>block Y</b>| REV[("revocation<br/>envelope")]
end
ACT --> V{Verifier<br/>compares anchors}
REV --> V
V -->|X < Y| OK["✓ action stands"]
V -->|X ≥ Y| BAD["✗ post-revocation —<br/>reject"]
classDef base fill:#0a0a0a,stroke:#f97316,stroke-width:2px,color:#fafafa;
classDef bad fill:#0a0a0a,stroke:#dc2626,stroke-width:2px,color:#fafafa;
classDef ok fill:#0a0a0a,stroke:#16a34a,stroke-width:2px,color:#fafafa;
class P0,P2,A1,V base;
class OK ok;
class BAD bad;
The verifier compares the action's OTS anchor block to the revocation's. If the
action predates the revocation, it stands. If the action isn't OTS-anchored but
a revocation exists that predates its declared signed_at, the verifier treats
the action as suspect — the agent's "I signed this before you revoked" claim is
not provable against Bitcoin.
This is why OC Agent strongly recommends OTS anchoring of actions whose authority might later be disputed.
Composing with the rest of the stack
With OC Lock
If a delegation's scopes would reveal sensitive intent, wrap the delegation envelope with OC Lock to the agent's device key. The confidentiality is additive; the authority verification is unchanged.
With OC Stamp
Every agent-action is an OC Stamp with two extra lines. A verifier with only a stamp implementation reads authorship + priority correctly; only the authority check requires OC Agent awareness.
With OC Vote
A principal may delegate vote:cast(poll_id=<hex>, choice=yes) to an agent. The
agent produces an agent-action whose content is an OC Vote envelope. Verifiers
see the agent cast the vote, backed by a delegation, backed by the principal's
bond.
With OrangeCheck
bond.attestation_id points to an OrangeCheck canonical message signed by the
principal. Verifiers re-resolve it against current chain state — the bond is a
live signal, not a stored number.
With MCP, Nostr, Lightning
Any downstream transport gets a companion authority artifact:
- MCP: an
agent-action(kind=30084)stamping the tool-invocation arguments as content. - Nostr posts: a companion kind-30084 event linked to the underlying kind-1 post id.
- Lightning: a stamp whose content is the payment hash.
Design constants
- Bitcoin address is identity, end of story.
- BIP-322 on a hex id is the signature.
- Verification is a pure function of envelopes + (optional) Nostr + Bitcoin headers.
- Every envelope is a single JSON object.
- Scope strings are parseable, comparable, composable.
- Revocation is always available, always citable — priority-ordered by OTS anchor.
- Stake is optional but first-class.
For the full normative rules, see SPEC. For the rationale behind the design, see why.