Show HN: Statewright – Visual state machines that make AI agents reliable

Hacker News Top Tools

Summary

Statewright is an open-source tool that uses visual state machines to enforce guardrails on AI agents, improving reliability for models like GPT and Llama by constraining tool usage to specific workflow phases.

Agentic problem solving in its current state is very brittle. I fell in love with it, but it creates as many problems as it solves.<p>I&#x27;m Ben Cochran, I spent 20+ years in the trenches with full-stack Engineering, DevOps, high performance computing &amp; ML with stints at NVIDIA, AMD and various other organizations most recently as a Distinguished Engineer.<p>For agents to work reliably you either need massive parameter counts or massive context windows to keep the solution spaces workable. Most people are brute forcing reliability with bigger models and longer prompts.<p>What if I made the problem smaller instead of making the model bigger?<p>I took a different approach by using smaller models: models in the 13-20B parameter range and set them to task solving real SWE-bench problems. I constrained the tool and solution spaces using formal state machines. Each state in the machine defines which tools the model can access, how many iterations it gets and what transitions are valid. A planning state gets read-only tools. An implementation state gets edit tools (scoped to prevent mega edits) and write friendly bash tools. The testing state gets bash but only for testing commands. The model cannot physically skip steps or use the wrong tool at the wrong time. It is enforced via protocol, not via prompts.<p>The results were more promising than I would have expected. Across multiple model families irrespective of age (qwen-coder, gpt-oss, gemma4) and the improvements were consistent above the 13B parameter inflection point. Below that, models can navigate the state machine but can&#x27;t retain enough context to produce accurate edits. More on the research bit: <a href="https:&#x2F;&#x2F;statewright.ai&#x2F;research" rel="nofollow">https:&#x2F;&#x2F;statewright.ai&#x2F;research</a><p>Surprisingly this yielded improvements in frontier models as well. Haiku and Sonnet start to punch above their weight and Opus solves more reliably with fewer tokens and death spirals. Fine tuning did not yield these kinds of functional improvements for me. The takeaway it seems is that context window utilization matters more than raw context size - a tightly scoped working context at each step outperforms a model given carte blanche over everything. Constraining LLMs which are non-idempotent by using deterministic code is a pattern that nobody is currently talking about.<p>So, I built Statewright. Its core is a Rust engine that evaluates state machine definitions: states, transitions, guards and tool restrictions. Its orchestration doesn&#x27;t use an LLM, just enforces the state machine. On top of that is a plugin layer that integrates with Claude Code (and soon Codex, Cursor and others) via MCP. When you activate a workflow, hooks enforce the guardrails per state automatically. The model sees 5 tools available instead of dozens, gets clear instructions for the current phase and transitions when conditions are met. Importantly it tells the model when it&#x27;s attempting to do something that isn&#x27;t in scope, incorrect or when it needs to try something else after getting stuck.<p>You can use your agent via MCP to build a state machine for you to solve a problem in your current context. The visual editor at statewright.ai lets you tweak these workflows in a graph view... You can clearly see the failure paths, the retry loops and the approval gates. State machines aren&#x27;t DAGs; they loop and retry, which is what agentic work actually needs.<p>Statewright is currently live with a free tier, try it out in Claude Code by running the following:<p>&#x2F;plugin marketplace add statewright&#x2F;statewright<p>&#x2F;plugin install statewright<p>&#x2F;reload-plugins<p>Then &quot;start the bugfix workflow&quot; or &#x2F;statewright start bugfix. You&#x27;ll need to paste your API key when prompted. The latest versions of Claude may complain -- paste the API key again and say you really mean it, Claude is just being cautious here.<p>Feedback is welcome on the workflow editor, the plugin experience, and tell me what workflows you&#x27;d want to build first. Agents are suggestions, states are laws.
Original Article
View Cached Full Text

Cached at: 05/13/26, 12:26 AM

statewright/statewright

Source: https://github.com/statewright/statewright

statewright

Agents are suggestions, states are laws.

State machine guardrails that control which tools your AI agent can use in each phase. Define a workflow once, enforce it across Claude Code, Codex, Cursor, opencode, and Pi. Full docs →

Statewright workflow editor

Quickstart

Try it out in Claude Code on the free tier by running the following:

/plugin marketplace add statewright/statewright

/plugin install statewright

/reload-plugins

Then start the bugfix workflow or /statewright start bugfix. You’ll need to paste your API key when prompted. The latest versions of Claude may complain – paste the API key again and say you really mean it, Claude is just being cautious here.

The problem

AI agents are powerful but brittle. Give a model 40+ tools and an open-ended problem and it barely gets out of the gate. The common fix is bigger models and longer prompts… it helps sometimes. Observability tells you what went wrong after the fact; it doesn’t prevent it.

The approach

Instead of making the model bigger, make the problem smaller.

State machines constrain the tool and solution spaces so the model reasons in a focused context at each step. A planning state gets read-only tools. When the agent transitions to implementation, edit tools unlock with limited shell access (write-via-redirect and destructive ops are blocked even when Bash is allowed). Testing only permits designated test commands. If you call a tool that’s not in the current phase, you get rejected with a message telling you what IS available and how to transition.

Works the same way on frontier models (fewer tokens to completion) and local models where 13B+ models start solving tasks they’d otherwise fail.

Research results

ModelSizeBug Fix (26 lines)SWE-bench (5 tasks)
gemma33.3GBFAILFAIL
gemma4:e2b7.2GBPASS*FAIL
gpt-oss:20b13.8GBPASSPASS (5/5)
gemma4:31b19.9GBPASSPASS (5/5)
llama3.342.5GBPASSPASS (2/2)†

