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 Required for 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-transfer payout 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 and acmp/escrowBind (§4.2); it only fits locks taken after negotiation, with payee_id known.
  • 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_ref is 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_funds still 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 own expires_in window, does the task reach a terminal abandoned state 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’s auth-capture leaves 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 requiring escrowStatus polling?
  • [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’s auth-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 removed initialize handshake (§7.4)? Today a buyer learns them from the -32042 challenge itself.


This document is part of the A2Agora specification. Licensed under Apache 2.0.


This site uses Just the Docs, a documentation theme for Jekyll.