Deterministic decisions for agents

Your LLM is great at language.
It's not great at deciding.

LogicPearl is the piece that decides. Compile your policy into an 8 KB Wasm artifact — same input, same verdict, every time, with a signed rule trace you can replay a year later.

$ npx @logicpearl/try --explain
GitHub · MIT licensed · Rust · Python · Wasm · stdio MCP server
Watch it fail, watch it hold

A customer writes this. Your LLM and LogicPearl disagree.

Same refund policy, same customer message, default temperature. This is a real capture: 5 serial calls to Claude Sonnet 4.5 on the left, one LogicPearl evaluation on the right, both staring at the same input.

Inbound customer message

Hi — I ordered the desk lamp exactly 30 days ago today. It's still in the box, never opened. I realized I don't really need it. Can I return it for a refund?

from: emily.ross@example.com order #47281 · $119.00 · 1 prior refund

LLM Claude Sonnet 4.5 · 5 runs

  Run 1  (3.2s)    APPROVE
        "Falls within 30-day window."
  Run 2  (3.4s)    APPROVE
        "Exactly at the 30-day deadline."
  Run 3  (3.2s)    APPROVE
        "Section 1 accepts within 30 days."
  Run 4  (3.1s)    APPROVE
        "Standard return window."
  Run 5  (3.2s)    APPROVE
        "Policy explicitly accepts."

  5/5 disagree with the artifact
  ~16 s total · ~$0.025 spend

LogicPearl compiled artifact · 1 run

  Input (extracted by LLM):
    days_since_purchase    30
    reason_category        "changed_mind"
    item_is_digital        false
    item_used              false
    order_amount_usd       119
    previous_refunds_90d   1

  Verdict:    DENY
  Fired:      rule_001
               days > 29 AND reason == changed_mind
  Latency:    0.37 ms
  Bitmask:    0b00010
  Artifact:   sha256:6713173a…

  byte-identical every run  · $0 · replayable
Both answers are defensible. The policy prose says "within 30 days"; the business codified it as days > 29 → DENY. Your LLM reasons from the prose and changes its mind as its version changes. The artifact enforces the compiled policy, byte-identical, signed. Only one is your policy of record.
The pattern

Put each on the side it's good at.

The split above isn't a choice of one or the other. In practice you let the LLM do what it's great at — reading prose, extracting structured data — and let LogicPearl do the decision.

Stage 1 · LLM
Read the message, extract features
Emily's message becomes a 6-field vector: days=30, reason=changed_mind, digital=false, used=false, …. Schema-checked, narrow, testable.
Stage 2 · LogicPearl
Evaluate the compiled policy
Signed Wasm artifact, ~0.3 ms. Returns the verdict, which rule fired, a counterfactual hint, and a bitmask you can pin to this decision forever.
Stage 3 · LLM
Phrase the reply to the customer
"Hi Emily, unfortunately your order passed our 30-day change-of-mind window…" — the words change, the decision doesn't.
Drop it into your agent

One command plugs LogicPearl into Claude Desktop and Cursor.

npx @logicpearl/mcp install writes the config for both hosts with timestamped backups. Every chat then has access to three tools — the LLM decides when to call them.

logicpearl_evaluate
Run a feature vector through the artifact. Returns verdict, fired rules, counterfactual hints, bitmask.
logicpearl_describe_artifact
Feature schema, allowed values, optional extraction-prompt template the agent can self-configure from.
logicpearl_list_rules
Every rule with a human-readable label and counterfactual. The LLM uses this to explain verdicts.
MCP docs →
See it in production shape

Three end-to-end demos using the same engine.

The refund case above is the quickest one to show. These are the same primitive running against harder data — live Wasm artifacts, governance traces, counterfactual hints, the works.

Working on something where this fits? ken@logicpearl.com.

Writing