The Neogen Brief
Agentic Automation

AI Agent Orchestration: A Second Approver, So One Human Stops Being a Queue of One

One human was the approval queue for four agents. How delegation went in on 9 August 2026, the invariant that had to hold, and the bug only the real path caught.

Rehdhil Siyad
Rehdhil Siyad
Founder · Neogen Media
24 September 2026
13 min read
Two chrome approval stamps with a stream of red request coins splitting between them, one coin bouncing away rejected

AI agent orchestration is usually described as a routing problem: which agent gets which task. In our mesh the harder problem was approval. Four agents, one approval gate, and exactly one human who could release anything gated. Every restart, budget change and record update from three subordinate agents waited on one phone. This is how we added a second approver on 9 August 2026 without turning the gate into a bypass.

The short version: we let JARVIS, the founder agent, release a named subset of actions on the founder's behalf. The invariant that made it delegation rather than a hole is that an agent can never approve its own request, and we enforce that twice. Seven tests through the real path proved it, and one of them caught a bug the convenient test path would have shipped.

Why did one human end up as the approval queue for a whole agent mesh?

Because the gate was built with one approver on purpose, and the mesh grew faster than the gate did. Between 21:32 and 22:34 on 30 July 2026, JARVIS designed, deployed and wired an inter-agent bus. Every step went through the approval gate with the founder's code: 13 submissions, each submitted, approved and executed, with 5 genuine failures retried in the open.

The bus itself had a sound authority model from the first hour. Per-agent keys, an allowlist, and a 403 that reads "non-super agents can only send to super agents". Kiara, Taurus and Neo could report up to JARVIS but could not task each other, and none of them could read another agent's inbox. That is the org chart enforced in code, which is the whole argument of our agent mesh post.

What the bus did not have was any approval authority. The gate still knew one person. So the mesh made the agents better at coordinating with each other and did nothing about the fact that every gated outcome of that coordination landed on one human. We had already seen the arithmetic of that on 30 July, when the CBO agent needed roughly 324 approval codes to do data entry; the governance post covers how the per-agent keys and the first self-service carve-out came out of that. Self-service shrinks the queue. It does not add a second person to it.

What did the founder's complaint on 9 August actually reveal?

The complaint was that the COO agent was asking permission for things inside his own job. The cause was not the approval gate. It was three descriptions of the system that disagreed with the system: a rule in the agent's identity file, a cron prompt, and an unstated reporting line. All three made escalating the locally safe move.

Seventeen bus messages passed between Taurus, the COO agent, and JARVIS in three hours, all about our task-management platform: a naming standard, section identifiers, which service to standardise. Five of JARVIS's replies came back as deliberate policy refusals. The thread ended as a decision memo on the founder's phone asking him to approve a naming convention.

When we pulled it apart, none of the causes was the suspect we expected:

  • The platform was never in the approval gate's registry. Taurus held his own API key for it and could have executed every write without asking anyone.
  • His identity file told him he could not. Rule 6 read "You propose, you don't execute." The gate had granted the permission weeks earlier; the prose still withheld it, and the prose is what the agent reads every time it reasons.
  • The escalation poller's prompt said "report the blocker to the founder" with no test for whose decision it was. Every unresolved item became a DM by construction.

A restriction the runtime stopped enforcing but the text kept stating fails the same way as a control that was declared and never applied: behaviour and declaration disagree, and nobody checks. The tell was cost, not error. Nothing broke. Two agents spent three hours enforcing a rule that no longer existed. We have written up how the same wrong belief spread into ten of Taurus's skill files in our multi agent system failures post; the delegation work below happened the same evening, after that sweep.

The fix to the routing was a different question, not a different threshold. The old poller asked "is this substantive?", and everything substantive reached the founder. The new one asks "whose decision is this?" first. If it sits inside the sender's own domain, JARVIS replies on the bus that it is theirs and does not relay it. Only money leaving the company, client-facing commitments, headcount or pay, irreversible actions and genuine gate approvals go to the human.

Why was self-service not enough on its own?

Because two of the powers in the COO agent's self-service set were money rather than operations, and detection alone cannot stop money already spent. Once Taurus had full autonomy over operations, the question that mattered was what should sit underneath that autonomy. Three facts decided it.

  • 60 of the platform's 68 actions are non-destructive. Gating them would put the founder in the loop for sixty reversible things to catch three irreversible ones.
  • Only three actions destroy anything: deleting a service, a task or a subtask. Archiving preserves history, and deleting a task status moves tasks rather than removing them.
  • Resuming a paused Meta campaign and setting a Meta budget were self-service for the COO. That is money leaving on a schedule, and it was the one power in his set that is not operations.

