Model or dataset
statewright/statewright avatar
statewright/statewright

Statewright: enforcing agent tool access with state machines

State machine guardrails for AI agents

491 stars21 forksRustNOASSERTION

At a glance

What is it?
Statewright wraps AI coding agents in a Rust state machine that limits which tools they can call in each phase. The idea is sound and the architecture is clean, but the research table is a five-task subset and the licence is not declared.
Who is it for?
Adopt Statewright if you already run Claude Code, Codex, Cursor, opencode or Pi and your failures look like wrong-tool calls rather than wrong reasoning. Do not adopt it if you need a declared open source licence or if your models run under 13GB of memory, since the README states that floor.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The failure mode Statewright is built around

The README opens with a claim worth taking literally: agents are suggestions, states are laws. The problem it names is not that models reason badly. It is that a model handed forty tools and an open-ended task will re-read the same file five times, call Edit during a review phase, or deploy before tests pass. The proposed fix is to shrink the problem rather than grow the model. A planning state sees read-only tools. Implementation unlocks edit tools with limited shell access. Testing permits designated test commands only. Call something outside the current phase and the call is rejected with a message listing what is available and how to move on. That rejection message is the whole product in miniature: the agent is not blocked silently, it is redirected. The intended user is an engineer already running an agent host (Claude Code, Codex, Cursor, opencode or Pi) who has watched a capable model waste turns on the wrong tool. It is not aimed at teams writing their own agent loop from scratch, and it is not a monitoring layer. The README is explicit that observability tells you what went wrong after the fact and does not prevent it.

Three layers, one of which has no dependencies at all

The repository splits into three parts. The engine in crates/engine is a pure Rust state machine evaluator: states, transitions, guards, tool restrictions, deterministic, with no LLM in the loop and no runtime dependencies. That last property is the most interesting design decision in the project. You can reason about, and test, the guard logic without a model, a network call or a plugin host anywhere near it. The second layer is crates/cli, which builds a binary called sw-agent. It is a direct-to-Ollama agent executor: it loads a workflow, runs the model in a constrained loop, enforces tool access and streams structured JSONL events. It can run a single state via --state and exit, leaving orchestration to the TUI or the MCP gateway. The third layer is the executor and plugin set: plugins/executor, crates/mcp-gateway and the per-host plugins. One executor owns the workflow session, credentials, delivery isolation, telemetry and host lifecycle; thin adapters translate each host's native tool hooks and model routing. The TUI in crates/tui builds a binary named statewright, a ratatui interface that spawns sw-agent as a subprocess and renders its JSONL stream live. The layering means the JSONL event stream is the contract between executor and interface, which is a cleaner seam than most agent tooling offers.

Per-state model routing and what each host can actually enforce

States carry a model field, and meta.default_model covers states without an override. The README's example routes diagnose to a fast model for reconnaissance, propose_fix to a stronger one for reasoning, and lets execute inherit the default. The interesting part is the admission that hosts differ in how strictly they can apply a route. Pi and OpenCode switch live. Claude Code and Cursor resume the same session after a route change. OMX applies the route at startup. The Codex app-server adapter routes each turn. That is a real limitation stated plainly rather than hidden: on some hosts, a model change is a session boundary, not a mid-turn swap, and the guardrail strength varies accordingly. Separately, sw-agent accepts a --config file with a model_routing block for per-state Ollama URL, temperature and context window overrides. So there are two routing mechanisms with different scopes, one for hosted models via workflow JSON and one for local Ollama via CLI config. If you mix hosted and local models in one workflow, expect to manage both.

Installing it, and the account it expects you to create

The quickstart is one command per host. For Codex: npx statewright-codex@latest init. For opencode: npx statewright-opencode@latest init. For Cursor: npx statewright-cursor@latest init. Claude Code uses its plugin marketplace instead: /plugin marketplace add statewright/statewright followed by /plugin install statewright. After the init command, the README states that your browser opens, you sign up at statewright.ai, generate a key, paste it, and you are done. That is a hosted dependency in the setup path, not an optional extra, and it is worth weighing before you run the command on a work machine. Once configured, a workflow starts either by asking the agent in natural language (start the bugfix workflow) or via the slash command /statewright start bugfix. The README's sample session shows the agent calling statewright_start, statewright_get_state, then statewright_transition with READY and later DONE, with the phase log moving planning to implementing to testing to completed. The statewright_run_agent MCP tool remains available for states where direct Ollama execution is preferred.

