From Prompt to Work: Routing, Execution, and Workflows
For Ruflo, the decisive moment is not when a task receives an agent recommendation; it is when an assigned responsibility crosses into a provider call and returns evidence of what happened. This chapter follows that path from routing through execution and then into the workflow runtime. The distinction gives the reader a practical test: an agent can be registered, a workflow can be created, and a model can be selected without the requested work having been completed.
Routing chooses a path, not a result
Ruflo’s hooks and routers sit between a task description and an execution choice. A pre-task hook can inspect the wording, estimate complexity, suggest agent types, identify risks, and recommend a model or handler. The recommendation may favor a deterministic codemod for a mechanical transformation, a cheaper model for a simple task, or a more capable provider for a task whose description signals greater complexity. Static patterns can be combined with recorded outcomes, so a previous success may influence a later route.
A deterministic codemod is the clearest case. Converting a narrow syntax pattern, removing a known logging call, or applying another fully specified transformation does not require a model to invent a solution. If the router can identify that the operation is safe and complete as a codemod, it can avoid an LLM call altogether. That changes both cost and latency, but it also narrows what the handler is allowed to do. The codemod should be judged by whether the intended transformation occurred and whether tests still pass—not by the fact that it ran quickly.
Tasks that need interpretation follow a different path. Ruflo’s routing surface can return a suggested agent, a confidence value, a complexity estimate, and alternative agents. A semantic or learned route can be useful when the wording differs from earlier tasks; a keyword fallback can keep the system functional when a semantic backend is unavailable. These choices are not interchangeable. A route based on a static keyword is easier to explain but may be brittle. A similarity-based route can generalize across wording but depends on embeddings, thresholds, and the quality of the patterns it retrieves. A learned route can reflect project history while also inheriting mistakes from weak feedback.
The route therefore needs a visible reason. “Use the security reviewer” is a useful recommendation only if the system can say whether that choice came from task type, capability, a matching pattern, or a recorded outcome. Confidence is a selection signal, not a probability that the eventual work will be correct. The router may be right about the kind of worker needed and still be wrong about the scope, prompt, or acceptance test.
The agent registry is the next boundary. Registration creates a record with an identifier, type, status, capabilities, health, and counters. It allows the coordination layer to assign work and report lifecycle state. It does not itself call a model. Ruflo’s provider-backed execution path loads the record, refuses a missing or terminated agent, marks the agent busy, increments its task count, and then resolves the model and provider used for the call. Keeping these transitions separate prevents an idle registry entry from being presented as an active intelligence process.
Execution also depends on configuration outside the registry. The provider path can use Anthropic directly or an OpenAI-compatible Ollama or OpenRouter route, depending on the configured keys, provider choice, and model information. A logical label such as a model tier may be resolved to a concrete model identifier. A concrete model selection can be useful for cost or capability decisions, but it remains a request to a provider until the provider returns a response. Without a configured provider, the execution path returns a structured error rather than fabricating output.
A successful response carries more than text. The execution result can include the model that answered, a message identifier, a stop reason, output text, token usage, and duration. A transient failure can trigger a bounded fallback attempt when the routing path supplied a concrete model and the error is retryable. The fallback is still not a guarantee of completion; it is another provider call whose result needs to be recorded. The agent is returned to idle after the attempt, whether the attempt succeeded or failed, so status reflects availability rather than quality.
This sequence exposes several different meanings of “completed.” A hook can complete its recommendation. The registry can complete an assignment. The provider can complete an API request. A workflow can complete a step. The project can still reject the resulting artifact. Ruflo makes the earlier stages observable, but the final judgment remains outside the mere existence of a response.
The distinction is especially important when model routing is used to optimize cost. A cheaper model may be entirely appropriate for classifying a simple task and entirely inappropriate for making a high-consequence architectural decision. A fallback provider may keep a workflow moving during a transient outage while changing the output’s model, cost, or behavior. A deterministic handler may be safer than a model for a narrow edit but useless for a request that needs interpretation. The route should therefore be evaluated against the task contract, not against the abstract appeal of speed or intelligence.
Workflows preserve state, not guarantees
Ruflo’s workflow runtime adds value when a task has a sequence that should survive beyond one tool call. A workflow record contains steps, variables, status, a current position, timestamps, and any error state. Creating the workflow persists that definition. Executing it reads the record, injects runtime variables, marks the workflow running, and walks its steps while saving progress. A crash or pause can therefore leave a more useful trace than a conversation that ends halfway through a plan.
The runtime binds steps together in two ways. A workflow can carry named variables from its initial configuration, and a later prompt can interpolate a prior step’s output. A research step might produce a summary that becomes the input to a design step; a design response might then be passed into an implementation or review prompt. This is not just convenience. It makes the dependency explicit and gives the operator a place to inspect what the later step actually received.
A task step dispatches through the same provider-backed execution path described above. It needs an agent identifier either in its configuration or in the workflow’s variables. The runtime constructs the prompt, resolves substitutions, calls the executor, and stores the result in the step and in workflow variables. If the provider fails, the step is marked failed, the workflow records an error, and execution returns a structured failure result. The runtime does not turn a missing provider into a successful placeholder.
A wait step is deliberately simple: it pauses for a bounded interval and records what it waited. A condition step evaluates a restricted expression against workflow variables and can choose a subsequent step position. This limited vocabulary is useful precisely because its semantics are inspectable. A reader can ask what state is written before and after each step, which variables cross the boundary, and what happens when the condition or task fails.
The boundary becomes visible in the step types that are not implemented. The workflow schema includes parallel and loop, but the current executor marks those steps skipped with an explicit note rather than pretending that the parallel branches or repeated iterations ran. This is an important form of honesty. A workflow definition can express a richer plan than the runtime can execute. The presence of a step type in a schema or tool description does not establish that its operational semantics exist.
Resumption has a similar limit. Pausing a running workflow records its state and current step. Resuming changes the workflow back to a running state and reports the remaining steps, but the tool’s own result says those steps still need to be executed through task tools. Persistence makes continuation possible; it does not perform the continuation by itself. A saved pointer is not an execution receipt.
This distinction changes how a workflow should be designed. A useful workflow contains steps with explicit inputs, outputs, and acceptance conditions. It does not rely on a later step guessing what an earlier step meant. If a step can have a side effect, the workflow should say how to detect duplicate execution after a crash or timeout. If a failure can be retried, the retry policy should be explicit rather than inferred from the existence of a failed status. If a deferred step is essential, the workflow should stop or surface the omission rather than continue to a final “completed” label.
Consider a bounded feature review. The first task asks a provider-backed agent to summarize the relevant code and identify uncertainties. The next task uses that output to propose a change. A separate test step checks the proposal, and a final review step decides whether the artifact is acceptable. Ruflo can persist each step and the outputs that bind them. It can also report that a provider was unavailable, that an agent returned an error, or that a requested parallel stage was skipped. The workflow still needs a reviewer or acceptance test to decide whether the proposed change should be applied.
A workflow can also expose a subtle form of false continuity. Because step output is stored in variables, later work may continue smoothly even when the earlier result was wrong. A fluent chain is not the same as a reliable chain. The more a workflow carries forward, the more important it becomes to include source references, validation results, and explicit uncertainty in the data passed between steps. Otherwise persistence amplifies the first unchallenged assumption.
Provider configuration creates another operational trade-off. Direct Anthropic execution, OpenRouter, and Ollama-compatible paths have different credentials, endpoints, model identifiers, privacy implications, and failure behavior. A local provider may keep inference on a controlled machine; a remote provider may offer a model that is unavailable locally. Ruflo can normalize response shapes across paths, but normalization does not make their data boundaries or billing identical. The operator must know which path was actually used.
The same is true of retries and fallback. A retry can reduce the impact of a transient 429 or timeout, but it can also duplicate a side effect if the request was accepted and the response was lost. A fallback can improve availability while changing the model that produced the result. The execution result’s model, usage, and fallback history are therefore part of the evidence needed to interpret the output. “The workflow finished” is insufficient if the task contract required a particular provider, budget, or quality check.
A workflow also needs an explicit ownership rule at its edges. The runtime can persist a step result, but it cannot know whether the result is safe to publish, merge, deploy, or promote into shared memory. That decision belongs to the acceptance boundary defined by the task. For a code change, the boundary may be a test suite plus a human review. For a migration, it may include a backup, a reversible rollout, and a check that the target state matches the intended state. For a research task, it may require source comparison and a citation check. The workflow should carry these conditions as data rather than treating its final status as a substitute for them.
This is also where side effects deserve special caution. A persisted failure can mean that the provider rejected the request, that the task ran and returned an error, or that the response was lost after a side effect occurred. Repeating the step blindly can create a duplicate change. The current runtime records state and errors, but it does not supply a universal transaction or idempotency layer for every external action. Operators should therefore keep execution steps narrow, make side effects explicit, and require a separate acceptance check before allowing a later step to broaden the impact.
Ruflo’s workflow surface is consequently best understood as a persistence and dispatch mechanism with bounded control flow. It helps the system remember where it was, connect outputs to later prompts, and report failures without hiding them. It does not supply an unlimited workflow engine, independent quality judgment, or automatic permission to apply side effects. Once execution has produced a result, the next problem is how to store and retrieve the useful context without treating every response as a fact.