Josh Rosen made a blunt case on X on 3 November 2026 for anyone running AI agents: stop trusting the model to follow your process, and enforce that process in code. His post, “Agent State Machines: Building Deterministic Scaffolding for Agents,” is one practitioner’s argument rather than a study. It does map a pattern that more teams are building on their own.
An agent, in plain terms, is an AI that works in a loop. It reads an instruction, picks a tool, looks at what came back, and goes again until it decides the job is finished. Rosen’s complaint is that the model alone chooses what to do next and when to stop. If your rules live in the prompt, you are asking the model politely and hoping it complies on every single run.
A state machine is the old software answer. You list the stages a piece of work can be in, the events that move it from one stage to the next, and the conditions each move must meet. The model can ask for a move. Ordinary code decides whether the move is allowed. In Rosen’s example, a customer service agent drafts a reply and lands in a waiting-for-approval stage. Only a human sign-off sends it, and a rejection sends it back to drafting. The wording is the model’s job. Pressing send is not.
Rosen sorts the builds he has seen into four kinds. Some govern the agent’s own loop, as Stately Agent does with the XState library. Some run a fixed workflow of stages above the model calls: LangGraph, Mastra and n8n all work this way. Some supervise a crowd of agents from outside. OpenAI’s Symphony watches an issue tracker, hands tasks to Codex sessions and handles retries, while Pi Missions does similar work from inside the Pi coding harness. The fourth kind models the work itself. ThruWire tracks checkpoints that need supporting evidence before a task counts as accepted, which is a different thing from LangGraph’s checkpoints, which only save progress so an interrupted run can resume.
Why build your own when frameworks exist? Rosen gives three reasons. A small job, say five custom task states and one coding agent, may need only a few functions and a polling loop. Many teams already run Claude Code, Codex or Pi and would rather manage tasks around it than replace it. And companies often have databases, queues and schedulers that already track who owns what. He also names the cost. Teams that start small tend to add saved checkpoints, locking, scheduling, monitoring and crash recovery, and by then they have rebuilt the infrastructure they set out to avoid.
The code itself can stay modest. Rosen says state can sit in a JSON file or a database, with transitions written as functions that check an event before updating anything. One route he describes is an MCP server (Anthropic’s protocol for plugging tools into AI) offering tools such as claim_task and complete_task, so agents on different harnesses share one record of what is done. For runs that must survive a crash, he points to Temporal, Restate and DBOS.
The business logic underneath is simple. A prompt is a request and code is a rule. When an agent can email customers, spend money or mark its own homework as finished, that gap is the gap between a policy and a suggestion. Rosen offers no measurements of how often unconstrained agents break their instructions, so the evidence here is his experience of what teams are building, not a failure rate.
Before the next agent goes near customers or money, list the three actions you would never want taken without a person looking, then check whether code or only a prompt stands in the way.
Josh Rosen (on X), 3 November 2026.