The agent is not trusted
That is the founding assumption. A sufficiently well-crafted clip — or campaign brief — will convince a model to approve a payout to an attacker, and no amount of prompt engineering makes that reliably false.
What is trusted · what is not · and what this does not defend against
Who is trusted with what
Four of the six actors are not trusted, including our own model.
| Actor | Trusted | Why |
|---|---|---|
| the operator | Yes | Authenticated human; their intent is the policy |
| the policy engine | Yes | Deterministic; reads nothing an attacker can write |
| the model | No | Reads attacker-influenced text; can be induced to propose anything |
| clips and briefs | No | Written by the party asking to be paid |
| reported view counts | No | Read from the platform, never from the submitter — and buyable either way |
| the payment client | Partly | Trusted to execute correctly; never as the only control |
Treating “the model won’t fall for it” as a control is the mistake this system exists to avoid. The same conclusion, reached independently from the data side: “behavioral instructions to models cannot substitute for deterministic authorization, because LLMs are probabilistic, not security mechanisms.”
Attacks in scope
What we assume somebody will try, and what happens when they do.
Payment redirection
A clip’s description instructs the agent to pay an attacker’s address. The agent proposes it — models do. The engine has no permission for that counterparty, so nothing moves, and the injected text is written to the record verbatim as evidence rather than discarded.
A real creator, bought views
An accepted creator posts a genuine clip and buys 800,000 views for it. Trusting a counterparty is not the same as accepting any number from them: the dwell window means bought views are gone before settlement, and the per-payment ceiling binds independently of who is being paid.
Drain by a thousand small charges
Every payment individually legal, under the cap, unremarkable. This is what a runaway actually looks like, and per-payment caps do nothing against it. The rolling window budget is the control that binds.
Authority nobody revokes
Permissions accumulate, the blast radius grows quietly over months, and adding one more is always cheaper than auditing the last twelve. Every permission expires. Inattention withdraws authority instead of extending it.
Paying twice
A retried request that spends again. Handled by idempotency on the reservation — see the architecture for where this is complete and where it is not yet.
The twenty-one invariants
The promises. Each enforced in code, each proved against generated inputs.
These are the promises. Each is enforced in code and checked against generated inputs rather than chosen examples — see testing.
| # | Invariant |
|---|---|
| I1 | Nothing above the absolute per-payment ceiling is ever authorized — no permission can raise it |
| I2 | Nothing is paid to a counterparty without live permission |
| I3 | No mainnet payment without an explicit, separate opt-in |
| I4 | The kill switch admits no exceptions |
| I5 | An expired permission authorizes nothing, at any time after expiry |
| I6 | Total authorized spend in a window never exceeds the window cap |
| I7 | The decision function is total — it never throws, for any input |
| I8 | It is deterministic — same inputs, same verdict |
| I9 | Policy is monotonic — tightening a limit never authorizes what the looser limit refused |
| I10 | Every decision names the control that produced it |
The first ten govern any payment. These eleven govern campaigns specifically — what a creator is owed, and what the agent may do about it.
| # | Invariant |
|---|---|
| I11 | A clip settles under the terms it was accepted under, until the deadline |
| I12 | Total payouts on a campaign never exceed its pool. Always |
| I13 | Views already paid for never decrease, so no view is ever paid twice |
| I14 | No payout without a preceding auto_pay decision |
| I15 | No payout without a passing verdict on the clip |
| I16 | No payout amount is ever negative, however the view count moves |
| I17 | A model output can never raise a cap or widen a rate band |
| I18 | Money never passes through a float — integer micro-USDC end to end, including into storage |
| I19 | The settlement wallet is derived from the network, never configured alongside it |
| I20 | Broadcasting and permitting mainnet are separate decisions; neither implies the other |
| I21 | No verdict the agent can return releases money — its strongest outcome is a delay |
I7 is a safety property, not a robustness nicety. An engine that can throw is an engine that can be made to fail open by whoever catches the exception.
I9 is about operability. Policy where tightening a cap might authorize something the looser cap refused is unreasonable to run — an operator would have no way to reason about what they just changed.
Out of scope, explicitly
What this does not defend against, named rather than left implied.
- Compromise of your provider credentials. If someone has your API keys they do not need your agent.
- Compromise of the host. Write access to the machine means write access to the record. The chain makes tampering detectable, not impossible.
- Malicious code in our own dependencies. The engine has none, which narrows this — it does not eliminate it.
- Whether the spend was wise. We enforce the limits you set. We have no opinion on whether buying that data was a good idea.