pen-to-squareWriting Effective Policies

Writing Effective Policies

Your policy is the foundation of everything ICME does. The quality of your guardrail is directly determined by the quality of your policy. This page covers how to write policies that compile cleanly, enforce precisely, and cover the edge cases that matter.


How ICME reads your policy

Before writing, it helps to understand what happens to your words. When you submit a policy, an LLM translates each statement into SMT-LIB formal logic. The compiler then checks the resulting rules for internal consistency. What makes it to the solver is a precise, mathematical representation of what you wrote.

This means two things:

Clarity beats cleverness. Write policies the way you would explain rules to a new employee, not the way you would write a legal contract. Short, declarative sentences formalize more reliably than long, nested clauses.

Be explicit about edge cases. The solver can only enforce what is in the policy. If a rule has an exception, write the exception. If a limit applies under certain conditions, write the conditions. Ambiguity in natural language becomes ambiguity in the logic — and ambiguous rules produce SATISFIABLE results rather than clean SAT or UNSAT.


Policy structure

A good policy is a numbered list of plain English rules. Each rule should express a single constraint.

Good:

1. Transfers over 1000 USDC are not permitted.
2. Transfers to wallets not on the approved list are not permitted.
3. No more than 3 transfers may be made within a 60-second window.

Harder to formalize:

1. Large transfers to unknown wallets are generally not permitted unless
   pre-approved, and the agent should also be careful about frequency.

The second version will compile, but the rules it produces will be less precise. "Large" is undefined. "Generally" introduces ambiguity. "Should also be careful" is not a constraint.


Policy examples by use case

DeFi and crypto agents

Autonomous payment agents

Enterprise AI assistants

Agentic coding tools

Healthcare and regulated industries


Common mistakes and how to fix them

Using relative terms without defining them

Large transactions require approval.Transactions over $5,000 require approval.

The solver needs a value it can evaluate. "Large" is meaningless to formal logic.


Writing policies that conflict with each other

This compiles but will produce IMPOSSIBLE results for any action involving an external wallet that hasn't been explicitly verified or unverified. ICME's consistency checker will flag this, use it as a signal to refine your rules.


Leaving implicit exceptions implicit

No transfers over 1000 USDC.

This blocks a transfer of 1000 USDC to an emergency fund, even if you intended that to be allowed.


Using process language instead of constraint language

The agent should check the whitelist before making transfers.

"Should check" describes a process, not a constraint. The solver doesn't evaluate processes.

Transfers are only permitted to wallets on the approved whitelist.


Writing compound rules that bundle multiple constraints

Large transfers to new wallets outside business hours require approval and must be logged.

This bundles four separate constraints into one sentence. Break it up.


Testing your policy before deploying

Before integrating your policy into a live agent, test it with a range of actions, including ones you expect to be blocked. Use /v1/checkIt during development.

Useful test patterns:

Boundary testing: if your policy blocks transfers over 1000 USDC, test exactly 999, exactly 1000, and exactly 1001.

Adversarial testing: try phrasing actions the way a bad actor might: vague descriptions, split transactions designed to stay under limits, indirect references to blocked actions.

Edge case testing: what happens if a field is missing? What if the wallet address is malformed? Write test cases for incomplete or unexpected inputs.

Contradiction hunting: if the solver returns IMPOSSIBLE on a reasonable action, it usually means two rules are conflicting. Revisit your policy for overlapping or contradictory constraints.


Policy versioning

Every call to /v1/makeRules produces a new policy_id. Treat these like code — keep a record of each version and what changed. If you need to roll back to a previous policy, you can do so immediately by switching the policy_id your agent passes to /v1/checkIt.

Good practice is to maintain at least three versions: production, staging, and draft. Test policy changes in staging before promoting to production.

Last updated