AI engineering · Problem-solution
How to make AI agent workflows reliable: executable patterns and stop conditions
An AI agent that improvises freely is not autonomous. It is unsupervised.
The reliability problem with AI agents is not that the model is wrong sometimes. It is that the model is confident even when wrong, and there is nothing in the loop that knows when to halt. The fix is structural: executable patterns the agent applies, and explicit stop conditions that bound where the agent can act on its own.
→ Read the deep guide on operational memoryWhat unreliable agent workflows actually look like
The unreliable agent is not the one that fails loudly. The unreliable agent is the one that succeeds plausibly. It produces a diff that compiles, passes the existing tests, and reads sensibly to a reviewer who has not been deep in the codebase that week. The fix it ships is the wrong fix — one you rejected last sprint, one that papers over a real bug, one that crosses a permission boundary nobody told it about.
Two failure modes account for most of the damage. The agent improvises past what it actually knows (no stop condition tells it to halt). The agent applies a generic best-practice answer to a project-specific problem (no executable pattern surfaces the project's actual rule).
Why "use a smarter model" does not fix reliability
Capability is not the bottleneck on bounded tasks
Most production agent tasks are not at the frontier of model capability. They are at the frontier of project-specific knowledge. A model two generations newer still does not know the convention you set last Tuesday, the fix you rejected last sprint, or the deploy step that requires owner approval.
Confidence scales with capability
A more capable model fails less, but when it does fail, it fails more confidently. The silent regression rate does not drop in proportion to capability — sometimes it goes up, because the diff is more plausible and harder to catch in review.
Reliability is verifiability
A reliable agent loop is not one that always succeeds — it is one whose failures are predictable and surface in time for the operator to act. An agent that halts on five named stop conditions is more reliable than an agent that succeeds 95% of the time and fails silently 5% of the time, because the 5% is no longer a surprise. Reliability is the operator's ability to predict when the loop will surface. Verifiability is reliability's measurable form.
The hidden cost of unbounded agent workflows
The visible cost of an unreliable workflow is the bugs that escape review. Trackable, eventually obvious, often blamed on the model.
The expensive cost is trust collapse. Once the operator catches the third confident-but-wrong diff, the agent loop is reviewed line-by-line for everything it produces. The productivity gain from running the agent at all begins to invert. The investment in the workflow stops paying.
Trust collapse is also recoverable, but slowly. Rebuilding trust in the agent loop after a few high-visibility silent failures takes longer than building it the first time. The stop conditions you add reactively cost twice — once to fix the failure mode, once to re-earn the operator's willingness to trust the loop. Adding stop conditions proactively, before the silent failure ships, is dramatically cheaper.
Real GNETICS scenario
Problem. We ran an autonomous agent against a backlog of bug-fix tickets. The agent was capable, the model was current, the tools worked. Pass rate on first review was around 60%.
What failed. The 40% that failed review were not catastrophic. They were plausible. The agent had picked a generic fix when the project had a specific rule. The agent had shipped a change that crossed a permission boundary because no rule said "stop here." Review became line-by-line on every diff. Throughput collapsed.
What changed. We attached executable patterns to the recurring failure modes: each rejected fix became a pattern with execution_stage, error_signature, expected_behavior, and a stop_condition. We added explicit ticket-level stop conditions: proof of delivery missing, tests not green, owner approval gate, risk-class change, permission boundary.
Measured operational effect. First-review pass rate rose sharply. The remaining failures clustered on the boundaries the agent now explicitly halted on — exactly the cases an operator should be reviewing. Review time per ticket dropped because the diff arrived with the rejected-patterns already filtered out and the stop-condition events surfaced.
The structural fix: executable patterns + stop conditions
Reliability is not a property of the model. It is a property of the loop. The two ingredients that make the loop reliable are executable patterns (what to do) and stop conditions (when not to act on your own).
An executable pattern carries the typed fields the agent acts on during execution. A stop_condition inside the pattern halts the agent when the pre-conditions are not met:
{
"execution_stage": "before_edit",
"tool_name": "edit_file",
"error_signature": "TimeoutError waiting for FTS5 rebuild",
"expected_behavior": "Warm the FTS index in a readiness probe before \
serving traffic; never block first request on rebuild.",
"stop_condition": "Tests not green OR readiness probe missing.",
"doc_reference": "/blog/claude-code-context-loss#stop-conditions",
"quick_fix": "Trigger a no-op INSERT/DELETE in a startup hook to warm \
the FTS index before serving traffic.",
"root_fix": "Replace FTS5 rebuild-on-attach with explicit \
SELECT * FROM patterns_fts LIMIT 1 in the readiness probe.",
"tags": ["fts5", "sqlite", "warmup", "readiness-probe"],
"status": "resolved"
}
Ticket-level stop conditions cover what a single pattern cannot. Five we use on autonomous tickets: proof of delivery missing (no verifiable artifact, no done), tests not green (no "almost passes" — surface it), owner approval gate (schema migrations, deletes, billing-adjacent changes), risk-class change (touching another service, broader permissions), permission boundary reached (read access here, no write; write here, no deploy).
The point is not to make the agent timid. It is to make the agent verifiable. An agent that halts on stop conditions can be trusted with longer tickets, because the operator knows the boundary cases where it will surface for review.
The most underrated benefit of explicit stop conditions is what they do to operator review. Without them, review is line-by-line, defensive, slow. With them, review concentrates on the diffs and the stop-condition events — the cases where the agent decided not to push through. Throughput rises because the operator is no longer the second-guesser on every safe diff; they are the decision-maker on the cases that explicitly asked for human input.
Wiring it to a real agent loop
Reliability gets wired the same way memory does — through tool use and bounded behaviour. Three pieces.
1. Attach stop conditions to every pattern
When the agent contributes a pattern, require a stop_condition field. A pattern without one cannot be retrieved.
2. Attach stop conditions to the ticket itself
Tickets carry their own halt rules: proof of delivery, tests, owner gates, risk class, permission boundaries. The agent reads them at start and respects them at every action.
3. Make halting first-class in the agent loop
Halting and surfacing is a positive outcome, not a failure. The agent reports the stop condition it hit and the state it left. The operator picks up from there.
Frequently asked questions
How do you make AI agent workflows reliable?
Two structural pieces: executable patterns (typed records the agent applies during execution) and explicit stop conditions (named halt rules on patterns and tickets). Reliability is a property of the loop, not of the model.
What is a stop condition for an AI agent?
An explicit, machine-detectable halt rule. Concrete examples: proof of delivery missing, tests not green, owner approval gate, risk-class change, permission boundary reached. The agent halts and surfaces the situation instead of pushing through.
Why is a smarter model not enough for reliability?
Project-specific knowledge — the convention you set last week, the fix you rejected last sprint — is not at the frontier of model capability. A more capable model fails less but fails more confidently. Reliability has to be wired into the loop, not assumed from the model.
Can I add stop conditions without rewriting my agent stack?
Yes. Stop conditions attach to two existing surfaces: the patterns the agent retrieves from memory, and the ticket the agent is working on. Both can be added incrementally without changing the model or the tool layer.
How is this different from just adding more tests?
Tests catch bad outcomes after the agent acts. Stop conditions halt the agent before it acts when the pre-conditions are not met. Both are useful — but stop conditions surface the situation in time for the operator to redirect, instead of after the diff has already shipped.
How many stop conditions is too many?
Five to seven ticket-level stop conditions covers the boundary cases for most autonomous workflows. Past that, you are likely encoding things that belong inside a pattern's stop_condition field instead. The rule of thumb: ticket-level conditions guard the perimeter; pattern-level conditions guard specific actions.
If your team spends more time rebuilding context than shipping, the bottleneck may not be the model — it may be the absence of operational memory.
GNETICS OPS was built around that single assumption.