Most AI guardrail tools fight fire with fire: they use a model to decide whether an AI agent's action is safe. smart402 doesn't. Every decision comes from deterministic policy rules, evaluated in pure Python, with no inference step anywhere in the path.
Here's why that matters, and why we're not changing it.
The circular trust problem
If your agent misbehaves, you want to know why. With an LLM-based guardrail, the answer is "the model said no" (which tells you nothing you can act on). You can't reproduce the decision with the same inputs tomorrow. You can't write a test for it. You can't explain it to a user whose payment was blocked.
An LLM is a stochastic function. Running the same inputs twice can produce different outputs. For a payment guardrail (where the result of a wrong answer is money leaving a wallet), that's not acceptable.
Deterministic by design
smart402's evaluator is a stack of predicate checks run in a defined order:
- Is the amount within the configured maximum?
- Is the token on the allowed list?
- Is the chain on the allowed list?
- Is the counterparty blocklisted?
- Does this push the agent over its daily budget?
- ... and so on, through 13 policy types.
Every check is a pure function: same inputs, same output, every time. You can trace
exactly which rules fired on a given evaluation by reading the
triggered_rules array in the response.
# Response when a payment is denied by budget policy
{
"decision": "deny",
"triggered_rules": ["daily_budget"],
"latency_ms": 4,
"rules_checked": 6
}
What "auditable" actually means
"Auditable" is overloaded. Here it means: a human can read the policy config, read the evaluation response, and independently verify that the right decision was made, without running any code.
If daily_budget is set to $50 and the response shows
triggered_rules: ["daily_budget"], the audit trail is complete. There's
no embedding, no attention weight, no "the model weighted this factor at 0.73."
Security-conscious teams need this. Any payment guardrail that can't produce a human-readable explanation for every decision is not auditable. It's a black box with marketing copy around it.
No API dependency in the hot path
The other benefit of not using a model: your agent isn't one API outage away from being unable to pay. smart402 is self-contained: the evaluator runs in your own container, with your policies, against your data.
If smart402 itself is unreachable, the SDK's fail_open mode lets
payments through with a warning log. You decide the failure mode. There's no
upstream model provider in the chain whose uptime you're implicitly depending on.
Rules are version-controllable
Your policy config is data, not weights. You can store it in git, diff it, roll it
back, and deploy it atomically. If you tighten the max_transaction_amount
policy and something breaks, git revert fixes it immediately.
Model-based guardrails encode policy in fine-tuning runs or prompt text that lives outside your deployment pipeline. That's a footgun for anything operating at payment scale.
When would we add a model?
Potentially for anomaly detection: flagging transactions that are statistically unusual even if they pass all explicit rules. But that would be additive, not a replacement for the deterministic layer.
The hard boundary is: no model output ever directly gates a payment
decision. Signals from a model could inform a policy rule (e.g., an
anomaly_score_threshold policy), but the policy rule is what fires.
The rule produces the entry in triggered_rules. The model stays
advisory.
For now, 13 policy types cover the cases we see in production. When we add more, they'll follow the same pattern: pure functions, same-input-same-output, logged results.