polyflow
Officialpolyflow
Агент уже может возобновить приостановленный запуск. Но он не может сказать вам, что разрешено делать возобновлённому запуску.
polyflow — это движок рабочих процессов для ИИ-агентов. Агент рассуждает о рабочем процессе, а не о следующем вызове инструмента; polyflow допускает этот рабочий процесс только в том случае, если он проходит проверку модели, затем выполняет его надёжно и выдаёт агенту по одному рабочему заданию за раз.
Он поставляется как MCP-сервер, поэтому любой агент, поддерживающий MCP — OpenWorker, Claude Code, Cursor — может использовать его без изменений в ядре агента.
Экспериментально, не проверено, не рецензировано. Проверка — это проверка согласованности, а не доказательство, и «исчерпывающе» всегда означает исчерпывающе по конечной области, объявленной контрактом. Каждый вывод — это зацепка, а не результат.
Цикл
tools → observe → reason → WORKFLOW ──▶ polyflow admits it (or refuses)
│
┌───────────────────┘
▼
one work order → the agent runs the tool, through its own
permission gates, with its own credentials
→ workflow_report
→ next work order … until terminalАгент никогда не решает, что будет дальше. Он рассуждает о том, как выполнить один заказ — а это именно то, в чём модель действительно хороша — и сообщает результат. Последовательность, повторы, таймеры, подавление дубликатов и терминальные условия принадлежат машине.
Related MCP server: nano-vm-mcp
Почему так, а не постоянное разрешение
Сегодня автоматизация без присмотра утверждается по глаголу: «разрешить slack_send в #cs», навсегда, для всего, что модель решит с ним сделать. Это потолок, когда план — это строка инструкций в прозе, перепланируемая при каждом запуске.
polyflow утверждает план. workflows/customer-brief/effect-invariants.mjs содержит предложения, с которыми пользователь действительно может согласиться:
{ name: 'no-post-without-prior-approval',
pred: (path) => path.emitted.every((e, i) =>
e.kind !== 'post_brief' || path.actionBefore('APPROVED', i)) }При запуске перечисляются все достижимые пути эмиссии по объявленной области контракта и проверяются. Рабочий процесс, который не проходит проверку, не регистрируется — не помечается, а становится невыполнимым:
[polyflow] admitted: customer-brief — paths explored: 5 · states seen: 10 · exhaustive within declared domains
[polyflow] REFUSED: unsafe-brief
[polyflow] no-post-without-prior-approvaltest/fixtures/unsafe-brief — это намеренно сломанный двойник: он публикует сообщение при входе в ревью, до того как человек ответит. Он по-прежнему вызывает ask_user, по-прежнему нацелен на тот же канал, по-прежнему удовлетворяет постоянному разрешению. Рецензент, читающий diff, легко может это пропустить. Шлюз — нет.
Быстрый старт
npm install # pulls polygraph (polyrun) as a dependency
npm test # 14 tests, no API key, deterministic
node bin/polyflow-mcp.mjs # MCP stdio serverЗапуск вместе с OpenWorker
Предварительные требования: Node 22+ (polyflow использует node:sqlite) и установленный OpenWorker. polyflow не требует собственного API-ключа — он никогда не вызывает модель.
1. Зарегистрируйте его. Из каталога polyflow:
node bin/polyflow-install.mjs --agent openworker/cowork --workspace acme
# --print shows the entry and the target path without writing anythingЭто добавляет запись polyflow в глобальный файл mcpServers OpenWorker — тот же, который редактирует страница Connectors (%APPDATA%\coworker\mcp.json на Windows, ~/.config/coworker/mcp.json в остальных случаях, $COWORKER_STATE_DIR переопределяет оба). Он объединяет, а не заменяет, и отказывается трогать файл, который не может разобрать.
2. Перезапустите OpenWorker. Нет демона polyflow, который нужно запускать или контролировать: OpenWorker запускает bin/polyflow-mcp.mjs через stdio при открытии сессии и завершает его вместе с сессией. Состояние выполнения хранится в SQLite-файле по пути POLYFLOW_DB, поэтому оно переживает и то, и другое.
3. Проверьте, что он поднялся. Шесть инструментов появляются как mcp__polyflow__*. Попросите агента «перечислить рабочие процессы, которые вы можете запускать» — он должен вернуть customer-brief, его admitted: true и пять гарантий, под которыми он был допущен. Если этого не произошло, на странице Connectors будет постоянная ошибка, а строки запуска самого сервера (admitted: / REFUSED:) уходят в stderr.
4. Используйте его. Ничего особенного: дайте агенту задачу, покрываемую рабочим процессом, и он сам подхватит этот рабочий процесс — именно это измеряется в FINDINGS-phase3.md. Чтобы поставить на него повторяющуюся задачу, создайте обычную автоматизацию OpenWorker, инструкции которой описывают задачу; рабочий процесс повторно прикрепляется по производному ключу при каждом срабатывании, а не начинается заново.
Области. --agent — это область класса агента (какая библиотека рабочих процессов доступна этому виду агента), а --workspace — область экземпляра (чьи это запуски). Одна установка polyflow может обслуживать несколько рабочих областей — зарегистрируйте её один раз для каждой рабочей области с другим --workspace, указывая на тот же POLYFLOW_DB для общего хранилища или на разные файлы, чтобы держать их раздельно.
Добавление собственного рабочего процесса. Скопируйте workflows/customer-brief/ и отредактируйте шесть файлов (см. Рабочий процесс ниже). Перезапустите сервер: рабочий процесс, не прошедший проверку эмиссии, отклоняется при запуске и не может быть запущен вообще, так что плохое редактирование проявляется громко, а не в 3 часа ночи.
Разрешения. Установленная запись намеренно задаёт requires_approval: false — инструменты polyflow не достигают ничего за пределами машины, а реальные побочные эффекты запуска — это СОБСТВЕННЫЕ инструменты агента, у которых есть свои шлюзы. Запрос подтверждения на каждый workflow_report поставил бы диалог между агентом и его собственной бухгалтерией. Запись также объявляет tool_risk для инструментов только для чтения, что учитывается при применённом патче upstream/0001-mcp-per-tool-risk-level.patch и безвредно игнорируется без него.
Откуда берётся polyrun. polyflow встраивает polyrun в процесс, разрешая его из node_modules/polygraph, затем из соседнего checkout; POLYFLOW_POLYRUN переопределяет оба.
Другие хосты агентов
polyflow — это обычный MCP-сервер stdio, поэтому всё, что говорит на MCP, может его использовать. Установщик записывает правильный файл для каждого хоста:
node bin/polyflow-install.mjs --host kiro # ~/.kiro/settings/mcp.json
node bin/polyflow-install.mjs --host kiro --scope workspace # ./.kiro/settings/mcp.json
node bin/polyflow-install.mjs --host claude-code # ./.mcp.json
node bin/polyflow-install.mjs --host generic # prints the entry, writes nothingДва хоста имеют другую форму и выводятся, а не записываются:
node bin/polyflow-install.mjs --host nemo # YAML for a NeMo Agent Toolkit workflow
node bin/polyflow-install.mjs --host registry # AWS CLI call to publish an Agent Registry recordKiro / Kiro Crew читает
mcpServersиз~/.kiro/settings/mcp.json(пользователь) или.kiro/settings/mcp.json(рабочая область, которая выигрывает при конфликте имён). Повторяющиеся автоматические задания Kiro Crew имеют ту же форму, что и запланированные задания OpenWorker, — это тот случай, о котором говорят результаты вFINDINGS-phase3.md.NVIDIA NeMo Agent Toolkit подключается через свою группу функций
mcp_client(требуетсяnvidia-nat-mcp). Выведенный блок объявляет группу и добавляет её вtool_namesрабочего процесса. NeMo также может работать как MCP-сервер, поэтому рабочий процесс NeMo может быть одним из инструментов, которые называет рабочее задание polyflow.AWS Agent Registry — это каталог, а не среда выполнения: публикация записи позволяет другим людям и агентам в организации обнаружить polyflow. Записи можно синхронизировать с HTTPS-эндпоинта, который stdio-сервер не может предложить, поэтому выведенная команда создаёт ручную запись MCP.
Только путь OpenWorker был проверен end-to-end (см. FINDINGS-phase2.md). Остальные построены на основе документированных форматов конфигурации каждого хоста и не запускались.
Переменные окружения, какой бы хост вы ни использовали:
env | значение | по умолчанию |
| каталог библиотеки рабочих процессов |
|
| путь к sqlite |
|
| область класса агента |
|
| область экземпляра (рабочая область) | имя базового каталога cwd |
| checkout polygraph |
|
Инструменты
инструмент | что делает |
| что этот агент умеет делать и гарантии, под которыми каждый был допущен |
| запуск или повторное присоединение — идентичность запуска выводится из проверенных входных данных, поэтому ночная задача возобновляется, а не перезапускается, и агент не может переименованием получить второй запуск |
| сообщить о результате инструмента, получить следующий заказ |
| состояние + открытые заказы, ничего не меняет |
| внеполосное событие; действие, которое не применимо, — это наблюдаемый отказ |
| каждый шаг, принятый или отклонённый, с причиной — также допустимый корпус трасс Polygraph |
Области
Два уровня, и им не нужны новые поля в OpenWorker:
область агента — одна на класс агента (
openworker/cowork). Владеет библиотекой рабочих процессов: что умеет этот вид агента. СоответствуетScheduledTask.agent.область экземпляра — одна на запущенную копию (
workspace). Владеет живыми запусками и их журналами. Соответствуетworkspace, который уже являетсяcoworker.memory.Scope.WORKSPACE.
Идентификатор экземпляра выводится из agent | instance | workflow | key, поэтому запуск и присоединение — это один вызов.
Рабочий процесс
Шесть файлов в каталоге:
polyflow.workflow.json name, area, tools{effect kind -> agent tool},
key{template,fields} — the run's identity, derived
contract.json states, actions, finite data domain
machine.cjs SAM v2 strict-profile module
effects.cjs pure mapper: transition -> work orders
effects.manifest.json completion actions + retry policy per kind
effect-invariants.mjs what may be EMITTED, on every reachable pathИнверсия, которая делает это рабочим для агентов: в polyrun среда выполнения выполняет эффекты. У polyflow нет учётных данных, коннекторов и механизма разрешений — у агента есть все три. Поэтому эффект — это рабочее задание, возвращаемое обратно. Обработчик паркуется; агент забирает заказ, запускает инструмент под своими собственными шлюзами и сообщает. Только после этого действие завершения диспетчеризуется.
Долговечность вытекает из механизма аренды. Карта ожидающих находится в памяти, поэтому сбой теряет обещание, аренда истекает, эффект повторно забирается, и заказ предлагается снова — тот же идентификатор намерения, как минимум один раз, поглощается машиной.
Что доказывают тесты
✔ the admission gate certifies the demo workflow exhaustively
✔ workflow_list reports the guarantees the run was admitted under
✔ happy path: one order at a time, ending posted
✔ the run key is derived from input, not chosen by the caller
✔ an invalid key field is refused with an instruction, not honoured
✔ a finished run says so, and says not to start another
✔ start is idempotent: re-attaching returns the run in progress
✔ a denial is a result, not a fault — and no post is ever ordered
✔ zero tickets ends the run rather than posting an empty brief
✔ a duplicate report is refused, not double-executed
✔ an out-of-band action that does not apply is an observable reject
✔ a workflow that can post before approval is REFUSED and cannot be started
✔ a run outlives the process: restart re-offers the open work order
✔ initialize, tools/list, tools/call over stdioТест перезапуска — тот, который важен: сессия 1 доводит запуск до шага утверждения и умирает; сессия 2 — это другой процесс без разговора, без транскрипта и без воспроизведения — потому что состояние никогда не было в сообщениях с самого начала. Он подхватывает запуск ровно там, где тот был, и ровно одна публикация происходит в обеих сессиях.
Ещё не построено
Продвижение. Рабочие процессы здесь создаются вручную. План состоит в том, чтобы извлекать повторяющиеся формы запусков из журналов и предлагать машину для проверки — индукция из истории, а не предвидение. Создание машины для каждой задачи стоит больше, чем вызовы инструментов, которые она заменяет, если только она не переиспользуется.
Версионирование. polyvers ограничивает изменённый рабочий процесс относительно выполняющихся запусков; не подключено.
Аудит. Журнал уже является корпусом трасс;
polyrun auditпо нему не подключён.Швы OpenWorker, требующие изменений ядра: маршрутизация приостановленного заказа во Входящие и
workflow_refнаScheduledTask. См.FINDINGS-phase0.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Durable background job execution, async task scheduling, and state persistence for AI agents.
Durable agent-to-agent handoffs and shared scratchpad for multi-agent workflows.
Hosted runtime for persistent agent teams, durable workflows, memory, schedules, and goals.
Reliable async execution for agent tool calls: schema gating, retries, idempotency, audit trail.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables AI coding agents to execute formal, stateful workflows with typed contracts, postcondition enforcement, and structured retry logic.1-
- AlicenseAqualityBmaintenanceGoverned agent execution gateway for LLM workflows, providing deterministic FSM-based execution, audit trails, and idempotency guarantees via MCP.5MIT
- FlicenseNot gradedqualityDmaintenanceLease governed AI agent instances without hand-built runner queues.-
- AlicenseNot gradedqualityCmaintenanceProvides durable queues, human-in-the-loop approval gates, and an audit trail for AI agent fleets, enabling blocking approval requests and reliable work handoffs.2 npmMIT