Essay
A portable Outcome for an ERC-8183 job
We ran the full ERC-8183 job lifecycle on Arc testnet and made one change: the completion reason is the hash of a signed, portable verification receipt anyone can check outside the job contract.

Arc's ERC-8183 standard gives agents a real job lifecycle on-chain: create a job, escrow USDC, submit a deliverable, evaluate, settle. We ran that lifecycle twice on Arc testnet and changed one thing about the evaluator's output.
In the standard flow, the evaluator's judgment lives in one opaque field: complete(jobId, reason, optParams), where reason is a bytes32. The reference tutorial uses keccak256("deliverable-approved"). The job settles, but the reasoning behind the settlement isn't a thing another system can fetch, check, or reuse.
So our evaluator did this instead:
- Before the job was created, the acceptance criteria were fixed: the delivered record must include company, website, contact_email, and status.
- The provider submitted the deliverable hash on-chain, per the standard.
- The evaluator verified the actual deliverable with Spoolis and got back a signed Outcome Receipt naming what was checked, what passed, and what was earned.
- It called
complete()withreason = keccak256(receiptId), in this transaction.
The contract still sees a bytes32 reason. The difference is that the preimage now resolves to a signed record outside the contract.
Now the on-chain settlement points at a portable record. Anyone holding the transaction can recompute the reason from the hosted receipt and verify the Ed25519 signature. The judgment left the contract.
The chain that didn't settle
The second run used criteria the deliverable couldn't meet. The verification came back FAIL with its own signed receipt, the evaluator withheld complete(), and the escrow stayed put (the submitted job never settles). Same mechanism, both directions: the receipt explains why money moved, and why it didn't.
Why bother
ERC-8183 settles the job. What it doesn't natively give you is a portable evaluation of what counted, what didn't, why, and what was earned. That's the piece we make. Keep the job contract and settlement exactly as they are. Give the evaluator a result that travels.
The wire-level anatomy of this pattern, with every payload, is in anatomy of a verified transaction. How the receipt itself works: what is an Outcome receipt.
What this doesn't prove
- Testnet, faucet USDC, throwaway keys we control, the deployed reference contract. A mechanism proof, not adoption.
- Arc and Circle did not participate and are not partners or customers.
- The verification used our keyless sandbox door: real verification logic and a real signed receipt, marked environment: demo. A paid x402 variant looks identical from the contract's side.
Notes
Run date 2026-09-02, ahead of Arc's public mainnet on 2026-09-16. Every transaction hash, both job ids (182722 completed, 182724 held), and the reason preimage mapping are in the repo's evidence file (docs/research/arc/portable-outcome-evidence.json). One practical note for ERC-8183 integrators: on the deployed reference implementation, setBudget is provider-only; the provider quotes the price.