statewright
- title
- statewright
- type
- toolbox
- summary
- Конечный автомат на Rust, ограничивающий доступные ИИ-агенту инструменты на каждом этапе работы
- tags
- rust, ai-agents, guardrails, mcp, claude-code, watchlist
- language
- Rust
- license
- Apache-2.0 / FSL-1.1-ALv2
- created
- 2026-05-13
- updated
- 2026-07-29
- lang
- ru
- translation_of
- statewright
- source_updated
- 2026-07-29
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Statewright - это движок конечного автомата на Rust для ИИ-агентов написания кода, который определяет, какие инструменты доступны на каждом этапе. Агент объявляет рабочий процесс (например, planning -> implementing -> testing -> completed), а движок принудительно соблюдает его для каждого состояния. Инструменты, не входящие в allowed_tools текущего состояния, модель просто не видит. Слоган проекта: "Agents are suggestions, states are laws".
Идея
Большинство сбоев в работе агентов принято списывать на качество модели и пытаться лечить более крупными моделями или раздутыми промптами. Statewright исходит из того, что проблема кроется в пространстве вариантов: когда у модели больше 40 инструментов и открытая задача, она тратит токены на бесцельные метания вместо рассуждений. Сужение набора доступных инструментов под конкретную фазу - простое и дешёвое решение.
Таблица с результатами экспериментов в README наглядно показывает эффект на локальных моделях: на выборке из 5 задач SWE-bench модели gpt-oss:20b (13.8 GB) и gemma4:31b (19.9 GB) подняли результат с 2/10 до 10/10 исключительно за счёт ограничений statewright - на том же железе и тех же задачах. Модели размером меньше 13 GB способны вызывать инструменты, но не могут удержать в контексте достаточно кода для точных правок, так что нижняя планка задаётся самой моделью, а не обвязкой. Флагманские модели с таким подходом тратят меньше токенов до успешного завершения задачи.
Как это устроено
Движок представляет собой крейт на Rust (crates/engine, лицензия Apache-2.0, встраиваемый, без зависимостей во время выполнения), который разбирает JSON-описания конечных автоматов: состояния, переходы, проверки условий (guards) и ограничения на вызовы инструментов. Никаких LLM внутри самого движка нет - все решения строго детерминированы.
Поверх движка работает слой плагинов, связывающий его с агентом через MCP. Statewright регистрирует набор MCP-инструментов (statewright_start, statewright_get_state, statewright_transition, statewright_create_workflow, statewright_deactivate), а хуки на каждый вызов инструмента отсекают всё, что не входит в allowed_tools текущего состояния. В итоге модель в принципе не видит лишних инструментов.
Ограничения для каждого состояния
| Механизм | Действие |
|---|---|
allowed_tools |
Скрывает от агента все инструменты, не указанные в списке |
| Разбор команд Bash | Блокирует перенаправления >>, деструктивные команды (rm, shred) и запуск скриптовых интерпретаторов вне состояний записи |
max_edit_lines |
Отклоняет diff'ы, превышающие лимит |
max_files_per_state |
Ограничивает количество редактируемых файлов в рамках одного состояния |
allowed_commands |
Разрешающий список shell-команд с сопоставлением по префиксу |
| Условные переходы | Предикаты (eq, gt, exists) поверх контекстных данных |
requires_approval |
Остановка процесса для ручной проверки человеком перед переходом |
blocked_env / env_overrides |
Изоляция переменных окружения под конкретные состояния |
CLAUDE_SESSION_ID |
Раздельное состояние для каждой сессии, поддержка параллельных рабочих процессов |
Конечный автомат - это не DAG: состояния могут зацикливаться и повторяться (например, testing -> implementing при падении тестов), что полностью соответствует реальной итеративной работе агента.
Пример рабочего процесса
{
"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" }
}
}
Поддерживаемые агенты
| Агент | Интеграция | Тип контроля |
|---|---|---|
| Claude Code | Хуки + MCP | Жёсткий (на уровне протокола) |
| Codex | Хуки | Жёсткий (alpha) |
| opencode | Плагин на TypeScript | Жёсткий (alpha) |
| Pi | Расширение skills | Жёсткий (alpha) |
| Cursor | MCP + правила | Рекомендательный (alpha) |
Жёсткий контроль означает, что вызовы блокируются на уровне протокола до того, как модель о них узнает. Рекомендательный контроль сводится к передаче правил в контекст, но модель всё равно может попытаться их нарушить. В случае с Cursor это архитектурное ограничение: один только MCP не позволяет заблокировать встроенные инструменты Cursor'а.
Место в общей картине
Statewright предлагает структурное решение сразу для нескольких частых проблем:
- sandboxing-ai-agents - изоляция файловой системы, сети, HTTP и системных вызовов определяет, к чему агент имеет доступ. Statewright добавляет пятое измерение: какие инструменты агент может вызывать на каждом конкретном этапе. Политики HTTP в духе Crabtrap и управление инструментами через statewright работают как взаимодополняющие уровни защиты.
- skill-atrophy-supervision-paradox - предварительное ограничение агента превращает рабочий процесс аудит-обсуждение-исполнение по Коэну из требования к личной дисциплине человека в формальную, машинно-проверяемую спецификацию.
- acceptance-criteria-ids / specsmaxxing - подходы "спецификации как идентификаторы, на которые ссылается агент" и "конечные автоматы как идентификаторы состояний, по которым агент переходит" дополняют друг друга, выстраивая понятную и управляемую структуру вокруг модели.
Механизм анализа команд bash (блокировка >> и деструктивных операций вне фаз записи) повторяет логику hazmat, который решает ту же задачу на уровне ОС через Seatbelt + pf, но statewright перехватывает вызовы ещё раньше - до того, как они уйдут исполнителю.
Стоимость
Бесплатный тариф: 3 рабочих процесса, 200 переходов в месяц. Pro ($29), Team ($99). Сам движок распространяется под лицензией Apache-2.0 и доступен для самостоятельного развёртывания. Self-hosted использование полного стека одним разработчиком или одной командой разрешено по лицензии FSL-1.1-ALv2 (автоматически переходит в Apache-2.0 с 2029-05-03).
Ограничения
- Для жёсткого контроля требуется MCP; Codex и opencode вместо этого используют хуки (в статусе alpha).
- Поддержка Cursor работает только на уровне рекомендаций: через MCP нельзя ограничить встроенные инструменты редактора.
- Описания процессов приходится писать вручную в JSON. Инструмент
statewright_create_workflowв MCP позволяет агенту создавать их самостоятельно, но исходную схему всё равно нужно передавать в контекст. - Слишком жёстко настроенный процесс может загнать агента в тупик; для ручного сброса предусмотрена команда
statewright_deactivate. - Практическая проверка ограничена подвыборкой из 5 задач SWE-bench, а не полным набором из 2294 тестов.
Быстрый старт (Claude Code, бесплатный тариф)
/plugin marketplace add statewright/statewright
/plugin install statewright
/reload-plugins
После этого достаточно сказать start the bugfix workflow или вызвать /statewright start bugfix. При первом запуске потребуется ввести API-ключ с сайта statewright.ai. (В README отмечается, что Claude может с осторожностью относиться ко вставке API-ключей - подтвердите действие, если появится запрос.)
Репозиторий: https://github.com/statewright/statewright (Apache-2.0 / FSL, 88 звёзд, свежий проект). Добавлен в watchlist как молодой проект от единственного поставщика.