Technical product management · System design · AI
Every time I have seen an autonomous AI system fail in production, the failure was not the AI making a wrong decision. It was because no human had a chance to catch the wrong decision before it became consequential. The model confidently misunderstood the user’s intent at step one, and by step nine, it had produced something expensive, wrong, and hard to undo.
When I built my agentic orchestration platform, I made a deliberate architectural commitment: every point where the system crosses a meaningful threshold — from ambiguous to understood, from planned to funded, from complete to published — requires an explicit human signal. Not a timeout. Not an implied default. A real approval, with real information, from a real person.
The false trade-off
The standard framing in agentic AI is that human oversight is the cost you pay for safety. You give up speed and autonomy in exchange for control. This framing is wrong, and building this system has made me more confident about that.
Approval gates, designed well, do not slow the system down in any meaningful way. The compute is fast — a thirteen-module build spec is decomposed and deep-dived in two to three minutes. The human decision that follows takes 30 seconds if the approval prompt is well-constructed.
The real cost of approval gates is not latency. It is design effort. Building a good approval gate means presenting exactly the right information in exactly the right format at exactly the right moment. That is hard product work. The temptation to skip it — to just run the system and let humans intervene if something goes wrong — is understandable but produces systems that users stop trusting, often after one bad experience.
Gate one: intake clarification
The first gate is the softest one and the most frequently skipped in production AI systems. When a user sends a request, the system does not immediately start working. The Master Agent researches the topic, identifies what it does not know, and generates a set of clarifying questions before committing to a plan.
I classified questions into two categories: mandatory and optional.
- Mandatory questions must be answered before the system can proceed — they represent genuine ambiguity where the wrong assumption would produce a fundamentally wrong output.
- Optional questions have sensible defaults, and the user is told what the default is and why. The user can reply “use defaults,” and the system proceeds without requiring input on every question.
This design is important for user trust. A system that asks twelve questions before starting anything feels like bureaucracy. A system that asks two critical questions, tells you it has assumed reasonable defaults for the other ten, and shows you what those defaults are — that feels intelligent. The maximum clarification rounds are capped at five. After five rounds, the system proceeds with whatever it has.
The intake gate has a second benefit that is not obvious at first: it forces the system to do research before it plans. The Master Agent’s first move is not to generate questions — it is to do background research on the topic, then generate questions informed by that research. This means the questions are better, the defaults are more defensible, and the subsequent decomposition is grounded in actual domain knowledge rather than generic assumptions.
Gate two: spec approval with cost and risk transparency
The second gate is the one that determines whether the system runs at all. After the Master Agent has clarified the request, selected a persona template, decomposed the task into modules, run a deep-dive on each complex module, and stitched together a holistic spec — it presents everything to the user in a single approval prompt.
The approval prompt contains five items:
- a human-readable narrative summary of what the system intends to do and why
- a cost estimate with a range (minimum to maximum) and a confidence level based on the complexity of the modules
- a recommended budget — the estimated cost multiplied by a 1.5x buffer, rounded to a friendly number
- a risk analysis: any modules that will perform destructive operations, make external network calls, or take irreversible actions are flagged explicitly with severity levels
- a time estimate based on the number of parallel waves and the average latency per wave
Three buttons:
- Approve and Start: sets the budget and moves the task to execution
- Request Changes: opens a modal for feedback, which gets fed back into the intake loop — the system re-plans with the feedback incorporated
- Reject: cancels cleanly
The risk analysis deserves elaboration. I built a heuristic scanner that reads the module specs and flags specific patterns: destructive keywords (delete, drop, purge, wipe), external call keywords (scrape, fetch from, send email, publish), irreversible keywords (deploy, merge to main, post to Twitter). These are imperfect — they are keyword matches, not semantic analysis — but they catch the overwhelming majority of dangerous cases and surface them before the user commits compute and money to a plan that might cause harm.
The approval prompt is also where the budget gets locked. From this point forward, the model router enforces the budget in three stages: at 70% spent, it downgrades all future calls to cheaper model tiers; at 90%, it moves to utility-tier-only; at 100%, it hard-stops and publishes a build-failed event on the bus. The user chose this number. The system respects it absolutely.
Gate three: budget alerts during execution
The third gate is asynchronous and non-blocking. A background watcher polls active tasks every thirty seconds and checks whether any budget threshold has been crossed since the last alert. When a task crosses 50%, 80%, 90%, or 100% of its budget, the user receives a Slack message with the current spend, the remaining balance, the burn rate in dollars per minute, and an estimated time to exhaustion.
This gate does not stop the system. It informs the human, who can then choose to intervene via the dashboard’s cancel button or let it run. The distinction matters: a hard stop at 50% would be paternalistic and annoying. A transparent alert at 50% respects the user’s original decision while giving them the information they need to reconsider if circumstances have changed.
One design subtlety: the watcher tracks the last threshold alerted per task and only fires once per threshold crossing. Without this, a task that hovers near 80% would spam the user every 30 seconds. The alert is meaningful precisely because it is rare — it fires once, at the moment of crossing, and then not again until the next threshold.
Gate four: content approval before publishing
The fourth gate covers content distribution. After the Build Master finishes the main deliverable, tasks that involve content creation — or any task where the user has requested it — trigger a Content Agent that generates platform-specific variations: a long-form blog post, a Twitter thread, a LinkedIn post, and a Substack newsletter.
All four are generated in parallel and presented in a single Slack prompt with previews. The user sees the first 600 characters of each variant, the word count, and the title or subject line. One approval covers all four. If the user requests changes, they describe what to fix in a modal, and all four variants are regenerated with the feedback applied — up to three revision rounds.
This gate exists for a simple reason: content that goes to a public platform under my name is irreversible in a way that internal deliverables are not. A wrong research report can be discarded quietly. A wrong LinkedIn post cannot. The approval gate is not bureaucracy — it is the correct response to the irreversibility of the action that follows.
What makes an approval gate work vs. fail
I have thought carefully about what distinguishes approval gates that users engage with meaningfully from ones they click through reflexively. Three factors determine it.
- Information quality
An approval prompt that says “the system is about to run — approve?” is useless. An approval prompt that says “the system will execute nine modules in three parallel waves, estimated cost $0.85 to $1.40 with medium confidence, recommended budget $1.30, one module will make external HTTP calls” — that is actionable. The user can make a real decision.
- The right level of friction
Approval gates should be easy to complete when the plan is right and appropriately difficult to bypass when it is not. The Request Changes path must be genuinely easy — if requesting changes takes more effort than just approving and fixing the output later, users will always approve, which defeats the purpose of the gate.
- Timing
An approval gate at the wrong point in the workflow is worse than no gate at all. Gate before spec approval is too early — you do not have enough information. Gate after execution is too late — the cost is already incurred. The art is identifying the exact point where the decision is both reversible enough to be meaningful and informed enough to be useful.
The takeaway
Human-in-the-loop is not a safety feature bolted on to an autonomous system. It is the mechanism by which an autonomous system earns the right to operate with increasing independence over time.
Every time a user approves a well-formed plan and gets back a well-formed output, their trust in the system increases. Every time the system surfaces a risk the user had not considered, that trust increases further.
The goal is not a system that never requires human input. The goal is a system where every moment of human input is meaningful, well-timed, and acted on faithfully.
