Talal Khawaja, home

Article · TypeScript

Human approval is an architecture decision, not a UX checkbox

Four agent builds, one lesson: an approval step only protects anything if the system is shaped around it. Where authority lives, what the model can touch, and what happens when someone says no.

Most AI demos that mention "human in the loop" mean a confirm button. The model decides, a modal appears, and someone clicks OK. That's a UX checkbox. It protects nothing if the model can reach the database without it, if "approve" is the only option, or if the system forgets who approved what.

Across four hackathon builds in 2026, the teams I worked with kept reaching the same conclusion from different directions: an approval step only works if the architecture puts it on the only path to the consequence. Here's what that looked like in each one, and the rules I now start from.

QuotePilot AI: the model can't set a price

QuotePilot AI is a quoting agent for service businesses. Qwen reads an incomplete request and returns schema-constrained analysis, which Zod validates. It never sets the number. Price and availability come from deterministic tools over a controlled catalogue, and a package the model recommends is checked against the requested service before it's used.

Approval there isn't a screen bolted on at the end. It's a stage the workflow can't pass without. Approving runs the (simulated) email and CRM steps. Rejecting leaves them untouched and records that nothing was sent. Missing information pauses the workflow for clarification before a quote exists at all.

The architectural choice: the commitment, meaning the price, lives in code the model can't write to. The approval gates the only path out of the building. (The full build is in Let the model reason, not promise.)

ScopeGuard AI: confirmation is locked until every question is answered

ScopeGuard AI turns scattered client instructions into a delivery scope. The model returns strict JSON Schema output that cites source IDs, and a second Zod pass rejects any citation that doesn't match a supplied source. The model is told to treat later requests as proposed changes, not approved commitments.

Then people take over. Every requirement gets approve, reject and edit controls plus a reviewer note, and every clarification question has to be resolved. Final confirmation stays locked while anything is pending, and any edit after confirmation sends the project back to draft.

The architectural choice: approval is per item and it's stateful. "Approved" is something the data model knows and can take back, not just a moment in the UI.

NeighborOps AI: policy lives in the tools

NeighborOps AI coordinates requests for a (fictional) community pantry. A Strands agent chooses between 15 narrow tools, such as classify_request, check_safety_threshold, reserve_inventory and request_human_approval. It has no general database or messaging tool, so its text alone can't reserve stock or change a status.

The interesting rule is the protected reserve. A ten-box request that would take food stock below the threshold of eight doesn't become an allocation. It becomes a human-review record. In the hosted run an operator reduced it to four boxes, and the reservation, volunteer match and task followed. Reservations are idempotent, using a conditional update and a unique allocation key, so a retried run can't double-reserve.

The architectural choice: the model decides which tool to call, but the tool decides whether the action is allowed. Escalation is an output of policy, not something the model chooses to do.

ThesisCircuit: nobody can talk their way past the risk governor

ThesisCircuit is the version with no human in the moment, which is why it's useful here. Three strategy agents emit typed theses, a critic looks for weaknesses, and a deterministic risk governor approves or vetoes. Agent consensus can create a proposal but can't authorise an order. A rejection becomes an audited NO TRADE. The system is paper trading only, and live configuration fails closed.

The human decision in ThesisCircuit happens earlier, in the design. People set the rules, the budgets and the session expiry, and the governor enforces them every cycle. It's the same principle with the approval moved to design time.

The architectural choice: persuasive output has no path to authority. Only a deterministic check does.

The rules I start from now

  1. Find the commitment first. What does the business have to stand behind: a price, a scope, a stock allocation, an order? That's where authority must not sit with the model.
  2. Put the commitment in code the model can't write to. Deterministic tools, validated inputs, narrow interfaces. No general-purpose "run SQL" or "send email" tool.
  3. Make approval the only path to the consequence. If there's any route around it, it's decoration.
  4. Make "no" a first-class outcome. Rejection, NO TRADE and needs-information should all be recorded states, with the reason. A system that can't record a refusal will eventually hide one.
  5. Make approval stateful and reversible. Per-item decisions, reviewer notes, and edits that invalidate a previous confirmation.
  6. Fail honestly. When the model or provider is down, say so. QuotePilot reports provider failures instead of inventing a result, and NeighborOps shows a generic retry state rather than claiming success.

None of this makes the model smarter. It makes the system's worst case a rejected draft instead of a wrong promise, and that's the trade I'd take for any client workflow.

These were team builds, and each case study credits the people who built it. For how this pattern carries into client work, see Teqprotech's AI agents with human approval service, or browse every project tagged AI agents. If you're scoping an agent of your own, the free human-approval architecture checklist turns these rules into checks you can run against a design.

Work like this runs through Teqprotech · AI Agents with Human Approval

The build

Projects in this post

  • Hackathon · 2026

    NeighborOps AI

    An operations dashboard for community pantries: a Strands agent handles routine coordination through narrow tools, and people decide how scarce resources are used.

  • Hackathon · 2026

    ThesisCircuit

    Paper-only options research agents: three strategies compete, a critic objects, and a fail-closed risk governor has the final say. NO TRADE is a first-class, audited result.

  • Hackathon · 2026

    QuotePilot AI

    An autopilot quoting agent for service businesses: Qwen reads the request, deterministic tools own price and availability, and a human approves before anything is sent.

  • Hackathon · 2026

    ScopeGuard AI

    Turns scattered client instructions (briefs, notes, emails, chats) into an evidence-backed scope that a person reviews and confirms before any work is committed.

More writing

Keep reading

  • Article

    Let the model reason, not promise: building QuotePilot AI

    QuotePilot AI splits flexible AI reasoning from business-critical commitments. Qwen structures the request, deterministic tools compute price and availability, and nothing reaches a customer without human approval.

  • Blog

    What LockSmith checks before a migration ships

    A migration can look harmless in a diff and still freeze production. Here's what LockSmith looks for, how it proves the lock in a real Postgres engine, and what it deliberately doesn't claim.