For the reversible sixty, the correct control for a principal who does not want to approve things is after-the-fact detection, not pre-approval. A notice costs the recipient nothing when the news is good and reaches them in minutes when it is not. An approval gate costs attention on every occurrence, most of which are fine, which is exactly how approval-by-habit gets trained. So the alerting we built that afternoon diffs the platform's inventory against a snapshot taken fifteen minutes earlier. There is no audit endpoint we can read, and a log would have been weaker anyway: any agent can call the API directly in three lines and never touch our tool. An inventory diff catches the change whoever made it and by whatever route, including the bypass.

For the two money actions, detection has a hole. It tells you within 15 minutes that a budget changed. The wrong budget spends during those 15 minutes. Those two needed pre-approval, and the obvious answer, "have JARVIS countersign", did not exist. The gate knew exactly one approver, so every pre-approval option routed straight back to the person who had asked not to be asked. That is the point at which delegation stopped being a deferred item.

How do you add a second approver without collapsing the authority model?

You name the delegated actions explicitly, you name who may release them and for which requesting agents, and you make self-approval impossible in two independent places. Anything less than the second part turns delegation into a bypass wearing its name, handed to the agent with the most access of the four.

The gate already had two sets per agent: actions that execute immediately, and actions that wait for the founder's code. We added a third, DELEGATED, listing the action types JARVIS may release on the founder's behalf and the requesting agents each applies to. A submission of a delegated type from Taurus routes to JARVIS instead of to the human, and the record shows the approver as the founder agent, not the founder.

The invariant

An agent can never approve its own request. That single sentence had to hold or nothing else about the design mattered, so it is enforced at both ends of the path. The release command refuses on identity: if the agent issuing the release is the agent that submitted, it fails with the reason "you submitted this yourself". And the submit command refuses to delegate at all when the submitter is the delegated approver, so a founder-agent submission of a delegated type is routed to the human by construction. Belt and braces. If one check is ever removed in a refactor, the other still holds.

This is the shape the OWASP Top 10 for LLM Applications asks for under Excessive Agency, where the seventh mitigation reads: "Implement authorization in downstream systems rather than relying on an LLM to decide if an action is allowed or not." JARVIS does not decide whether he is allowed to release his own request. The gate decides, from the key the request arrived on, and the key is not something an agent sends. It is baked into the forced command each agent's connection lands in.

Seven tests through the real path

Proven, not assumed. Each test was a real submission through the real submit path, with the real gate answering:

  • Taurus submits a container restart. Result: queued, routed to JARVIS rather than to the human, approver recorded as founder agent.
  • Taurus tries to approve it himself. Refused: only the founder agent may release this type.
  • Kiara, a peer, tries to approve it. Refused.
  • JARVIS approves it. Executed, approved by founder agent, with the requesting agent recorded as COO.
  • JARVIS submits the same action type himself. Approver recorded as the human. Never delegated to himself.
  • JARVIS tries to release his own submission. Refused, with the reason "you submitted this yourself".
  • Taurus submits a Meta budget change. Routed to JARVIS, refused with a stated reason, never executed.

The fifth and sixth lines are the ones that matter. The first four show delegation working. Five and six show it failing in the direction it must fail, from the one agent whose failure would be worst.

What moved into delegation, and what stayed with the human?

Two actions moved, both of them money, and the test for choosing them was not seniority. It was whether the action can be undone and whether it leaves the company. Seniority would have handed the COO agent everything an operations chief may do, including spend. Reversibility and blast radius put a container restart and a CORS origin in one bucket and a payment in another, regardless of who asked.

Resuming a Meta campaign and setting a Meta budget left the COO's self-service set and became delegated: Taurus requests, JARVIS releases, and the refusal path exists for a reason. Pausing a Meta campaign stayed self-service. It only ever stops spend, and the safe direction should never be the slow one.

Nothing else moved toward the founder. What is deliberately not delegated, each for a stated reason:

  • Billable provisioning, such as creating a database project or a CMS project. That is a recurring cost created by an agent.
  • Credential minting, such as creating an API token. A new secret is a new thing to rotate, leak and audit.
  • Anything client-facing, such as sending an invoice. It leaves the company and cannot be unsent.
  • Cash, such as recording a payment. The ledger is the one place a wrong write compounds.
  • Root anywhere: running arbitrary commands on a host or restarting the compose stack. The blast radius is the whole box.

If you are designing an agent mesh where agents touch live systems and want the approval boundary designed in rather than retrofitted, that is the work our AI agent development team does. Most of it is deciding which bucket each action belongs to before a single line of the gate is written.

What bug did only the real path catch?

A refusal reason that lied about itself. The submission script reaches the gate through an SSH forced command, and forced commands cannot do quoted expansion. A refusal reason passed as a quoted string arrived word-split, the code took the next single argument, and the audit recorded the reason as "delegation" instead of "delegation self-test, never intended to run".