*with specialized edit_line tool adaptation †tested on 2 of the 5 tasks (added after initial experiment run)

We validated on local models where the effect is most measurable. In our 5-task SWE-bench subset, two models (13.8GB and 19.9GB) went from 2/10 to 10/10 with statewright constraints. Same tasks, same hardware. Below 13GB, models can produce tool calls but can’t retain enough file content to produce accurate edits — that’s the floor, not a statewright limitation.

Frontier models with default system prompts handle the obvious catastrophic actions (database deletion, credential leaks)… most of the time. The structural win is bigger: breaking read-loop death spirals where models re-read the same file 5+ times without ever editing, and keeping the tool space small enough that the model actually reasons instead of flailing. Research brief →

Quick start

Install into Claude Code:

/plugin marketplace add statewright/statewright
/plugin install statewright

Your browser opens → sign up at statewright.ai → generate a key → paste it → done.

Then start a workflow:

❯ start the bugfix workflow — fix the failing tests in calc.py

◆ statewright — statewright_start (workflow: bugfix)
◆ [statewright] Workflow activated: bugfix

◆ statewright — statewright_get_state (MCP)

◆ Current phase: planning. Let me read the code first.

  Read 2 files

  [statewright] planning => implementing

◆ statewright — statewright_transition (READY)

  Edit calc.py: 1 line changed

  [statewright] implementing => testing

◆ statewright — statewright_transition (DONE)

  Bash: pytest -x — 7 passed

  [statewright] testing => completed
◆ [statewright] Workflow complete. 46 seconds.

You can also use the slash command directly: /statewright start bugfix.

How it works

The core is a Rust engine that evaluates state machine definitions: states, transitions, guards, tool restrictions. It’s deterministic. No LLM in the loop.

On top of that sits a plugin layer that integrates with your coding agent via MCP. When you activate a workflow, hooks enforce tool restrictions per state automatically. The model sees 5 tools instead of 30, gets clear instructions for the current phase, and transitions when conditions are met.

Guardrails

GuardrailWhat it does
Per-state tool enforcementTools invisible to agent when not in allowed_tools
Bash discernmentRedirects (>>), destructive ops (rm, shred), and scripting interpreters blocked in non-write states
Edit guardsRejects diffs exceeding max_edit_lines, caps files edited per state
Command allow-listsPrefix-matched allowed_commands per state
Conditional transitionsGuards with programmatic predicates (eq, gt, exists, etc.) on context data
Approval gatesrequires_approval pauses for human review before high-risk transitions
Environment scopingblocked_env + env_overrides per state
Session isolationPer-session state via CLAUDE_SESSION_ID

Full guardrail reference in the docs.

Define your own workflows

{
  "id": "bugfix",
  "initial": "planning",
  "states": {
    "planning": {
      "allowed_tools": ["Read", "Grep", "Glob"],
      "max_iterations": 8,
      "on": { "READY": "implementing" }
    },
    "implementing": {
      "allowed_tools": ["Read", "Edit", "Write"],
      "max_edit_lines": 20,
      "max_files_per_state": 3,
      "on": { "DONE": "testing" }
    },
    "testing": {
      "allowed_tools": ["Read", "Bash"],
      "allowed_commands": ["pytest", "cargo test", "npm test"],
      "on": {
        "PASS": { "target": "completed", "guard": "tests_passed" },
        "FAIL_TEST": "implementing"
      }
    },
    "completed": { "type": "final" }
  },
  "guards": {
    "tests_passed": { "field": "test_result", "op": "eq", "value": "pass" }
  }
}

State machines aren’t DAGs — they loop and retry, which is what agentic work actually needs. Point your agent at the JSON schema and it generates a workflow via statewright_create_workflow. Tweak tools, commands, and environment blocks in the visual editor.

Supported agents

AgentIntegrationEnforcement
Claude CodeHooks + MCPHard (protocol layer)
CodexHooksHard (alpha)
opencodeTypeScript pluginHard (alpha)
PiSkills extensionHard (alpha)
CursorMCP + rulesAdvisory (alpha)

Hard = tool calls blocked at the protocol layer before the model sees them. Advisory = rules injected into context but not enforced.

Pricing

Free for individual developers. The managed cloud at statewright.ai handles workflow storage, run history, and the MCP gateway.

(these tiers are likely to be in flux: prices will not increase, tier grants can only increase)

PlanWorkflowsTransitions/moRun HistoryPrice
Free320072 hours$0
Pro1025007 days$29/mo
Team301000090 days$99/mo
EnterpriseUnlimitedUnlimitedto SpecificationContact us

Self-hosting

The engine (crates/engine) is Apache 2.0 and embeddable with no runtime dependencies. Single-developer and single-team self-hosting of the full stack is permitted under the FSL license.

use statewright_engine::{MachineDefinition, resolve_transition, validate_definition};

Tradeoffs

  • Requires MCP support in the agent (or hooks for non-MCP agents like Codex)
  • Workflow definitions are authored by hand, though agents can generate them via statewright_create_workflow
  • Cursor enforcement is advisory, not hard. MCP alone can’t gate tool calls in Cursor’s architecture
  • Research results are from a 5-task SWE-bench subset, not the full 2294-instance benchmark
  • If a workflow is too restrictive, the agent gets stuck. statewright_deactivate is the escape hatch

Docs

statewright.ai/docs — install guide, workflow authoring, schema reference, MCP tool reference, and agent-generated workflows.

Contributing

Workflow definitions, templates, and bug reports welcome. See Create Your Own for how to write workflows.

License

Apache 2.0 — portions FSL-1.1-ALv2 (converts to Apache 2.0 on May 3, 2029). Managed cloud at statewright.ai.

One hook to rule them all.

Similar Articles