Judge dossier · live proof & quickstart
Architecture & security ·
Protocol specification
Autonomous agents do not fail only because transactions fail. They also fail because the world changes while they are still working.
A transaction that was correct a few seconds ago may no longer be the transaction that should reach the blockchain. A spending limit changes. A recipient disappears from an allowlist. A market condition shifts. The agent is no longer facing a failed transaction; it is facing a different reality.
When the world changes, something has to decide how to adapt. An autonomous agent exists precisely to make that judgement: it observes the new reality and chooses what to do instead. Infrastructure cannot make that choice on the agent's behalf without trying to enumerate, in advance, every way the world might change — and an open world does not permit that. So the agent keeps the adaptive choice.
The architectural question Mandate explores is a different one: what must remain true while the agent adapts — and can that be made explicit and independently enforceable?
The agent chooses the candidate. Mandate makes the bounds of that choice explicit and enforceable.
KeeperHub already gives a clear owner to execution: once the transaction to execute is known, it reliably carries it through simulation, submission, routing, execution, and confirmation onchain. Mandate sits beside the agent's choice rather than making it — it does not pick the candidate; it bounds it.
Agent observes the world and chooses the candidate adaptation
↓
Mandate makes / checks the admissible envelope — what the adaptation may not violate
↓
KeeperHub submits the exact call
↓
Custody recomputes and enforces → executes or reverts
Software is beginning to operate on its own. Large language models no longer only generate text; through agent frameworks they invoke tools, call APIs, and execute long-running financial workflows without a person in the loop. That turns what was once an occasional human judgement — how to adapt when an authorized action no longer fits — into one the agent must make unattended, at machine rate, and it raises the question of where the limits of that judgement are written down.
Mandate is a prototype built around that boundary, and it reached this hypothesis through a first, deployed experiment. That experiment (V1) had a resolver choose the replacement deterministically — REDUCE_TO_LIMIT, 150 → 100 — and building it is what exposed the limitation the current hypothesis answers: infrastructure should not try to choose the agent's adaptation for it. V1 below is that historical first experiment; V2 is the current hypothesis, in which the agent chooses and Mandate bounds. The name for the boundary — a resolution seam — is provisional; the boundary matters more than the terminology, and the project does not claim the seam already exists.
For most of their history, models produced output a human then acted on. That is changing. MCP, A2A, AP2, the OpenAI Agents SDK, and Claude Code are turning agents into execution environments: the model decides, and something downstream carries the decision out.
As agents become operators rather than assistants, their work changes shape. It becomes long-running and unattended — a procurement cycle, a payroll run, a reimbursement queue, a treasury rebalance, a stream of internal allocations. These are not single actions. They are workflows.
A long-running workflow will meet a constraint — an allowlist, an expiry, a risk limit, a spending ceiling. These are the guardrails that make unattended operation safe, so meeting them is not a fault to engineer away; over a long run it is the expected case. When a step no longer fits, the system is not malfunctioning — it is doing exactly what it was told.
When a person supervised each step, the case where an authorized action no longer fit — a request just over a limit, a route suddenly unavailable — was resolved on the spot, by judgment, one instance at a time. It never needed a name, because someone always supplied the answer. Autonomy removes that someone. The same case now recurs at machine rate, across long unattended workflows, and has to be answered by declared rules rather than judgment.
An action that no longer fits reality is not an error to catch but a moment of adaptation. In autonomous systems the agent makes that adaptation; what no layer yet owns is an explicit, enforceable boundary on what the adaptation may not violate.
There are two different questions here, and stacks answer only the first.
Authorization asks: May this action run?
This asks: When the agent adapts and runs something else, what must still hold?
The first question keeps unsafe actions out. On its own it cannot keep a workflow moving: to a step that no longer fits, its only answer is to refuse it — and in an unattended workflow a refused step stalls dependent work or forces a human back into the loop. The agent's answer is to adapt; the second question asks what that adaptation is still bound by.
The second question is the one this repository is about.
Architecture is ultimately about assigning ownership of decisions. Systems are rarely divided along functions; they are divided along decisions — by which component is responsible for which choice. Modern stacks already give three of them a stable owner:
- authorization owns may this actor do this, under these terms?
- custody owns is this outcome valid, and may the funds move?
- settlement owns carry the effect out.
There is a fourth thing that needs an owner — not what runs when a request can no longer run as-is, which in an autonomous system the agent decides, but the boundary on that adaptation: what the agent's substitute is still required to preserve. The striking thing is not that no one enforces it. Everyone does, implicitly. Wallets encode it, workflow engines encode it, payment hosts encode it, applications encode it, human operators hold it in their heads. The implementation is not missing; it is everywhere, written differently each time. What is missing is an explicit, independently checkable owner for that boundary — and Mandate asks whether it deserves one of its own.
Some of the more durable moves in systems architecture were not new algorithms. They were acts of recognition: noticing that a decision made ad hoc in a hundred places was in fact one decision, and giving it a single owner — a name, a boundary, an interface — behind which the implementations became interchangeable. The decision usually existed, and was already made everywhere, long before it was isolated; what changed was that it became worth giving it an owner.
Whether this responsibility deserves an architectural owner of its own — whether there is a distinct seam here at all — is an open question, and it is the one Mandate explores rather than claims to have settled. The case for taking it seriously is that the decision has the shape that has, before, preceded isolation: it recurs, it is made differently everywhere, it has a clean input — an original request, the agent's proposed adaptation, and the active constraints — and a small set of outcomes (admit, or refuse), and it has a natural place in the stack — a seam between authorization, which decides whether, and custody, which decides whether the funds may move.
The argument for making it explicit is ordinary software architecture, and its decisive form is independent change. Authorization policy, custody rules, and the boundary on how an agent may adapt when a request no longer fits evolve for different reasons and on different schedules; fuse the third into the first two, and a change to any one forces the others to be re-reasoned and re-verified. A boundary earns its place precisely where a decision can change without the components around it changing with it — where it can be reasoned about, verified, replaced, and, if the shape recurs across systems, standardized on its own terms. The same decision inlined into application code has none of these properties. The wager here is not that any resolver is clever, but that this boundary changes on its own schedule often enough to deserve its own place to change.
The project's first move — its historical V1 — was to make the resolution itself explicit and give it an owner: a declared rule, a resolver, that maps a request the active constraints reject to the outcome that should run instead. This is the framing the current hypothesis moved past, but it is where the work began, and it is worth seeing on its own terms. The resolver is the implementation; the subject is the decision it makes explicit, and where that decision lives. It never has the last word.
The historical V1 responsibility split:
Agent / intent
│ proposes a financial action
▼
Authorization who may act, under what terms (AP2, session key, role)
│ an authorized request
▼
Mandate derives the constrained candidate action and
builds the exact MandateVault calldata (the boundary this repository explores)
│ candidate vault call
▼
KeeperHub submits and observes the transaction (on-chain execution + reliability)
│ transaction invoking the vault
▼
MandateVault recomputes the relation during execution, verifies
the active mandate, and executes or reverts (custody; last non-bypassable point)
│
▼
Blockchain receipt and logs
Mandate is not another execution layer; it sits before submission. In this V1 model the resolver proposes; custody verifies and enforces. Nothing off-chain — not the agent, the model, or the resolver — can move funds on its own; the contract that holds them recomputes the relation and is the final authority. Chronologically, KeeperHub invokes the vault before the vault can verify anything; architecturally, MandateVault remains the final authority because the transaction succeeds only if the vault accepts the candidate action. Isolation is not cosmetic here: because the resolver is only a proposer, its output can be checked by the party that actually matters, and by anyone afterward, without trusting the code that produced it — and it is the same isolation the current hypothesis relies on, with the agent now supplying the candidate.
Four levels sit apart here, and it is worth keeping them apart: Mandate is the project; the question it investigates is whether this decision has an owner of its own — the boundary this repository calls a resolution seam; MandateVault is that boundary's first implementation; and REDUCE_TO_LIMIT its first resolver.
REDUCE_TO_LIMIT is the first implemented resolver. It exists because it exercises the complete architecture end to end, not because it is the point.
When a transfer proposes more than the active on-chain ceiling, the resolver proposes the transfer at exactly the ceiling — and only when the request truly exceeded it — leaving recipient, asset, chain, and action class unchanged. The vault (MandateVault) recomputes the relation on chain:
originalAmount > activeCap
executedAmount == activeCap
and moves the funds only if it holds. The clamp min(requested, cap) is trivial. What the prototype demonstrates is the separation around it.
For divisible, best-effort work — internal allocation, discretionary top-ups, a treasury rebalance — this lets a small overrun resolve to the permitted outcome and the workflow continue, without weakening the ceiling or trusting the agent, and with the reduction verifiable afterwards.
It is the wrong resolver for invoices, atomic purchases, collateral, or any exact obligation where a partial outcome changes the economic finality. There, the right answer is a different resolver or a terminal outcome — reject, defer, queue for review — never a silent reduction. A resolver's suitability is declared in advance, never inferred.
Building V1 clarified the limitation: a resolver that derives the replacement is, in the end, infrastructure choosing the agent's adaptation for it — and an open world cannot be enumerated that way. The current hypothesis keeps the adaptive choice with the agent and narrows Mandate to bounding it. It is proven offline, against an unchanged ResolvingVault: the agent chooses the candidate; the vault enforces the envelope.
A new resolver, BoundedAdaptationResolver (code 4), is a pure admissibility verifier: given a candidate the agent already chose, it checks whether that candidate lies inside the mandate's admissible space (0, bound], strictly below the recorded request. It never produces the candidate. Under one mandate (bound 100, recorded request 150):
V1 REDUCE_TO_LIMIT 150 → 100 only (a point)
V2 BOUNDED_ADAPTATION 150 → 83 ✓ 150 → 71 ✓ 150 → 100 ✓ 150 → 101 ✗ (a bounded space)
V1 resolves to a point; V2 admits a bounded space and leaves the choice of a point inside it to the agent. Proven offline in test/ResolvingVaultV2Adaptation.t.sol; no new deployment, and the historical Base Sepolia evidence demonstrates V1, not V2.
This experiment does not claim a security primitive stronger than a programmable wallet policy. The original request is operator-asserted, not owner-signed, and recipient continuity is allowlist-based and record-internal — not a cryptographic proof that the executed recipient equals an independently committed original recipient (the test test_v2_different_allowlisted_recipient_executes makes this boundary visible). Binding the original intent independently is future work.
KeeperHub is the on-chain execution and reliability layer, and Mandate is built above it, not beside it. Once the candidate vault call is known — the agent's chosen adaptation in the current hypothesis, or REDUCE_TO_LIMIT's deterministic outcome in the historical V1 path — KeeperHub submits it and owns the operational last mile of that submission: simulation where available, gas, retries and backoff, nonce management, routing and MEV protection, status tracking, the audit trail, transaction-hash retrieval, and confirmation. It is the transaction KeeperHub submits that invokes the vault, which then recomputes the relation during execution and either moves the funds or reverts.
So the split is: KeeperHub submits the call; the fund-holding vault decides whether that call is valid and whether the funds move. In the deployed V1 path that authority is MandateVault; in the V2 experiment it is ResolvingVault. Mandate claims neither role. It does not submit the transaction, choose an RPC, manage nonces or gas, or guarantee that a call lands; in the historical V1 path it derived the deterministic candidate and built the exact calldata, and in the current V2 hypothesis it makes the admissible envelope explicit and checks the agent's candidate against it. In one line: Mandate is a constraint-boundary and custody-enforcement component built above KeeperHub's execution and reliability layer. KeeperHub, for its part, never decides whether the candidate action satisfies the mandate, and never changes the recipient, the asset, the candidate amount, or the verified outcome.
For the deployed V1 path, anyone can recompute the deterministic resolution record from the public receipt and logs — the proposed and executed amounts, the active ceiling and policy version, the asset, chain, and action class, and the intent-hash relation — without trusting the resolver or the operator. Independent verification is exactly the property an isolated responsibility buys you: the resolution can be checked on its own terms, by a third party, without re-deriving the whole system. In the V2 experiment the same record shows the recorded request and the executed candidate evaluated under the mandate; but recipient continuity there is allowlist-constrained and record-internal, and is not a proof that the executed recipient matches an independently authorized original recipient — the original request is operator-asserted, not owner-signed. This is a recomputable adaptation record. See the architecture and security reference.
The two-question split maps onto existing work. AP2 can supply the authorization evidence — who may act and under what terms. This prototype addresses the admissibility boundary around an agent-chosen candidate and its enforcement at the resource once that candidate reaches the execution path. The deployed V1 path instantiated that boundary as deterministic resolution; the current V2 experiment tests bounded adaptation instead. The two compose along different responsibilities. AP2 is not implemented here, and the MVP stands in for a full authorization layer with a fixed on-chain operator role rather than a signed authorization over the original request.
Custody is the last non-bypassable check. A compromised agent, an altered payload, an alternative client, or a misbehaving operator cannot produce an outcome the constraints reject, because the vault recomputes the relation itself. Governance may tighten immediately — lower the ceiling, remove a recipient, freeze — and loosen only behind a timelock. Out of scope: a malicious owner, a compromised owner key, a contract or chain flaw.
- the live Base Sepolia deployment is the first, resolver-inlined
MandateVault, over one ERC-20 action and one scalar field; - the repository additionally proves a substitutable
IResolverboundary withNONE,REDUCE_TO_LIMIT, and terminalREJECT_OVER_CAPpolicies; - a separate, offline V2 experiment adds one resolver (
BoundedAdaptationResolver, code 4) under which the same mandate accepts agent-chosen candidates150→83and150→71and rejects150→101, distinct from the deterministicREDUCE_TO_LIMITpoint — and it claims no security beyond a programmable wallet policy (the original request is operator-asserted, not owner-signed); - the same resolver contracts are exercised unchanged in a second, token-free bounded-parameter domain;
- AP2 is not integrated; the MVP's authorization context is an operator role;
- public recomputation is shown for the deployed Base Sepolia path; the substitutable seam and second domain are proven offline.
There is one recommended reading path: this overview → judge dossier. The two technical references are optional deep dives.
| Path | Role |
|---|---|
SUBMISSION.md |
judge dossier: live proof, KeeperHub surfaces, quickstart, current policy, and scope |
docs/architecture.md |
optional architecture, trust boundaries, threat model, resolver taxonomy, and AP2 sketch |
docs/mandate-vault-specification.md |
optional normative encodings, guards, events, vectors, verifier order, and D2/D3 rules |
src/ |
Solidity contracts and resolver implementations |
packages/ |
canonical protocol, compatibility façade, and KeeperHub adapter |
test/ |
Foundry proofs, integration tests, and invariants |
make proof # 96 Foundry tests + 90 Vitest tests
pnpm e2e:local # real local EVM: deploy → submit → confirm → recomputeThe revealing experiment is no longer whether another resolver can choose a different replacement. It is whether one unchanged mandate can admit multiple agent-chosen adaptations while custody continues to enforce the same boundary.
Whether that responsibility deserves abstraction beyond a programmable wallet policy remains deliberately open.
Today's financial systems mostly describe what an agent is authorized to do. As agents become operators, the recurring question is no longer only whether an action is permitted, but how the agent should adapt when a permitted action no longer fits reality.
The temptation is to answer that in infrastructure — to enumerate, in advance, what should run instead. The first experiment here did exactly that, deterministically, and it ran on Base Sepolia. Building it clarified the limit of the approach: an open world cannot be enumerated, and an autonomous agent exists precisely to exercise the judgement that enumeration would replace. So the agent should keep the adaptive choice.
What remains for infrastructure is narrower, and possibly more durable: not deciding how the agent adapts, but making explicit — and independently enforceable — what that adaptation may not violate. Whether that boundary deserves an owner of its own is the open question; Mandate demonstrates one small, honest instance of it, and is careful about what it does not yet prove.
That points past any single project. For decades, this kind of infrastructure advanced by making permissions explicit — naming ever more precisely what a party may do. Autonomous operation may ask for the next step to be different: not naming what the agent should do when the world changes, but making explicit what must remain true while it decides for itself.
The action may change. The mandate may not.