Agent work for someone else
Seam ② Contract. Build: both sides' records of a deal between a principal's agent and a counterparty. Conform to: draft-mih-agent-evidence-request-00 and draft-mih-agent-settlement-records-00.
When an agent acts for a principal and deals with a counterparty, three parties hold records, and the evidence layer has to let each one check the others without trusting them.
1What it is
Agent work for someone else is an exchange with three parties: a principal who authorizes the work, an agent that does it, and a counterparty the agent deals with, often with a payment between them.
Each party seals only what its own side observed, under its own key, and asks the others for evidence with a request whose answer is exactly one of three things: the artifact, a signed refusal with a reason, or the asker's own record that nothing came.
Separate records answer separate questions (was it permitted, who authorized it, what was done, did the runtime enforce), and they are joined by one digest of the action rather than merged into one format.
2Design choices
payee_observed leg only from what its own wallet reported crediting and deducting.crates/evidence-plugin/src/settlement_legs.rs)3What it shows / what it does not
Shows
- That two records sealed under two distinct keys report the same payment reference, amount (after the receive fee) and status, or which of those differ.
- That a responder answered, refused with a stated reason under its signature, or that the asker recorded no answer inside its waiting window.
- That a responder gave two askers different bytes for the same subject and anchor: they compare artifact digests, without trusting each other (not for exchange subjects, which only one asker holds; there the responder's own recorded ask is the second copy, evidence-request §5).
- An omission: a party holding the other side's signed reply citing its half, when that side now answers
no_such_subject(evidence-request §3.1, §6). - That a WHO record and a WHAT record name the same action, by recomputing the digest each one binds.
Does not show
- That either side's observation is true; agreement on a digest attests to the digest, not to what it stands for.
- Who holds a key in the real world; that is the verifier's own key policy.
- Why nothing came back: a partition, a crash and a deliberate silence look the same (evidence-request §4.4).
- That evidence stays available; a responder's signed retention commitment makes a later absence attributable, not impossible (evidence-request §9).
- That the action was authorized, or that the record set is complete, just because digests match (accountability-composition-01 §6.2).
- Who is right when the two sides disagree; neither record is preferred.
4Example
Two conformance cases for the symmetric ask. The responder's declared holdings include one record that cites the asker's exchange half e2c78557…. Asking about that half is served; asking about a half no record cites is refused no_such_subject, never matched loosely.
"responder": {
"evidence_stream": "stream-a",
"log_size": 42,
…
"exchange_citations": {
"e2c78557e239cd93cf344c2e435158367deac1d3b525deb6e09c23d1a8139227": [
"ef53392288cd922e52ce6d54c30196a2f33af60ba87885b89cd34ed3d17a35d1"
]
},
…
},
…
{
"id": "res-exchange-cited",
"section": ["§3.1 Subject", "§6 The Symmetric Ask"],
"request_json": "{\"coverage\":{\"expected_pin\":\"e2c78557e239cd93cf344c2e435158367deac1d3b525deb6e09c23d1a8139227\"},\"nonce\":\"n-0107\",\"subject\":{\"exchange\":\"e2c78557e239cd93cf344c2e435158367deac1d3b525deb6e09c23d1a8139227\"}}",
"request_json_digest": "61a78ad010f8eee326f2bd696f21821c4bbf6731bb3e9dbdda257dcb0320ca42",
…
"expect": { "answer": "artifact" }
},
{
"id": "res-exchange-not-cited",
"section": ["§3.1 Subject", "§6 The Symmetric Ask"],
"request_json": "{\"coverage\":{\"expected_pin\":\"a2ad745b1e5290793135b8c1fb20887d6e8de485cccb6c14e63dfc8337038846\"},\"nonce\":\"n-0108\",\"subject\":{\"exchange\":\"a2ad745b1e5290793135b8c1fb20887d6e8de485cccb6c14e63dfc8337038846\"}}",
"request_json_digest": "0d60ed530c450e0d3521d9d4bc11aaa76ca3858d471779f30ef9ab280252a580",
…
"expect": { "answer": "refusal", "reason": "no_such_subject" }
}
| Field | Type | Meaning |
|---|---|---|
| responder.exchange_citations | object | The responder's holdings for this case: exchange-half digest → the records that cite it. |
| subject.exchange | hex | The asker's own sealed half of the exchange, by digest: what it wants evidence about. |
| coverage.expected_pin | hex | The anchor the answer must verify against; a requester's own exchange half is a valid pin for an exchange subject (§3.2). |
| nonce | string | Requester-supplied; recommended, so a recorded refusal cannot be replayed against a fresh request. |
| request_json_digest | hex | SHA-256 over the request bytes as received (RFC 8785 text); a refusal names the request by this digest. |
| expect.answer | string | artifact or refusal, written by hand from the draft text. |
| expect.reason | string | The most specific registered reason; here the half resolves to no record. |
The vectors are derived from the -00 text, not from any implementation; where -00 leaves a wire shape open (here, a subject as a one-member map), the file records the reading it used.
Source: action-state-group/agent-action-capsule:vectors/evidence-request/resolution.json @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
5Status
- live Exchange halves in the Mesh-LLM worked example: four paid exchanges between two nodes built from capsules v0.1.4, each node sealing its own half of each exchange.
Mesh-LLM/capsules:CHANGELOG.md(0.1.4, “Verified on live hosts, and not”) @b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad. Settlement legs and evidence requests were not checked in that run. - designed The whole flow in one host: a principal's authorization, the agent's and the counterparty's halves, settlement legs and evidence requests, recorded together for one piece of delegated work. Not built on any host this site describes.
- built-not-live Settlement-record legs, libraries and vectors: Python, Rust and Go code with conformance vectors in
action-state-group/agent-action-capsule(vectors/settlement/,python/agent_action_capsule/settlement.py,rust/agent-action-capsule/src/settlement.rs,go/settlement/) @2ef8aeb49e2334e24c404bd62d3fdb161770873c; producer and verifier inaction-state-group/capsule-emit(python/capsule_emit/settlement.py,rust/capsule-emit/src/settlement.rs) @d51a934ebf9d3efa3c86e7f27aaafe2bc06ac05d. - built-not-live Settlement legs in the Mesh-LLM worked example: for each invoice of a paid exchange, the payer seals the terms leg and pushes it to the serving peer, then seals
payer_observed; it seals one delivered leg per exchange, citing the output invoice's terms leg; the provider sealspayee_observed.Mesh-LLM/capsules:crates/evidence-plugin/src/settlement_legs.rsandCHANGELOG.md(0.1.1, “Settlement-record legs for paid exchanges”) @b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad(tag v0.1.4). The provider's leg needs host settlement events carrying the wallet's credited amount and fee: Mesh-LLM/mesh-llm PR 2169, merged. The v0.1.4 notes record a live two-node run of paid exchanges, not a check of the settlement legs themselves; the provider's own delivered leg is not sealed yet. - built-not-live Evidence request protocol: the
evidence-requestRust crate 0.2.0 (published on crates.io), with Python and Go implementations and the -00 conformance vectors, inaction-state-group/agent-action-capsule(rust/evidence-request/,python/agent_action_capsule/evidence_request.py,go/evidencerequest/,vectors/evidence-request/) @2ef8aeb49e2334e24c404bd62d3fdb161770873c. The Python responder moved there from capsule-emit in action-state-group/agent-action-capsule PR 244 (merged); capsule-emit's older module is deprecated (action-state-group/capsule-emit PR 314, merged). - built-not-live Evidence requests in the Mesh-LLM worked example: the plugin answers
evidence-request/1in-process, an artifact or a signed refusal, through the earliercapsule-emit-evidence-requestcrate pinned at=0.0.3, with a parity corpus that includes theexchangesubject.Mesh-LLM/capsules:crates/evidence-plugin/src/mesh_evidence_bridge.rs,src/evidence_request_parity.rs,docs/SHARING-POLICY.md@b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad. The v0.1.4 notes record no live run of an evidence request. - built-not-live WHAT joined to WHO: one composition vector set, an accepting case and three rejecting cases, each rejected at one named stage, with a staged verifier.
action-state-group/agent-action-capsule:vectors/interop/composition/@2ef8aeb49e2334e24c404bd62d3fdb161770873c. The WHO artifact in it is an external format, verified with its own tooling. - designed CAN and AUDIT slots: specified in accountability-composition-01 §6.1 and §6.4; no CAN or AUDIT cases in
vectors/interop/composition/@2ef8aeb49e2334e24c404bd62d3fdb161770873c. - planned A third attestor over the same action digest (for example a measured reading of the outcome): a reserved stub,
vectors/interop/composition/pos-composition-third-attestor-STUB/andDESIGN-NOTE.md@2ef8aeb49e2334e24c404bd62d3fdb161770873c.
6Specs
- Internet-Draft draft-mih-agent-evidence-request-00 — the request, the three outcomes, caller invariance, the symmetric ask, retention commitments.
- Internet-Draft draft-mih-agent-settlement-records-00 — two independent sealers, the four legs, exact amounts, derived payment and delivery states.
- Internet-Draft draft-mih-sato-agent-accountability-composition-01 — CAN, WHO, WHAT and AUDIT composed by a shared action digest; assurance tiers; cross-slot conformance.
- Internet-Draft draft-mih-agent-bilateral-attestation-02 — each side's attestation of its part of an exchange, refusals across the boundary, and the three asymmetry dispositions (delivery_unconfirmed, counterparty_timeout, countersign_refused).
- Internet-Draft draft-mih-scitt-agent-action-capsule-05 — the record every half and every leg is.
- RFC RFC 8785 — JSON Canonicalization Scheme: the JSON bytes under the evidence request digest and under the action digest in the WHAT×WHO vector set.
- RFC RFC 8949 — CBOR: the evidence request's CBOR binding, in deterministic encoding.
- RFC RFC 9943 — SCITT architecture: registering a record so a party who trusts neither side can check it.
- Code action-state-group/agent-action-capsule — the drafts' vectors, the
evidence-requestcrate, settlement libraries. - Code action-state-group/capsule-emit — settlement producer and verifier; bilateral handshake helpers.
- Code Mesh-LLM/capsules — the worked example: settlement legs and evidence requests in a Mesh-LLM plugin.
7What you need before the next step
- A host event for each paid exchange that names both sides and carries what each wallet reported, so each side can seal its own legs.
- A way for two parties to push sealed records to each other, and a channel to carry evidence requests and their answers.
- A deterministic artifact for each (subject, anchor), so two askers can compare what they were given.
- A place for the principal's authorization to live as its own signed record, joined to the agent's record by the action digest, rather than inside it.
- An honest status per part: which records your host seals today, and which are designed only.