The mechanism is documented behaviour, not a quirk. OpenSSH's sshd_config manual states that when a forced command is in effect, "the command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable". That is one string, and the shell's word-splitting of it does not respect the quotes your local shell already consumed. Our own script carried a comment saying exactly this, and its base64 handling of JSON parameters existed for exactly this reason. We had solved the problem for parameters and reintroduced it for the refusal reason one function away.

A refusal reason that lies about itself is worse than no reason at all. An empty field tells the reader to go and look. A plausible single word tells them there is nothing to see. The fix was to join the remainder of the argument list rather than take one element.

It only surfaced because the seventh test ran the in-container script rather than the host-side wrapper. The host wrapper does not cross an SSH boundary, so it passes quoted arguments intact, and every test through it would have been green. The convenient test path and the production path differed in exactly the place the bug lived. We had learnt the same lesson earlier the same day, when an alerting path that had never fired turned out not to be a control. Tests that avoid the real path prove only that the test rig works.

Should the human be told when a delegated action fires?

No. Telling the founder every time a delegated action is submitted, approved or refused rebuilds the bottleneck one level down. He asked to stop being a queue, and a notification queue is still a queue. Delegated actions are silent to him by design.

What he does see arrives after the fact, through the operations notice wired that same afternoon, for the two categories that matter: Meta spend and irreversible changes on the task-management platform. Each notice carries the approver. So a budget change released by JARVIS appears in the next fifteen-minute notice with JARVIS named as the releaser, and the audit line behind it names the requesting agent, the releaser and the reason. The oversight moved from before the action to after it, with the record intact. For the reversible actions that is the right trade, and it is the same trade the whole Neogen AI OS build keeps making: detection where the action can be undone, a gate where it cannot.

The primitive: delegate by blast radius, not by seniority

The test for what an agent may release on a human's behalf is not how senior the requesting agent is. It is two questions about the action: can this be undone, and does it leave the company. If both answers are no, a second agent can release it and the human hears afterwards. If either answer is yes, it waits for a person. And whoever releases anything, they can never release their own request, checked in two places so that no single refactor can remove the rule.

Frequently asked questions

Does delegating approvals to an AI agent still count as human oversight?

Yes, for the actions where oversight after the fact is sufficient. The human still sets the delegated list, still holds every irreversible and outbound action, and still receives a notice with the approver named. What changes is timing: the human reviews a record within fifteen minutes rather than a prompt in real time. For a payment or an invoice, that trade is wrong, so those never entered the delegated set.

Why not make a human colleague the second approver instead of an agent?

Because the queue moves, it does not shrink. A second human is available for the same eight hours as the first and has the same attention to spend. The delegated actions are the ones already judged reversible and internal, and an agent releases them in seconds at any hour, with the same identity checks and the same audit line a human release would produce. The human seat is reserved for the actions where a person's judgement is the point.

How do you stop the delegated approver being talked into releasing something?

By making sure the approver never reasons about whether it is allowed. The gate resolves identity from the key the request arrived on, not from anything the agent claims, and refuses self-approval on that identity. A budget request outside the delegated bounds is refused with a stated reason and is never executed, however persuasive the request text is. Authorization lives in the gate, downstream of the model.

How many actions should be delegated first?

Two, in our case, and both were the actions that had just been taken out of self-service because they were money. Start with the actions you have already decided need pre-approval but cannot afford to route to the human, prove the self-approval refusal on each one through the real path, and widen from there. A delegated set you cannot list from memory is too big.

Does this apply if the stack is n8n and GoHighLevel rather than a custom gate?

Yes. The pattern is a submission record, an approver identity resolved from a credential rather than a claim, and a rule that the submitter cannot be the releaser. Where the actions go afterwards is secondary. In our own gate, activating an n8n workflow remained gated to the human because it can start sending, while creating an inactive workflow is self-service because it cannot.

Want a second approver that is not a second bottleneck?

We build these gates for teams running agents against live ad accounts, CRMs and ledgers, and the first deliverable is always the bucket list: what executes, what waits, what one agent may release for another. If your agents are queueing on one person, talk to us and bring the list of what they are waiting on. We can usually tell from that list alone which half should never have been gated and which two should never be delegated. Our AI operating system work starts there.

Rehdhil Siyad
Rehdhil SiyadFounder · Neogen Media

Founder and Director at Neogen Media. Writing field notes on AI automation, growth systems, and the integrated playbook we ship for Indian SMBs. Based in Kochi.

Follow on LinkedIn
Next Step

Want a system like this shipped for you?

If the playbook above maps to your stack and you'd rather we implement it than read about it, book a 30-minute strategy call. We'll map the priorities, tell you what's actually worth building, and leave you with a plan either way.

Book a Strategy Call
30 MINFREE AUDITNO DECKNO OBLIGATION
Or send us a WhatsApp
// What You Walk Away With
  • 01

    A map of every manual task worth automating

  • 02

    Ballpark ROI on your top 3 automation opportunities

  • 03

    Honest read on whether we are a fit — or who is

Usually responds within 24 hours