What Tesoro is
A type-3 AEGL you can pip install: ten
deterministic engines that decide whether an agent may spend, before it spends, and record which
control decided.
pip install tesoro
tesoro init
tesoro decide --amount 2.50 --vendor acme --resource /market/snapshot
The claim, in one line
Autonomous payment should not mean unrestricted payment.
Concretely, Tesoro is a policy-engine host. You supply a policy pack — the rules and the numbers — and it enforces that pack against a profile, producing a decision, an attribution, and an evidence record for every action an agent wants to take.
AEGS is one profile it can enforce, not its identity. Run it with
profile: none and it governs exactly as well; it simply makes no conformance claim.
Which is the adoption mechanism: nobody installs a standard. They install a spend cap, keep the
default profile, and emit conformant evidence without reading a specification.
What it produces
A decision
One of four verdicts, before money moves. Deterministic integer arithmetic — same inputs, same answer, replayable from the journal.
An attribution
Which control decided. The field you need when an agent stops at 2am and you have to know what to change.
Evidence
An append-only hash-chained record. Editing, middle-deletion and reordering are all detected.
$ tesoro report
policy : default 46abca353ed56adc 12 rules
profile : aegs-1
decisions: 3 settled 1 spent $0.060000
by attributed control -- what actually governed this agent
policy 2
treasury 1
envelopes: external
per_transaction per call ceiling $10.000000
daily today $0.060000 of $50.000000 headroom $49.940000 (tightest)
chain : 6 entries, VALID [sha256, 128 bits]
note : a hash chain detects edits and middle-deletions, not truncation…
by attributed control is the line worth reading. Counts by verdict say
what happened; counts by attributed control say what is actually governing this agent —
frequently not what whoever wrote the policy expected.
What makes it type 3 rather than a cap
Four things a per-payment limit cannot express, each of which exists because of a specific failure:
| Capability | Catches |
|---|---|
| Cumulative envelopes daily, monthly, per-counterparty, per-resource |
five identical purchases where only the sixth exhausts the day. The refused payment is byte-for-byte identical to the approved ones |
| Declared intent purpose, budget, scope, expiry |
an affordable purchase from a trusted counterparty of something the agent was never asked to buy. Treasury, trust, risk and policy all approve; only intent objects |
| Earned trust cold start, accrued over settlements, revoked by dispute |
a brand-new counterparty treated as if it had a track record |
| Delegation clamp a sub-agent's authority is the narrower of its own and its parent's |
a sub-agent claiming more than the agent that spawned it — including one that declares no limit at all |
That last parenthesis was a live escalation in this codebase. The layer compared a delegate's limits against its delegator's and refused anything larger — which detects nothing when the delegate declares no limit, because there is nothing comparable and the delegate has no ceiling of its own to trip. Declaring nothing was strictly more permissive than declaring a large number. A $1.00 payment was approved under a parent capped at $0.002. The specification now says clamp to the narrower rather than refuse the wider, because a clamp has to produce a number and so has no case it can quietly fail to cover.
Design commitments
These are not preferences. Each is enforced by a test that fails when it is violated.
- No model in the decision path. Every engine is integer arithmetic over structured values. An optional advisor may be consulted behind an economic gate and is clamped — it can tighten a verdict, never widen one.
-
Policy is data, never code. Declarative rules, a closed comparator vocabulary, no
eval. A security boundary: an executable policy pack fetched from a registry is remote code execution wearing a governance hat. -
Money never touches a float. Integer atomic units, converted once at the boundary
with a pinned rounding mode. Passing a
floatraises. - Two channels never share an envelope. Different currencies, counterparties and failure modes — and a different correct response to the same breach.
- Absent ≠ not-run ≠ unknown ≠ zero. Four distinct states, one classifier, enforced across every schema.
- Every control may only narrow. Widening is unreachable rather than refused.
- Agents do not import the governor. The governor wraps the agent, duck-typed. A test fails if that arrow reverses — otherwise “plugin” and “dependency” are indistinguishable.
- Keys are never stored, logged or journalled. A masked display path is the only way a key is ever shown.
- Evidence is append-only and hash-chained, with its one known gap documented rather than papered over.
The cost
A governed decision costs microseconds and zero tokens. Ten runs of 3,000 decisions against the published package:
| p50 | p99 | |
|---|---|---|
| median of ten runs | ~170 µs | 398 µs |
| range across runs | 139 – 330 µs | 272 – 1218 µs |
| spread | 2.4× | 4.5× |
Treat any single figure as a sample. The spread is machine load, and it is 2.4× on one laptop. An earlier single run reported 128 µs and that number got repeated in a README, a CLI doc and a test as though it were a property of the system — it sits below the observed minimum of ten later runs.
The honest short form is ~200 µs, varying by 2× with load, and it is recorded as a sealed measurement with its own limitations section.
What Tesoro does not do
Stated here rather than in a footnote, because everything above is only worth reading if this section is honest. Every item also appears in the CHANGELOG and the specification's security section.
- Structuring is undefended. Forty payments of a tenth of a cent breach no value envelope and no rate limit — 0.08% of a daily budget, nothing refused. It ships as a runnable demonstration rather than a paragraph. Catching it needs a control that reads the shape of a sequence, and no envelope does.
-
Velocity evasion is closed, and the fix was already in the standard. Pacing
under a rate limit used to be unbounded in total — 97 actions an hour against a
ceiling of 100 is 2,328 a day for $2.33, inside every value envelope. A rate limit bounds the
rate; no product of a rate limit and a duration was ever compared against anything.
actions_per_dayandactions_per_monthnow bound the total. AEGS-0.1-ENV-7 had permitted count envelopes since 0.1; what was missing was any window longer than an hour. -
Journal truncation is undetectable without an external anchor, and no anchor
is configured by default.
Governor.verify_anchored()exists and takes one — four outcomes,consistent/truncated/diverged/unknown, and an unreadable sink is never a pass. **An anchor bounds truncation rather than eliminating it:** everything appended since its last publication is unattested and still removable, so the honest claim is detectable beyond a bound you chose. No sink ships, deliberately — see below. - AML screening is a schema with no engine behind it. No list, no matching, no jurisdiction model. No regulatory compliance is claimed or sought.
- No independent implementation has been scored. Every conformance case and threat was written by the author of the system under test — the largest open question in the project.
- The CrewAI adapter's hooks are unverified against a real run — documentation only. Its governance behaviour is tested as thoroughly as the others; the hook names are not.
- Advisor prompt injection is untested. The narrowing clamp defends it structurally, and the clamp is well tested — but the attack itself is not in any threat catalogue.
0.x. The API may change before 1.0. Stated here, on the README, in the CHANGELOG header and at the end of the quickstart, because you are about to point this at a wallet.
The red-team suite's own summary, kept because it is the fairest available: it resists prose; it
did not resist a minus sign, and it does not yet resist patience. The minus sign — a
-$1000 payment that was approved, because every
amount ≤ headroom comparison is satisfied by a negative — is fixed and permanently
covered by a test vector. Patience is still open.