All posts
·5 min read·#architecture#policy

Belt and suspenders: policy as instruction and as enforcement.

How Yelt compiles a CFO's English sentence into a typed runtime descriptor, drops it into the agent's SKILL.md, and enforces it at the gateway anyway.

There's an old saying about belt and suspenders. The belt keeps your pants up. The suspenders keep your pants up if the belt breaks. Either alone is sufficient most days; together, they're sufficient on the day that matters.

Yelt's policy story is the same shape. We ship every policy as instruction to the agent, and as enforcement at the runtime. Either alone would catch most cases. Together, they catch the case that actually shows up in front of a regulator.

Policy as instruction

When a CFO publishes a policy in the Yelt dashboard, our renderer compiles it into a SKILL.md file and pushes it into every detected agent host on every machine running our CLI. Claude Code reads it. Cursor reads it. Codex CLI reads it. The agent now knows the org's rules — “don't pay above $500 to a new vendor without approval,” etc. — before it even attempts the action.

That works most of the time. Modern frontier models are honest and obedient when told a constraint clearly. But:

  • Models drift. A new version of the agent regresses on edge cases.
  • Context gets lost. The skill file falls out of the active context window during a long session.
  • Adversarial inputs. A prompt-injected email convinces the agent the policy doesn't apply this time.
  • Honest mistakes. The agent decides this $501 vendor must be in the allowlist, even though it isn't.
Telling an agent the rules is necessary. It is not sufficient.

Policy as enforcement

The same compiled policy descriptor — same canonical bytes, same version number — also lands in our Rust MCP gateway. Every outbound tool call from the agent passes through the gateway. Every call gets evaluated against the active policy bundle in sub-five-millisecond p99 latency. The strictest outcome wins: deny > approve_required > allow.

If the model forgets the rule, the runtime catches it. If the prompt-injected email confuses the agent, the gateway holds the action and pings the approver in Slack. If the agent honestly thinks $501 is fine, the gateway returns “blocked by spend-limit” and writes a row to the audit ledger.

Why ship both

Skills alone is the developer-tooling story. Most of the developer tooling ecosystem is doing it. It works for developer-grade trust.

Skills + gateway is the CFO story. The CFO doesn't care whether the agent “intended” to violate policy. They care whether the policy held. The runtime is what makes the claim auditable.

Belt and suspenders. We ship both because the case that matters is the case where the belt breaks.