The research table is small, and the README says so

Statewright publishes results from a five-task SWE-bench subset, and the README flags that it is not the full 2294-instance benchmark. Two local models went from 2 of 10 attempts passing to 10 of 10 under the constraints, on the same tasks and hardware. The table lists gemma3 at 3.3GB failing both the 26-line bug fix and the subset; gemma4:e2b at 7.2GB passing the bug fix only with a specialized edit_line adaptation and failing the subset; gpt-oss:20b at 13.8GB and gemma4:31b at 19.9GB both passing; and llama3.3 at 42.5GB passing 2 of 2, added after the initial run. Five tasks is a small sample, and the README does not present it as more than that. The stated floor is around 13GB: below it, models identify bugs correctly but rewrite entire files instead of making surgical edits. The README calls that a model limitation rather than a Statewright one, which is a fair reading but also means the tool cannot help you under that threshold. If your local setup is a 7B model on a laptop, the guardrails will not rescue the edit quality.

Where the guardrails stop, and what to use instead

The Bash discernment guardrail blocks write-via-redirect such as echo > file, along with rm -rf, sed -i and scripting, even in states where Bash is allowed. That is a denylist of shell patterns, and denylists of shell syntax have a long history of being incomplete. The README does not claim otherwise, but it also does not describe how the patterns are matched or what happens with a shell construct that is not on the list. Treat this as a reduction in blast radius, not a sandbox. The more fundamental limit is that a state machine encodes a workflow you already understand. If your task is genuinely open-ended, or the right next step depends on information the workflow author did not anticipate, the transitions become the obstacle. The README argues that state machines loop and retry, unlike DAGs, which is the correct distinction for agentic work, but looping inside a wrong state graph is still wasted time. The obvious alternative approach is a permission or policy layer that evaluates each tool call against rules without a phase model, the way host-native allowlists and hooks work. That gives you per-call control and no workflow to design, but it cannot express that Edit should be legal in implementation and illegal in planning, because it has no notion of where you are. Statewright trades flexibility for phase awareness. If you do not want to design phases, it is the wrong tool.

Maintenance, releases and the licence question

The release cadence visible in the material is fast and split by host: codex-v0.3.2 and codex-v0.3.1 in September 2026, and claude-v0.3.1 two days earlier. Separate version streams per plugin mean a fix for one host does not imply parity on another, so pin your plugin version and read the matching release note. The 0.3.2 note describes managed resumes recovering narrowly recognized partial writes and stale rollout pointers through an explicit, backed-up repair path, with project-scoped App Servers and tenant homes isolated across restarts. That is a repair path for corrupted resume state, which tells you resume state can be corrupted in the first place. The upgrade cost is not just the plugin: workflows you have written are JSON with states, allowed_tools and model fields, and a schema change would touch every workflow file. The repository metadata reports the licence as NOASSERTION, meaning GitHub could not classify it from the repository contents. I cannot tell you what the terms are, and the README does not state them. For an internal tool that may not matter. For anything shipped or redistributed, resolve the licence before you build on it, and check the licences of the npm packages and plugin bundles separately from the repository, since those are what you actually install.

Editorial conclusion

Adopt Statewright if you already run Claude Code, Codex, Cursor, opencode or Pi and your failures look like wrong-tool calls rather than wrong reasoning. Do not adopt it if you need a declared open source licence or if your models run under 13GB of memory, since the README states that floor. Before installing, read docs/releases/codex-0.3.2.md and the workflow schema at docs.statewright.ai, and confirm the licence terms of the packages you are actually installing.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. statewright/statewright on GitHub
Community notes

Community notes