I recently watched a coding agent refuse to start an approved implementation.
The work plan contained this:
## WorkPlan Review
- **Status**: approved (2026-08-02)
The agent found the line and understood the word approved. Then it asked for approval again because the workflow expected a field named Implementation Approval.Status.
Nothing was missing in substance. The label was wrong.
The agent was following a repository-resident workflow I had designed to carry a change through requirements, design, review, planning, and implementation. I had spent months adding status fields, handoff contracts, review gates, retry rules, and escalation paths. Each addition addressed a failure I had actually seen. Together, they had made the workflow brittle enough to stop on a heading.
I had built the system around an old question: how do I stop the model from losing the path?
The model could now follow the path. My path had become the problem.
Two kinds of constraint
The approval incident exposed a distinction I had missed.
A boundary constraint reduces the solution space:
- Preserve the public API contract.
- Do not perform an irreversible external action without authority.
- Implement the confirmed requirements and keep recorded non-goals out of scope.
- Treat the task as complete only when the required behavior is observable.
A work-generating constraint creates obligations:
- Always produce three alternatives.
- Require unit, integration, and end-to-end tests for every feature.
- Require a mitigation task, owner, rollback plan, and approval record for every risk.
- Resolve every review finding before continuing.
- Stop when an optional field is absent or uses an unexpected label.
Both can look like safeguards. They behave very differently once the model is capable of carrying them out.
Boundary constraints tell the agent where it may operate. Work-generating constraints are read as requested work. A reliable agent will reliably create the extra artifacts, tests, abstractions, and stop conditions they imply.
That gave me the principle I now use when changing an agent workflow:
Be strict about boundaries and evidence. Be flexible about the path between them.
Why the problem surfaced now
The capability shift behind this is real, although public measurement often trails the models people are using.
METR's task-completion time horizon shows a strong historical increase in the difficulty of software tasks that agents can complete. METR also warns that the benchmark covers well-specified tasks, that capability remains jagged, and that new releases may go unmeasured for weeks or be skipped entirely. As of August 2, its public page was still dated May 8, and even its list of recent unmeasured models had not caught up with later releases.
Actual usage has moved toward longer execution as well. An analysis of roughly 400,000 coding-agent sessions found a recognizable division of labor: people made most planning decisions, while agents made most execution decisions. The authors describe it as people deciding what to build and the agent deciding how to build it.
Neither source proves how today's models behave in my workflow. The model families involved in the failures described here were released after the measurements and benchmarks I found. I did not find a public rerun on those releases.
That timing matters most for FixedBench. In May 2026, the researchers tested five then-current coding models on 200 issues where the code had already been fixed. The agents still made undesirable changes in 35% to 65% of cases. It is useful evidence that action bias existed in that generation. It is not a current failure rate.
The more interesting result is what happened when the researchers changed the instruction. Telling the agents to verify first and treat abstention as success reduced edits to already-correct code. On partially fixed code, the same instruction made them abstain when more work was still required. Prompt engineering traded action bias for passivity.
That is exactly the trap I had created in my own workflow. A model failed once, so I encoded the opposite behavior as a universal rule. When the model or task changed, the compensation remained.
The strongest evidence here comes from the failure history of this workflow on the current models I use. The studies explain why those failures are plausible and why simple prompt fixes decay. They do not substitute for observing the system itself.
How reliability started manufacturing work
The strict approval field was only the most visible failure.
In another run, the workflow stopped before implementation because it could not find external accounting evidence, document approval records, an exact release command, and detailed E2E environment assumptions. The repository, local services, and test tools were available. Most of the implementation could have proceeded. The workflow had converted useful planning context into mandatory readiness gates, then treated every missing gate as a user-owned decision.
The documents had expanded too. Product requirements and design docs started collecting stakeholder approval, live-service access, release procedures, dashboards, and operational evidence. A work plan for a data-export change included account setup and production concerns even though the requested outcome ended at implementation.
Review made the expansion worse. During that same planning flow, a reviewer requested a deterministic 20,000-row proof. The planner accepted the finding without asking what decision the proof would change or whether a cheaper boundary check would be enough. The reviewer then found that the proposed proof data contradicted an existing aggregation contract, which triggered another revision. Every step was technically defensible. The loop itself had no economic judgment.
I had made the reviewer authoritative and the author obedient. “Review until approved” had become “add work until the reviewer runs out of ideas.”
That is not convergence. It is a ratchet.
What I changed
I did not solve this by deleting every rule. I changed where the workflow is strict.
Decide the outcome before designing the solution
A user request is no longer accepted as an automatically valid implementation scope. Before design, the workflow records:
- the observable outcome;
- what is required now;
- what describes the current state, a desired future, or speculation;
- explicit non-goals;
- a rough view of implementation cost and structural impact.
The cost assessment stays rough because this is requirements work, not detailed estimation. Its job is to make a bad tradeoff visible while scope is still cheap to remove.
“No change” and “reuse what already exists” are valid conclusions, but neither is a default. The agent must inspect enough evidence to decide whether the outcome is already satisfied, partially satisfied, or still requires implementation. That avoids turning FixedBench's action bias into its mirror image.
This also changes what users need to communicate. A useful request contains the boundary of the current outcome, not just a list of desired features. “Extend the existing authentication path without changing the public response contract” is more valuable than a long list of implementation rules. It states both the result and the point at which design needs to be reconsidered.
Give the model decisions, not a predicted route
The old workflow described complete routes: run one agent, populate every field, run another agent, stop on any missing input, repeat until a serialized state appears.
I now try to give each phase four things:
- the purpose it owns;
- the evidence that can change its decision;
- the criteria for choosing the next action;
- the smallest result the next consumer needs.
“Run every test lane” predicts a route. “Use the narrowest test that observes the required boundary” provides a decision criterion. Exact schemas still matter where software parses the response. A human-readable work plan does not need to fail because two headings express the same approved state. I changed the approval check to accept semantically equivalent evidence instead of requiring one heading.
The main agent also owns lightweight resolution. It can interpret semantically equivalent states, resolve repository-local ambiguity, retry with new evidence, and continue unaffected work. User escalation is reserved for decisions that belong to the user: a changed product outcome, a new requirement, a major approved design change, unavailable authority, or an irreversible external action.
Let review findings be declined
The receiver of a review now has three choices:
- Apply a finding that contradicts an approved requirement, accepted design, repository rule, or observable correctness.
- Decline a finding that adds scope, reverses an exclusion, duplicates proof, requests optional hardening, or costs more than its observable effect justifies.
- Return for user decision when resolution changes the product outcome or a major approved decision.
A decline includes evidence and goes back to the reviewer. The reviewer may maintain the finding when that evidence still leaves the result incorrect or unverifiable. Repeating the same preference without new evidence does not block the workflow.
A useful review process preserves a basic engineering skill: deciding not to implement a technically reasonable suggestion.
The constraint I had to put back
Removing rules can be just as careless as adding them. I proved that during this rewrite.
The planning flow generated integration and E2E test skeletons so the first vertical slice could prove an acceptance criterion across a real boundary as early as possible.
After I simplified the handoff, the planner treated the generated test skeleton as an unrelated file and planned a new E2E test later in the project. The artifact still existed, so the workflow looked complete. Its reason for existing had disappeared.
I restored the skeleton's purpose in the planner: consume the exact generated file in the earliest task that can make its boundary executable. Shared infrastructure may come first only when no acceptance criterion can work without it, and only the infrastructure needed by that first slice belongs there.
This is a boundary constraint worth keeping. It connects a planned implementation to observable proof and prevents integration risk from being postponed until every component has been built. Removing it made the workflow smaller and less reliable.
What remains strict
Several controls still earn their cost:
- User approval for product requirements and major design decisions.
- Explicit authority and mechanical containment for irreversible actions.
- Exact schemas at genuinely machine-consumed boundaries.
- Plans for work with real dependencies.
- Early vertical proof of an accepted outcome.
- Observable verification before completion.
- Independent review where a separate perspective can catch false confidence.
For dangerous operations, sandboxes, restricted credentials, isolated filesystems, and network controls are stronger than long prompt instructions. They limit the blast radius even when judgment is imperfect. Repeated approval prompts are a weaker substitute: one implementation report describes high approval rates and declining attention, and responds by using automated judgment to reduce routine prompts.
The same division applies to the workflow as a whole. Enforce the durable boundary mechanically where possible. Let the model choose among reversible actions inside it. An account of an agent-first engineering environment uses a similar principle: treat the top-level instructions as a table of contents rather than an encyclopedia.
The four questions I now ask
I now use four questions when reviewing an existing rule:
- What changes if I remove it? Name the decision, irreversible boundary, downstream consumer, or observable failure it affects.
- Does it limit scope or create work? Keep durable boundaries. Require current evidence before generating artifacts, test lanes, approval records, retry loops, or operational tasks.
- Can the model choose from evidence? Replace exhaustive branches with a purpose and selection criteria when the choice is reversible.
- Does it work in a fresh session? Rerun a representative task from the beginning. Continuing the old conversation only proves that a human can steer around the failure.
The fresh-session test has to cover both sides. A small change should remain small, ordinary ambiguity should not return to the user, and optional review findings should not expand scope. Required tests, approvals, and quality checks must still run. Fewer rules are not evidence of a better workflow.
A workflow can become technical debt
The hardest lesson for me was that reliability work can itself become overengineering.
Every workflow rule depends on an assumption about model behavior. A rule added after yesterday's failure can become redundant when the model improves, or harmful when a different task needs the opposite judgment. Status fields and review gates add coupling just as surely as public interfaces and shared abstractions do.
Boundary constraints age better because they describe what must remain true: the approved outcome, the public contract, the authority available, and the evidence required for completion. The route between those boundaries can change with the model.
I no longer ask only whether a new rule would have prevented the last failure. I also ask what work it will create, what decision it will remove from the model, and whether it will still make sense after the failure mode disappears.
The job of an agent workflow is no longer to make a model capable of finishing the process. It is to help a capable model finish the right amount of work.
Top comments (1)
"Be strict about boundaries and evidence, flexible about the path" is the most portable line here — I'm going to steal it for how we review agent workflow changes.
The distinction between boundary and work-generating constraints explains a failure I kept mis-diagnosing: every scaffold I added to stop a weaker model wandering became requested work the moment the model got capable enough to execute it literally. The approval-field-label story is perfect because nothing was wrong in substance — the agent did exactly what a reliable executor should, and reliability was the problem.
Where this gets sharp is that boundary constraints are the ones you can safely make rigid (API contract, no irreversible external action, done-means-observable), while work-generating ones want to be hints, not gates. We've started literally tagging steps in our workflow specs as
boundaryvspath, and on each model upgrade we only re-audit the path ones. Have you found a good way to keep the path flexible without losing the audit trail that made you add those gates in the first place?