the moment it clicked
so i've been building this thing at upwork called fusion studio. the idea is straightforward — take the frontend catalog of components and surfaces across the platform and let AI agents rebuild them. like a factory line but for UI.
at first we did the obvious thing. you prompt the AI, it generates a component, you review it, ship it. basically using AI as a fancy autocomplete. it worked okay for isolated pieces but fell apart the second you needed coordination across multiple steps. the AI had no memory of what it was doing or why. every prompt was a fresh start.
then something clicked. what if instead of using the AI as a tool we hand tasks to, we treat it more like a coworker that drives the workflow itself? the AI decides what to do next. it reads the catalog, writes the spec, builds the prototype, requests review. we just give it guardrails.
the chaos problem
the first version of "AI drives everything" was pure chaos. the agent would skip steps, jump straight from reading a catalog entry to trying to ship production code. sometimes it would loop forever between generating and reviewing its own work. it was like hiring someone extremely fast but with zero process discipline.
unconstrained AI agents are a problem. they're confident, they're fast, and they will absolutely do the wrong thing at full speed if you let them.
fsm as gps
the fix turned out to be something i learned about years ago and never thought i'd use in this context — finite state machines. the idea is dead simple. you define every valid state the workflow can be in, and you define which transitions are allowed. the AI can only move forward (or backward) along paths you've explicitly permitted.
type State = "catalog" | "spec" | "prototype" | "review" | "production"
const transitions: Record<State, State[]> = {
catalog: ["spec"],
spec: ["prototype"],
prototype: ["review"],
review: ["prototype", "production"], // can go back to fix
production: [],
}
function canTransition(from: State, to: State): boolean {
return transitions[from].includes(to)
}think of it like GPS for the AI. the agent still decides when to turn and how fast to drive. but the road network is fixed. you can't drive from catalog straight to production — that road doesn't exist. you have to go through spec, prototype, and review first.
the review state is interesting because it has two valid transitions. if the reviewer (another AI agent or a human) says the prototype isn't right, it goes back to prototype. if it passes, it moves to production. that's the only place where going backwards is allowed.
function transition(current: State, next: State): State {
if (!canTransition(current, next)) {
throw new Error(`invalid transition: ${current} → ${next}`)
}
return next
}
// this works
transition("review", "prototype") // send back for fixes
// this throws
transition("spec", "production") // nice trywhat this actually looks like in practice
each state has an AI agent (or sometimes a group of agents) responsible for it. the catalog agent reads the source application and identifies surfaces worth rebuilding. the spec agent takes that and writes a detailed specification. the prototype agent builds it. the review agent checks it against the spec and the original.
the FSM doesn't care what happens inside each state. the agents can use whatever tools they want, call whatever APIs, spawn sub-agents. the machine only cares about the edges — when an agent says "i'm done, move me to the next state" it checks if that transition is valid.
this is the inversion of control pattern. we're not telling the AI what to do step by step. we're letting it drive while constraining where it can go. it's the difference between giving someone turn-by-turn directions versus giving them a map with roads on it.
why this matters
the thing i keep coming back to is that AI agents are going to get better. faster, smarter, more capable. but "more capable" without structure just means "more capable of doing the wrong thing." the FSM pattern scales because it separates the what (agent intelligence) from the where (workflow structure). you can swap in a better model tomorrow and the guardrails still hold.
we're still iterating on this. some states probably need to be broken down further. but the core insight — treat AI as a coworker with a process, not a tool you poke — has changed how i think about building with these systems.