AI coding agents are now fast enough that your attention, not their output, is the bottleneck. The trick is adding human-in-the-loop checkpoints that catch.
AI coding agents are now fast enough that your attention, not their output, is the bottleneck. The trick is adding human-in-the-loop checkpoints that catch drift and bad decisions without turning every step into a ticket.
This tutorial walks through concrete patterns to add review gates to an orchestrated multi-agent workflow, using Maxxwell where it’s helpful and staying generic where it’s not.
Before wiring in human checkpoints, you should have:
If you’re still at "one agent in one terminal", start with the pillar guide on AI coding agent orchestration, then come back once you feel the coordination cost.
You cannot review everything at the same depth, or you become the throughput limit. You need a small set of explicit decision points where humans own the call.
From current industry guidance (OpenAI guardrails, NIST, OWASP, GitHub):
Write these down as rules your agents can follow. Example, in a AGENT_GUARDRAILS.md at repo root:
# Agent guardrails
1. Shell commands that mutate state (rm, mv, chmod, package installs): REQUIRE HUMAN APPROVAL.
2. Changes to auth, RBAC, or data access layers: REQUIRE HUMAN ARCHITECTURE REVIEW.
3. New external integrations (APIs, queues, SaaS): REQUIRE HUMAN DESIGN DOC.
4. No changes land on `main` without a human merging the PR.
These become the basis for your checkpoints. Agents don’t have to understand risk; they only have to respect these rules.
Human-in-the-loop breaks down when every agent asks you separately. You need one place where decisions get surfaced and made.
Pattern:
In Maxxwell, the orchestrator is:
Example orchestrator brief:
You are the orchestrator for multiple coding-agent workers.
Your job:
- Keep a list of active sessions and their goals.
- When a worker blocks on a decision, draft a message asking the human to choose.
- When work completes, summarize what changed and whether it obeyed guardrails.
Guardrails:
- Do NOT run shell commands yourself.
- Do NOT approve architecture changes.
- For high-risk actions, pause and ask the human to decide.
This gives you a single conversational surface where the decisions the orchestrator surfaces get made.
Code review is already the human decision layer in most teams. The goal is to move trivial review earlier, keep the merge button human, and stop agents from spamming you with tiny questions.
DORA’s data says:
Use agents to handle the trivial parts, and reserve human checkpoints for:
Pattern:
Concrete example prompt for the worker:
You have implemented the requested change.
Before opening a PR:
1. Run the test suite.
2. Analyze the git diff.
3. List:
- Potential bugs.
- Missing tests.
- Security, performance, or reliability concerns.
4. Suggest fixes and apply them.
Do NOT push directly to main.
This mirrors GitHub Copilot’s finding that self-review can remove roughly a third of trivial back-and-forth.
Pattern:
Example orchestrator instruction:
When a worker opens a PR:
1. Run unit tests.
2. Run static analysis.
3. Perform an AI code review focusing on:
- Logic correctness
- Security issues
- Performance concerns
4. Produce a summary:
- Files changed
- Key behaviors affected
- Review findings
- Explicit recommendation: "ready for human merge" or "needs human deep review".
Do NOT merge the PR; the human owns the merge decision.
You still press the merge button, as GitHub’s guidance makes explicit. The agents make your decision cheaper by front-loading information.
Architectural decisions are where "confidently wrong" does the most damage. You need a lightweight checkpoint that forces a design doc and a human approval before agents run off and implement the wrong thing for hours.
Pattern:
Instruction to the orchestrator:
When a new feature request involves:
- Multiple services
- Data model changes
- External integrations
Do NOT start implementation workers.
Instead:
1. Start a "design-doc" worker.
2. Have it draft a design document with:
- Problem statement
- Constraints and assumptions
- Proposed architecture
- Interfaces and data contracts
- Risks and open questions
3. Return the design doc to the human for approval.
You read one design doc instead of debugging five misaligned branches later.
Make the gate explicit in your tooling. Examples:
needs-arch-approval vs arch-approved.arch-approved label".In Maxxwell, you keep the gate with fleet controls:
You are approved to implement according to v2 design; start work on service A and B as planned.That preserves the human as the one who actually greenlights the architecture.
OWASP and NIST both stress that AI-generated code changes the threat model. You need safety checkpoints that catch obvious problems early without requiring a full manual security review on every diff.
DORA’s data shows that:
So you get more throughput and more instability unless you add safety rails.
Pattern:
Example orchestrator prompt:
After a worker completes its task and opens a PR:
1. Run:
- Static analysis (e.g. semgrep, eslint, bandit).
- Secret scanning (e.g. trufflehog, git-secrets).
- Dependency checks (e.g. osv-scanner).
2. Summarize:
- Any new high-severity findings.
- Any changes in dependency risk.
3. If high-severity issues exist, mark the PR as "requires human security review" and notify the human.
4. Otherwise, recommend "security checks passed".
Never override human security approvals.
This matches GitHub’s direction with dedicated security review commands and early security gating.
You decide how deep to go based on the summary. Example:
Security guidance from OWASP is clear: automated tools miss business-logic issues. Agents can surface where to look; humans still need to look.
Human-in-the-loop only works if you can see which agent sessions are stuck, blocked, or waiting on you. Without that, you either poll everything or miss drift.
Maxxwell makes this explicit with per-session states like:
workingidlewaiting on youneeds sign-inblockeddonedeadnot heard fromOn top, it overlays "possibly stalled" when work hasn’t moved in a while.
In practice this means:
Because Maxxwell runs each worker in a real terminal session you can attach and take over at any time. Quitting the app detaches; it never kills sessions. Work outlives the window, which matters when you add checkpoints that might pause progress.
The biggest failure mode with human-in-the-loop is fake control: the UI shows an approval, but the system already did the thing.
OpenAI’s own guidance makes the split clear:
Maxxwell takes a hard stance here:
Practically, this gives you:
Anthropic reports that Claude Code users approve 93% of permission prompts; repeated prompts lead to fatigue. Maxxwell does not route or aggregate those prompts - each worker's permission prompts are still answered in that session's own view - but keeping every fleet-changing action behind a deliberate send keeps the decisions that matter from becoming reflex clicks.
To make this concrete, here’s a minimal pipeline you can actually run.
AGENT_GUARDRAILS.md and share them with the orchestrator.worker-impl - implements feature on a branch.worker-tests - writes/updates tests.worker-docs - updates docs.worker-impl to implement, self-review, and open a PR.worker-tests to extend tests for the PR.worker-arch and gate implementation on human approval.Because Maxxwell shows each session state and never auto-executes fleet changes, you keep velocity without silently losing control.
Start from risk and impact:
Codify this in a short guardrails file that agents read and follow.
Use one orchestrator seat and aggregate approvals:
This keeps you from clicking "allow" on every micro-action, while still owning real decisions.
Yes, and they already do at scale. GitHub reports that Copilot code review now accounts for over one in five reviews, with 71% producing actionable feedback.
Use agents to:
Then keep humans as the ones who decide what merges.
Tie approvals to scope:
You read and approve one doc instead of debugging multiple misaligned branches later. Velocity improves because rework drops.
In Maxxwell’s model, sessions are real terminals and outlive the app. Quitting detaches, it never kills them.
That matters for human-in-the-loop: