Layer 4 — Escrow & Settlement
| Field | Value |
|---|---|
| Layer | 4 |
| Status | draft |
| Working Group | escrow-settlement |
Scope
Defines how CU value is locked before a task begins and released upon verified completion. This layer specifies the escrow signaling protocol — the roles, states, and messages. The underlying movement of value is delegated to pluggable settlement rails (§7); no specific rail is mandated.
The key words MUST, MUST NOT, SHOULD, and MAY are interpreted as in RFC 2119.
1. Roles & Trust Model
Escrow involves three parties:
| Role | Responsibility |
|---|---|
| Buyer | Locks CU before work starts; releases against accepted proof; reclaims unused funds. |
| Provider | Performs the work; may claim payment with proof if the buyer goes silent. |
| Escrow Agent | Neutral third party that holds locked CU and enforces the state machine below. |
The Escrow Agent is a role, not an implementation. It MAY be operated as a hosted platform service, a mutually trusted third party, or a smart contract — all are conforming as long as they implement the message interface in §4. Per RFC-0001 principle P4, at least one non-blockchain implementation path MUST always exist (see §7.2).
Buyer and provider each talk to the Escrow Agent over a standard ACMP
connection (Layer 1): all messages below are JSON-RPC 2.0
requests in the acmp/ namespace.
Party authorization: the agent binds the buyer role to the authenticated
connection identity (Layer 1 §5) that created the lock, and the payee role
to the authenticated identity matching the bound payee_id. Buyer-side
operations (bind, release, reclaim, dispute) MUST be rejected with -35005
unless they arrive from the buyer’s identity; escrowClaim MUST be rejected
unless it arrives from the bound payee’s identity. Note that payee_id itself
is self-reported at this layer — verifiable identity binding is Layer
7’s job (e.g. W3C DIDs).
An Escrow Agent declares the capability like any other ACMP role — the object below, carried in whichever envelope the binding in use specifies (see Layer 1 §1):
{
"version": "0.1.0",
"role": "escrow-agent",
"accepts": [
"acmp/escrowLock", "acmp/escrowBind", "acmp/escrowRelease",
"acmp/escrowReclaim", "acmp/escrowClaim", "acmp/escrowDispute",
"acmp/escrowStatus"
]
}
2. Escrow Lifecycle
An escrow tracks a balance (locked CU) through four states:
┌────────┐
lock │ │ release / reclaim (buyer)
BUYER ──────────────▶│ open │────────────────────────────────▶ closed
│ │ ▲
└───┬────┘ │
│ claim (provider, with proof) │
▼ │
┌─────────┐ challenge window elapses │
│ claimed │───────(auto-release)──────────────┤
└───┬─────┘ │
│ dispute (buyer, within window) │
▼ │
┌──────────┐ resolution (agent policy) │
│ disputed │──────────────────────────────────┘
└──────────┘
| State | Meaning |
|---|---|
open |
Funds are locked. Partial releases and partial reclaims are possible; the escrow stays open while remaining balance > 0. |
claimed |
The provider has claimed payment with proof; a challenge window is running. Auto-release at window end unless disputed. |
disputed |
The buyer contested a claim. Frozen until the agent’s resolution process concludes. |
closed |
Terminal. Balance fully disbursed (released + reclaimed = locked). |
Happy path (matches the RFC-0001 sequence diagram): buyer locks 0.005 CU → task runs → buyer verifies proof and releases 0.003 CU to the provider → buyer reclaims the unused 0.002 CU → escrow closes.
Safety path (silent buyer): the provider submits acmp/escrowClaim with
its proof. If the buyer does not dispute within the challenge window, the
agent auto-releases the claimed amount. This is the settlement-side twin of
Layer 3’s Optimistic Execution + Challenge
Period model.
Expiry: every lock carries a valid_until_ms deadline. If the escrow is
still open at expiry, the agent MUST auto-reclaim the remaining balance to
the buyer and close the escrow. A pending claim or dispute suspends expiry
until resolved — a provider who claimed in time cannot lose payment to the
clock. Buyers SHOULD size valid_until_ms to cover task timeout plus the
challenge window.
3. Idempotency
Every mutating message carries a caller-generated op_ref (unique string,
e.g. op_<random>). An agent that receives a repeated op_ref on the same
escrow MUST NOT execute the operation twice; it MUST return the outcome of the
first execution. This makes every operation safe to retry after a network
failure — the same rule Layer 1 §3.1.1 applies to task_id.
A message the agent rejects before changing any state — invalid
parameters, -35002 insufficient_funds, or a payment challenge (§7.4) — has
not been executed. A later message with the same op_ref is processed as if
it were the first, so a buyer can fix the cause (top up, pay) and retry
without minting a new key.
4. Message Schemas
4.1 acmp/escrowLock — buyer locks funds
{
"jsonrpc": "2.0",
"method": "acmp/escrowLock",
"id": "req_5c11aa",
"params": {
"op_ref": "op_9f21b3c4",
"amount_cu": 0.005,
"tier": "B",
"valid_until_ms": 1783017900000,
"payee_id": null,
"challenge_window_ms": 86400000
}
}
| Field | Type | Required | Description |
|---|---|---|---|
op_ref |
string | yes | Idempotency key (§3). |
amount_cu |
number | yes | CU amount to lock. Rejected with -35002 if the buyer’s funding does not cover it. |
tier |
string | no | CU quality tier (S, A, B). |
valid_until_ms |
number | yes | Absolute epoch-ms expiry of the lock (§2 Expiry). |
payee_id |
string | no | The provider allowed to claim/receive. MAY be omitted at lock time (RFC-0001 locks before provider selection) and bound later via acmp/escrowBind. |
challenge_window_ms |
integer | no | Challenge window applied to claims (§4.5). Note the lock typically happens before Layer 6 negotiation (RFC-0001 ordering), so the buyer can only set a standing default here; the negotiated value is set at bind time (§4.2). Default: agent policy (RECOMMENDED 24 h). |
Result: { "escrow_id": "esc_a3f9c2", "state": "open", "amount_cu": 0.005,
"valid_until_ms": 1783017900000 }
The returned escrow_id is what the buyer passes to the provider in the Layer
6 accept and in Layer 1 acmp/invoke.
How the lock is funded is rail-specific (§7) — e.g. an existing credit balance with the agent, or an inbound rail payment.
4.2 acmp/escrowBind — buyer binds the payee
Binds an unbound escrow to one provider. Binding is once-only: rebinding MUST be rejected with -35003. Typically sent between Layer 6 accept and Layer 1 invoke.
{
"jsonrpc": "2.0",
"method": "acmp/escrowBind",
"id": "req_5c11ab",
"params": {
"op_ref": "op_71d0e2aa",
"escrow_id": "esc_a3f9c2",
"payee_id": "agent:openclaw-3:us-east",
"challenge_window_ms": 86400000
}
}
| Field | Type | Required | Description |
|---|---|---|---|
op_ref |
string | yes | Idempotency key. |
escrow_id |
string | yes | The escrow to bind. |
payee_id |
string | yes | Layer 1 §4 identity format. |
challenge_window_ms |
integer | no | The challenge window agreed in the Layer 6 terms. Since bind follows accept, this is where the negotiated value lands; it overrides any default set at lock time. |
Result: { "escrow_id": "esc_a3f9c2", "payee_id":
"agent:openclaw-3:us-east" }
4.3 acmp/escrowRelease — buyer releases funds to the provider
The fast path: the buyer verified the proof itself and pays out immediately.
{
"jsonrpc": "2.0",
"method": "acmp/escrowRelease",
"id": "req_5c11ac",
"params": {
"op_ref": "op_c44d19e0",
"escrow_id": "esc_a3f9c2",
"amount_cu": 0.003,
"payee_id": "agent:openclaw-3:us-east",
"task_id": "task_a7c923f1",
"proof": { "method": "result-hash", "hash": "sha256:e3b0c442..." }
}
}
| Field | Type | Required | Description |
|---|---|---|---|
op_ref |
string | yes | Idempotency key. |
escrow_id |
string | yes | The escrow to release from. |
amount_cu |
number | yes | Amount to release. MUST be ≤ remaining balance (-35006 otherwise). Partial releases are allowed; the escrow stays open while balance remains. |
payee_id |
string | yes | MUST equal the bound payee. If the escrow is unbound, this release binds it implicitly. |
task_id |
string | no | The Layer 1 task this payment settles. Audit trail. |
proof |
object | no | The accepted Layer 3 proof. Audit trail; the agent stores it but does not verify it on this path (the buyer already did). |
Result: { "escrow_id": "esc_a3f9c2", "released_cu": 0.003,
"remaining_cu": 0.002, "state": "open" }
A release in state claimed is allowed as a fast-forward confirmation of the
pending claim — but only for amount_cu ≥ the claimed amount (it resolves
the claim; any surplus release is a normal partial release). A smaller release
MUST be rejected with -35003: a buyer who believes less is owed must
dispute, not undercut the claim.
4.4 acmp/escrowReclaim — buyer takes back unused funds
{
"jsonrpc": "2.0",
"method": "acmp/escrowReclaim",
"id": "req_5c11ad",
"params": {
"op_ref": "op_2b8ce671",
"escrow_id": "esc_a3f9c2",
"amount_cu": 0.002
}
}
| Field | Type | Required | Description |
|---|---|---|---|
op_ref |
string | yes | Idempotency key. |
escrow_id |
string | yes | The escrow to reclaim from. |
amount_cu |
number | no | Amount to reclaim. Default: entire remaining balance. |
Result: { "escrow_id": "esc_a3f9c2", "reclaimed_cu": 0.002,
"remaining_cu": 0, "state": "closed" }
Reclaim is only valid in state open (-35003 otherwise) — a pending claim
blocks it, so a provider’s in-flight claim cannot be undercut.
Bound-escrow guard: on a bound escrow, reclaim MUST additionally be rejected (-35003) until at least one release or resolved claim has occurred. Binding signals that a deal is on; without this guard, a buyer could drain the escrow while the provider is still working, winning the race against the provider’s claim and defeating the safety path entirely. The buyer’s funds are never stranded: they come back via the happy path (release, then reclaim the remainder — the RFC-0001 flow) or via expiry auto-reclaim if the provider never delivers. Unbound escrows can be reclaimed freely at any time.
4.5 acmp/escrowClaim — provider claims payment with proof
The safety path for a silent or unresponsive buyer. Valid only in state open
(-35003 otherwise); one claim may be pending at a time.
{
"jsonrpc": "2.0",
"method": "acmp/escrowClaim",
"id": "req_5c11ae",
"params": {
"op_ref": "op_e09a3d17",
"escrow_id": "esc_a3f9c2",
"amount_cu": 0.003,
"task_id": "task_a7c923f1",
"proof": { "method": "result-hash", "hash": "sha256:e3b0c442..." }
}
}
| Field | Type | Required | Description |
|---|---|---|---|
op_ref |
string | yes | Idempotency key. |
escrow_id |
string | yes | MUST be bound, and the caller MUST be the bound payee (-35005 otherwise). |
amount_cu |
number | yes | Claimed amount, ≤ remaining balance. |
task_id |
string | yes | The task the claim settles. |
proof |
object | yes | The Layer 3 proof. In v0.1 the agent stores it as dispute evidence rather than verifying it cryptographically — verification maturity tracks Layer 3. |
Result: { "escrow_id": "esc_a3f9c2", "state": "claimed", "claim": {
"amount_cu": 0.003, "window_ends_ms": 1783104300000 } }
State moves to claimed and the challenge window starts. If the buyer does
not dispute before window_ends_ms, the agent MUST auto-release the claimed
amount to the payee (any remainder returns to open, still reclaimable).
4.6 acmp/escrowDispute — buyer contests a claim
Valid only in state claimed, before the window ends.
{
"jsonrpc": "2.0",
"method": "acmp/escrowDispute",
"id": "req_5c11af",
"params": {
"op_ref": "op_55fe0c28",
"escrow_id": "esc_a3f9c2",
"reason": "Returned result does not match the task input.",
"evidence": { "task_id": "task_a7c923f1", "offer_id": "offer_6217d1" }
}
}
Result: { "escrow_id": "esc_a3f9c2", "state": "disputed" }
The escrow freezes. Resolution is agent policy, not protocol: the agent
arbitrates (itself, via a third party, or via a Layer 3 re-execution audit)
and disburses accordingly, closing the escrow. Parties observe the outcome via
acmp/escrowStatus. Standardizing arbitration is out of scope for v0.1.
4.7 acmp/escrowStatus — query
Callable by the buyer or the bound payee (-35005 for anyone else).
{
"jsonrpc": "2.0",
"method": "acmp/escrowStatus",
"id": "req_5c11b0",
"params": { "escrow_id": "esc_a3f9c2" }
}
Result:
{
"escrow_id": "esc_a3f9c2",
"state": "open",
"locked_cu": 0.005,
"released_cu": 0.003,
"reclaimed_cu": 0,
"remaining_cu": 0.002,
"payee_id": "agent:openclaw-3:us-east",
"valid_until_ms": 1783017900000,
"claim": null,
"dispute": null
}
5. Error Codes
Layer 4 uses the -35xxx range — distinct from Layer 1’s -33xxx; -34xxx
is informally in use for negotiation-level errors.
| Code | Name | Description |
|---|---|---|
| -35001 | escrow_not_found |
Unknown escrow_id. |
| -35002 | insufficient_funds |
Lock could not be funded. |
| -35003 | invalid_state |
Operation not permitted in the current state (incl. rebinding). |
| -35004 | escrow_expired |
The lock passed valid_until_ms and was auto-reclaimed. |
| -35005 | not_authorized |
Caller is not a party to this escrow, or not the party allowed to perform this operation. |
| -35006 | amount_exceeds_remaining |
Release/reclaim/claim amount exceeds the remaining balance. |
| -35099 | internal |
Unspecified agent-side error. |
6. Atomicity
The core guarantee of this layer:
Locked CU leaves the escrow only through (a) an explicit buyer release, (b) an unchallenged claim’s auto-release, (c) a dispute resolution, or (d) expiry auto-reclaim to the buyer. A conforming agent MUST NOT move value on any other trigger, and MUST perform the rail payout (§7) strictly after the corresponding state transition is durably recorded.
Settlement latency target for the happy path (release → payout initiated): < 500 ms. On-chain rails may exceed this for finality; the state transition itself must still meet the target.
7. Settlement Rails
7.1 Abstract rail interface (normative)
The escrow agent holds value between two rail interactions: funding in, payout out. A conforming agent:
- MUST support at least one funding mechanism for locks (e.g. a credit balance held with the agent, or an inbound rail payment at lock time).
- MUST support at least one payout mechanism to disburse releases (to the payee) and reclaims (to the buyer).
- MUST perform payouts idempotently (one payout per state transition, keyed by
escrow_id+ transition), and only after that transition (§6). - MUST NOT expose one party’s rail credentials or funding details to the other party.
- MAY support multiple rails simultaneously; the payout rail is selected by the recipient’s wallet configuration (Layer 7).
7.2 Non-blockchain path (P4)
A plain credit ledger at the agent is a fully conforming rail: funding debits the buyer’s account balance, payout credits the payee’s. No chain, no token. This path MUST always remain implementable (RFC-0001 P4).
A more powerful chain-free rail exists in Chaumian blind-signature e-cash (e.g. GNU Taler): true bearer tokens with payer privacy and payee-side income transparency (AML/CFT-friendly), measured costs below USD 0.0001 per transaction, and settlement in a few hundred milliseconds — comfortably inside this layer’s latency target (§6), and priced for exactly the micro-amounts CU trades involve. See Chaum, Grothoff & Moser, How to Issue a Central Bank Digital Currency (SNB Working Paper, 2021) for the reference design. Like all rails here: a candidate binding, not a requirement.
7.3 x402 binding (informative)
x402 is an HTTP-402 stablecoin rail with immediate, single-round-trip settlement. That instant-settlement nature is not in tension with escrow-on-proof once the rail is placed at the edges of the escrow rather than in the middle:
- Funding edge: the buyer funds a lock by paying the escrow agent over
x402 (agent responds
402 Payment Requiredfor the lock amount; buyer pays; lock opens). Instant settlement into escrow is unproblematic — the funds are now held by the neutral agent. - Payout edge: after a release (or resolved claim), the agent transfers
the amount directly on the network and in the asset named by the
provider’s
onchain-transferpayout entry (Layer 7 §6.4). This hop is a plain on-chain transfer, not an x402 exchange: every x402 scheme in the specification repository (exact,upto,batch-settlement,auth-capture) moves value from a client to the resource server it calls, and a payout would need the provider to run an x402 server that charges the agent. Instant settlement out of escrow is exactly what the < 500 ms target wants.
In short: settle in → hold → settle out. The escrow guarantee lives at the
agent, between two instant hops — x402 on the way in, a direct transfer on
the way out. ACMP therefore needs no hold/capture semantics from the rail,
although x402 now offers them (below). This resolves the previously [OPEN]
question on reconciling instant-settlement rails with escrow-on-proof.
auth-capture as an on-chain escrow. x402’s
auth-capture
scheme (v1.1, 2026-08-18) holds funds — on EVM in an escrow contract — and
maps closely onto this layer’s states: authorize places the hold (lock),
capture releases all or part of it to the recipient (release), and void —
or the client’s own reclaim once captureDeadline passes — returns the
remainder (reclaim). In the EVM
binding,
operatorType: "custom" lets an operator contract add its own rules around
the lifecycle, time locks and arbitration among them; such a contract is the
smart contract variant of the Escrow Agent role (§1). Two limits keep it
from being a drop-in binding:
- The payee is fixed at
authorize. The client’s signed authorization commits to every payment field, the recipient included, so a hold cannot be bound to a provider later. That rules out RFC-0001’s lock-before-selection order andacmp/escrowBind(§4.2); it only fits locks taken after negotiation, withpayee_idknown. - Claims and disputes are not standardized. x402 defines no provider claim, challenge window, or dispute path (§4.5–§4.6). An operator contract can implement them, but as its own rules, not as an interoperable interface.
x402 also defines an MCP
transport,
but only for tool calls: the server answers tools/call with an
isError result carrying the payment requirements, and the client retries
with the payment under _meta["x402/payment"]. acmp/escrowLock is a
JSON-RPC method, not an MCP tool, so unlike MPP (§7.4) x402 cannot fund a lock
inside the Layer 1 connection without exposing the lock as a tool; over HTTP
the funding edge works as described above.
7.4 MPP binding (informative)
The Machine Payments Protocol (MPP), co-authored by Tempo
Labs and Stripe, carries the same request → payment challenge → pay → retry
pattern as x402 over several payment methods: stablecoins on various chains,
Lightning, and — through Stripe’s Shared Payment Tokens — cards. This binding
targets the Internet-Drafts
draft-httpauth-payment-01
(the core “Payment” scheme) and
draft-payment-transport-mcp-00
(its JSON-RPC and MCP transport). Both are drafts and may change.
MPP covers the funding edge only. Money in MPP flows from client to server: a server charges for a resource, and there is no payer-initiated push to a third party. That fits funding a lock — the buyer pays the escrow agent — but not payout, where the agent would have to push value to the provider. Payouts therefore stay with the recipient’s configured payout rail (Layer 7, §7.1). Half of settle in → hold → settle out runs over MPP; the other half does not.
Funding a lock over MCP. Escrow messages already travel over Layer 1, and
MPP’s MCP transport hooks payment into any JSON-RPC method. An escrow agent
that funds locks over MPP answers an acmp/escrowLock the buyer’s balance
cannot cover with MPP’s -32042 Payment Required instead of -35002,
offering one or more payment challenges for the lock amount converted at the
agent’s rate (illustratively 1 CU = USD 1 below; MPP amounts are in the
currency’s smallest unit):
{
"jsonrpc": "2.0",
"id": "req_5c11aa",
"error": {
"code": -32042,
"message": "Payment Required",
"data": {
"httpStatus": 402,
"challenges": [{
"id": "qB3wErTyU7iOpAsD9fGhJk",
"realm": "escrow.example.com",
"method": "stripe",
"intent": "charge",
"request": {
"amount": "1250",
"currency": "usd",
"externalId": "op_7d40e2aa",
"methodDetails": { "networkId": "profile_…", "paymentMethodTypes": ["card"] }
},
"expires": "2026-10-10T12:05:00Z"
}]
}
}
}
The buyer pays and retries the same request with the same op_ref,
echoing the challenge in an MPP credential under _meta:
{
"jsonrpc": "2.0",
"method": "acmp/escrowLock",
"id": "req_5c11ab",
"params": {
"op_ref": "op_7d40e2aa",
"amount_cu": 12.5,
"valid_until_ms": 1783017900000,
"_meta": {
"org.paymentauth/credential": {
"challenge": { "id": "qB3wErTyU7iOpAsD9fGhJk", "…": "echoed unchanged" },
"payload": { "spt": "spt_1N4Zv32eZvKYlo2CPhVPkJlW" }
}
}
}
}
The result is the ordinary §4.1 result (escrow_id, state: "open", …),
with MPP’s receipt (status, method, reference, challengeId) under
result._meta["org.paymentauth/receipt"]. Three existing rules do the rest:
- The unpaid first call changes no state, so under §3 it has not been
executed and the paid retry with the same
op_refis processed afresh. From then on §3 applies as usual: further retries return that one lock. - A rejected credential is MPP’s
-32043, which carries a fresh challenge. -35002 insufficient_fundsstill applies when the agent offers no funding path the buyer can use.
The CU-to-currency rate behind the challenge amount is the agent’s; CU exchange rates are open at RFC-0001 §5.
Small amounts. Card fees make charging per lock uneconomic at the CU amounts single tasks involve. The cheaper pattern is to fund a credit balance at the agent (§7.2) over MPP in larger steps and lock against it. How an agent sells balance top-ups is agent-specific and outside the §4 message set — for example an MPP-protected HTTP endpoint of the agent.
Cards, P4, and finality. MPP’s card path needs no blockchain, so it is a second external rail compatible with RFC-0001 P4 (§7.2 remains the mandatory path regardless). But a card charge is not final: MPP’s charge intent names card chargebacks as a reversibility case. A card-funded lock can be reversed after the agent has already paid the provider out. That risk sits with the escrow agent, not with the protocol, and how to bear it — accept it, price it in, or fund locks only from final methods such as stablecoins — is agent policy.
Compatibility with MCP 2026-07-28. MPP’s MCP draft predates the MCP
revision Layer 1 pins, in two ways an implementer will notice. It advertises
payment support in the InitializeResult, which 2026-07-28 removed together
with the handshake; up-front advertisement is therefore an open question here
(below). And -32042/-32043 fall inside -32020…-32099, the range
2026-07-28 reserves for the MCP specification itself — no collision today,
but MCP could assign those codes later. Neither affects the per-request flow
above, which only uses _meta and an error code.
Design Decisions
| Question | Decision | Rationale |
|---|---|---|
| Who holds the escrow? | Neutral Escrow Agent role (interface, not implementation) | Platform, trusted third party, or smart contract all conform; P4 keeps a non-chain path mandatory. |
| Who initiates the lock? | Buyer | Matches RFC-0001’s sequence and Layer 6’s accept (+ escrow_id). |
| Payee binding | Optional at lock, once-only bind afterwards | RFC-0001 locks before provider selection; binding at accept-time closes the gap without a second lock. |
| Silent-buyer problem | Provider claim + challenge window + auto-release | The settlement twin of Layer 3’s Optimistic Execution model; without it, providers bear unbounded non-payment risk. |
| Expiry | Auto-reclaim at valid_until_ms; pending claim/dispute suspends expiry |
No stranded funds, and the clock can never expropriate a timely claim. |
| Early-reclaim race | Bound escrows cannot be reclaimed before a first release/claim resolution | Otherwise a buyer could drain the escrow mid-task and beat the provider’s claim to the punch — the guard makes the safety path race-free. |
| Instant rails vs escrow-on-proof | Rails at the edges (fund-in / payout-out), escrow held at the agent | Dissolves the tension without requiring hold/capture semantics from any rail. |
| MPP’s role | Funding edge only, via MPP’s MCP transport on acmp/escrowLock |
MPP moves money client → server; payout would need a push MPP does not have. Hooking into the existing lock call reuses §3 idempotency and adds no method. |
| Error range | -35xxx | -33xxx is Layer 1; -34xxx is de-facto negotiation. |
Open Questions
[OPEN]Partial completions of streaming tasks (Layer 1 §7 / Layer 2 §5): can a partial result justify a partial claim, and how is “how much was delivered” measured? Deferred until Layer 3 matures.[OPEN]Abandoned interrupts. If Layer 1 gains resumable interrupts (L1 Open Questions, L2 Open Questions), a provider may pause a task awaiting buyer input while the buyer never returns. The escrow mechanics already exist — partial release (§4.3) and expiry auto-reclaim (§2) — so the open part is the trigger semantics, not the plumbing: does an interrupt carry its ownexpires_inwindow, does the task reach a terminalabandonedstate distinct from plain expiry, and is the provider partially settled for compute spent up to the interrupt point (rather than the buyer reclaiming everything)? Coupled to how “work done so far” is measured, which tracks Layer 3.[OPEN]Dispute arbitration: v0.1 leaves resolution to agent policy. Should a future version standardize an arbitration interface (e.g. a Layer 3 re-execution audit as neutral arbiter)? x402’sauth-captureleaves arbitration to custom operator contracts (§7.3) — a hook, not an interface ACMP could reference.[OPEN]Should the agent push state-change notifications (acmp/escrowResolved?) instead of requiringescrowStatuspolling?[OPEN]CU tier exchange rates — who publishes them and how often do they update? (Tracked at RFC-0001 §5.)[OPEN]MPP sessions as a two-party lock? MPP’s session intent opens a payment channel: the payer deposits funds, then signs cumulative vouchers as service is delivered, and the unused deposit returns at close. That resembles lock → partial release → reclaim between buyer and provider directly, without a neutral agent — but without the provider claim, challenge window, or dispute path either (§4.5–§4.6). Is there a useful profile for low-value, low-risk tasks, or does losing the silent-buyer protection rule it out? x402’sauth-capture(§7.3) is the closer comparison: a hold with partial capture and a client reclaim after a deadline, but likewise with the payee fixed up front and no claim path.[OPEN]Should the escrow-agent declaration (§1) advertise its funding rails up front (e.g. which MPP methods it accepts), now that MPP’s own MCP advertisement relies on the removedinitializehandshake (§7.4)? Today a buyer learns them from the-32042challenge itself.
Related
- RFC-0001 — At a Glance (the lock → release → reclaim sequence this layer implements)
- Layer 1 — Transport & Invocation (transport for all
escrow messages;
escrow_idinacmp/invoke;escrow_invalid-33005) - Layer 3 — Proof of Execution (proof acceptance triggers release; the claim path mirrors its optimistic model)
- Layer 6 — Negotiation Protocol (terms incl.
challenge window;
accept (+ escrow_id)) - Layer 7 — Agent Wallet (CU balance, payout rail configuration, verifiable identity)
- Machine Payments Protocol and its specifications repository (funding-edge rail, §7.4)
This document is part of the A2Agora specification. Licensed under Apache 2.0.