Architecture
Ten deterministic engines behind one call. Every one of them may narrow a verdict and none may widen it, so the decision is order-independent — but the attribution is not, which is why evaluation order is part of the specification.
The decision path
amount ≤ headroom comparison ever written, so a -$1000
request was once approved by this very layer. It is now refused before an envelope is
read, and both that bug and a 30-digit overflow are permanent test vectors.
The ten engines
| Engine | Group | Answers |
|---|---|---|
treasury | economic | Is there headroom in every envelope this action touches? |
intent | economic | Is this what the agent was sent to do? |
policy | economic | What do the operator's own rules say? |
roi | economic | Is the expected value worth the price? |
trust | risk | Has this counterparty earned anything, over how many settlements? |
risk | risk | Does this action's shape score as risky? |
identity | evidence | Who is acting, under whose authority, and is it still valid? |
audit | evidence | Append the record, and verify the chain. |
escalation | evidence | What needs a human, and how does it get to one? |
eiap | evidence | Is consulting an advisory model economically rational here? |
No engine imports another engine's family, and none imports the runtime.
Enforced by test, not convention. An engine that reached into runtime would be able
to see state the decision path is not supposed to depend on, and the determinism guarantee would
quietly stop holding.
Narrowing, and why widening is unreachable
Every engine returns an assessment. The final verdict is the most severe one any engine produced — so a single control can refuse, and no control can rescue an action another control refused.
That makes the verdict order-independent: run the engines in any sequence and the answer is identical. But the attributed control is not order-independent, and that asymmetry is why AEGS makes evaluation order normative and why conformance scores attribution rather than just the verdict.
A worked example of why attribution is hard. A sanctioned counterparty asks for more than the per-transaction ceiling. Both controls refuse. If attribution is “the last control that narrowed”, the answer depends on which limit happened to trip first — so a sanctions refusal could be reported as a budget problem.
The specification fixes this with dispositive controls: a finding that decides
attribution whether or not it narrowed anything, and which must be declared.
sanctions is the only one Tesoro declares.
Two channels, never one budget
Why no model sits on the decision path
Every engine is integer arithmetic over structured values. Nothing in the decision path reads natural language, which has three consequences worth separating:
Cost
A decision costs microseconds and zero tokens. Ten runs of 3,000 decisions gave a p50 median of ~170 µs — and a 2.4× spread, so treat any single figure as a sample.
Determinism
Same inputs, same verdict, replayable from the journal. A model on the path would make the evidence unreproducible.
Prose injection
Structurally absent. There is nothing on the path that interprets language, so there is nothing to talk into anything.
That third one is the strongest property the design has, and it is worth being precise about why: the defence is not a filter. A filter can be got wrong. The attack surface does not exist. Seven injection payloads through every counterparty-controlled field produce fourteen verdicts identical to the baseline — not because the text was sanitised, but because nothing read it. The text survives verbatim in the journal, which is compatible with being inert only because nothing interprets it.
It reopens the moment a model is put on the path. Tesoro has an optional advisory model, consulted only behind an economic gate and clamped — it may tighten a verdict, never widen one. The clamp is well tested. Advisor injection itself is not tested and is recorded as an open finding.
Money never touches a float
Integer atomic units internally — USDC has 6 decimals, so 2500000 is
$2.50 — with conversion once at the boundary and an explicitly specified rounding mode
(half-up). Passing a float raises rather than rounding quietly.
# both of these are $2.50
gov.authorize(amount_usd="2.50", ...) # a decimal string
gov.authorize(amount_usd=2500000, ...) # atomic units
gov.authorize(amount_usd=2.50, ...) # TypeError
The rounding mode is pinned because every language's default differs and none is wrong in isolation — an implementation inheriting its own has made a decision it did not know it was making.
Evidence, and exactly what it proves
hexdigest()[:16] independently — at 64 bits a second preimage is 2⁶⁴ work, reachable
with commodity GPUs in months, which weakens edit detection directly. All hashes now route through
one module so the length exists in one place.
Governor.verify_anchored() closes this against an external anchor, and
bounds rather than eliminates it: anything appended since the anchor's last publication is
unattested. Four outcomes, and an anchor that cannot be read reports unknown —
never consistent, because otherwise anyone who can cut the verifier off from the
sink can also make a truncated journal verify.
The gap remains disclosed rather than fixed by default, and the fix that looks like one
is worth naming: writing the chain head and length to a second file beside the journal is
not an anchor, because whoever can truncate the journal can rewrite that file. Shipping it
would be worse than shipping the gap, because it would make the system appear anchored.
Four states, never three
absent ≠ not-run ≠ unknown ≠ zero. These are
four different answers and conflating any two of them loses information a reader needs:
| State | Means | Confusing it with zero would say |
|---|---|---|
absent | nothing was claimed | “we measured, and the answer was nothing” |
not-run | the control exists and declined to answer | same, and worse — it hides a gap |
unknown | it ran and cannot report a value | the failure this rule exists to prevent |
zero | it ran and the answer really is zero or false | — |
From a real defect: an unmeasured vendor history rendered as 0 made every advisor
treat established counterparties as strangers. In the HTML report, an unset limit renders
as absent and never as $0.00 — rendering it as zero would state the
tightest possible ceiling where there is none, which is exactly inverted.
Reference
Public API
Stability tiers, what is deliberately not public, and where the document has been wrong.
api-surface.md →