Removing myself from the development loop
How I built the confidence to let agents deliver work autonomously, where I still get involved, and why the workflow keeps changing.
We've all seen an agent assure us that a feature is done, only to open the browser and discover it isn't there.
The explanation sounds convincing. The tests pass. The summary lists everything it implemented. Then you try to use the thing.
That gap is where most of my work on agent coordination started. I wanted to avoid repeating issues, introducing new bugs, and trusting tests that didn't actually protect anything. Over months, that turned into a workflow that lets me select a batch of tickets or milestones and leave agents to work through them autonomously.
I haven't read a single line of code in months.
That's a statement about how my role has changed. I bring the intent, answer questions, and resolve tradeoffs. Agents help define what we're building through conversation, then write the requirements and record the decisions. When an agent reaches a decision that needs me, I get a notification and can answer from my phone. Implementation, verification, and delivery also belong to the agents.
The question I've been working on is: how do I remove myself from the development process with confidence?
Today, I use the full workflow in three projects: Navaris, a CRM with WhatsApp communication and proposal generation for small and medium travel agencies; Samu, a project tracker built around agents and strong QA, with a focus on understanding which features a project has; and Imagery, a Rust-based service similar to Cloudinary.
A ticket in these projects usually takes about an hour to reach production. That's an observation about my current work, not a delivery estimate for arbitrary features. Getting there took months of improving the system around the agents.
The biggest change was making confidence depend on evidence.
An agent saying “done” tells me what it believes. I need the workflow to establish what actually happened. Did the feature behave as expected? Did the data change correctly? Did we exercise the failure paths? Would a test catch the bug it claims to prevent?
For new guard tests, one of my rules is deliberately concrete: remove the line the test is supposed to protect, confirm the test fails, and restore it. If the test still passes, it hasn't demonstrated that protection. A green test suite can be reassuring while missing the exact failure we care about.
I also separate implementation from quality assurance (QA). The agent implementing the ticket owns delivery. A separate QA agent verifies the behavior with its own context and reports findings. The implementer fixes them and goes through verification again, with a limit on how many rounds can run before escalation.
Independent QA can still miss things. Confidence comes from combining it with automated checks, observable behavior, scope control, and the ability to recover from a bad change. Each covers something the others can miss.
This is also why “it rendered” isn't enough. If the ticket is about generating a proposal, seeing a page load doesn't establish that a user can generate the correct proposal. The evidence has to match the promise we're making.
Diagram source
flowchart TD
Human["I bring intent and priorities"] --> Define["Agents ask questions and define requirements with me"]
Define --> Requirements["Agents write requirements and record decisions"]
Requirements --> Work["Agent implements the ticket"]
Work --> QA["Independent QA and automated checks"]
QA -->|"In-scope failure"| Work
QA -->|"Verification passes"| Review["Review and delivery gates"]
Review -->|"All green"| Ship["Merge and deliver"]
Work -->|"Decision needed"| Escalate["Notification to my phone"]
QA -->|"Scope question or round limit"| Escalate
Escalate --> Decision["I decide; the decision is recorded"]
Decision --> WorkThe routine work stays inside the loop. Decisions that need my judgment come back to me.
Monitoring production is a critical part of this workflow. Verification before delivery gives me confidence to ship. Observing what happens afterward tells me whether that confidence holds up in real use.
Logs are one source of evidence. We can also build our own tools to inspect the outcomes customers are getting. A request can complete without an error while extracting the wrong information or leaving a customer frustrated. Those are failures I want the system to look for, too.
In Navaris, we've built a process that uses a highly capable model to analyze every conversation from the previous day. It checks whether data was extracted correctly, looks for opportunities to improve, detects potential bugs, and assesses customer sentiment. That gives us a way to examine how the product is working across actual conversations, beyond the scenarios we anticipated during development.
The model's findings still need investigation. A suspected bug is something to reproduce and verify; a suggested improvement may require a product decision. But this analysis gives us concrete places to look and work to feed back into the development process. Stepping away from implementation makes this feedback from production even more important.
For example, a customer reports a bug, but the behavior they're asking for conflicts with the documented design. What takes precedence?
The agent can investigate, explain the conflict, and present options. Resolving it may change a product commitment. That's a decision I want brought to me. Once I answer, the decision needs to live in the ticket or design document so the next agent doesn't have to rediscover it.
That boundary is what makes autonomy useful. I can pre-authorize routine actions such as branching, committing, opening a pull request, and merging when the agreed gates pass. My attention goes to the decisions the workflow cannot settle from the requirements and evidence it already has.
There is another kind of work I had to remove from my day: checking whether the agents were still working.
An agent can finish verification, announce that it will open the pull request next, and end its turn. A status indicator may still say it's in progress. Nothing is happening, and the next step exists only as a sentence.
My coordination layer supervises those transitions. It checks for new milestones, distinguishes a running agent from a stalled one, and prompts it to continue when appropriate. Those prompts preserve the verification requirements. Failed recovery attempts eventually escalate instead of continuing forever.
For parallel work, each group of agents needs its own working copy of the code. Several agents changing a shared working copy can interfere with one another. Tickets touching the same code may need to run sequentially even when plenty of agents are available. Coordination includes knowing which work can safely happen at the same time.
My workflow contains plenty of mechanics like these. I keep the delivery rules in one workflow document and use skills, reusable instructions for agents, for the commands and procedures that execute them. If a skill contradicts the workflow, the workflow wins and the skill needs fixing. That gives me one place to maintain the decisions about how work ships.
But I don't bring all of this machinery to every project.
When I'm starting from scratch, I prefer to talk with agents and have them ask me lots of questions until the idea is complete enough to build. That conversation is how we define the requirements: agents draw out the details, help me work through the decisions, and write them down. For a larger project, they produce product requirements documents and architectural decision records. For something smaller, I may ask them to start coding and keep a document of features and completed work.
The amount of structure follows the maturity of the project and the cost of getting things wrong.
| Project situation | How I work with agents |
|---|---|
| Exploring a new idea | Conversation and lots of questions to clarify what we want |
| A small project taking shape | Direct implementation, with features and completed work recorded |
| A larger project taking shape | Agents turn our conversations into product requirements and architectural decision records |
| Ongoing delivery in Navaris, Samu, and Imagery | The full coordination, verification, escalation, and delivery workflow |
| This site | Codex with Astra, without skills or an extra workflow |
This site is a useful example. It's being built by Codex with Astra, without skills or an extra workflow. For other projects, I've used smaller, tailored versions of the playbook to keep iteration fast. Depending on the project, some of these mechanisms, all of them, or additional ones may be needed.
Models and the tools that run them keep improving. I want to revisit my techniques, systems, and skills as often as possible. A workaround that solved a real problem months ago might now add friction without improving the result.
That means keeping the reason for a rule alongside the rule itself. What failed? What was this supposed to prevent? Can the current setup handle it reliably without the extra instruction? Those questions give me a way to simplify the workflow while checking whether the protection still holds.
The fact that I use the full playbook today doesn't mean I want to use every part of it forever. Maintaining the system includes removing machinery that has stopped earning its place.
For developers and technical leaders, this changes where engineering effort goes. Deciding how much autonomy a project can support, what evidence is sufficient, and which decisions need a person becomes a larger part of the job. Those responsibilities become more visible as implementation requires less direct attention.
That's the work I've been doing for months: building a process I can trust enough to step away from, and continually reconsidering what that trust requires.
If you want to build this kind of development process for your team, let's talk about where autonomy fits and how I or the team at Southern Code could help put the workflow in place. Reach me by email or on LinkedIn.