DEV Community

Cover image for Part 6: Where should an invoice agent stop and ask a person?
Shakar Bisetty
Shakar Bisetty

Posted on

Part 6: Where should an invoice agent stop and ask a person?

Part 6 · One Agent, Five Platforms

"Human in the loop" is often treated as a checkbox: somewhere in the flow, a person clicks approve. That isn't a design. A design says exactly where the agent stops, what the person sees, what their approval allows, and what happens if nobody answers.

This part fixes those decisions for the invoice-exception agent, before any platform is involved. Every build from Part 11 onwards has to implement them the same way.

Where the invoice agent stops and asks

Three gate points

Following the flow from Part 2, there are three places where the question "does a person need to decide?" gets answered.

Gate 1: no gate, by design (within tolerance)

An invoice that matches the PO and receipt within the agreed tolerance closes automatically, by rule. No agent, no adjustment, no person.

This is a deliberate decision, not a gap. Putting a person in front of thousands of correct invoices trains them to click approve without reading, which makes the gates that matter weaker. The tolerance itself is set and owned by finance, and changing it is a controlled change, not something the agent can touch.

Gate 2: before any write to the ERP

Before post_invoice_adjustment can change a price, a quantity or a posting, a person with the right authority must approve the specific proposal. This is the gate that protects money.

The agent prepares everything: the exception type, the evidence (PO line, receipt, supplier history, price agreement) and the exact adjustment it proposes. The person approves or rejects that one proposal.

Gate 3: before any contact with a supplier

Before notify_supplier sends anything, a person approves the message. Supplier relationships are long-lived, and a wrong or badly worded query can do more damage than a delayed payment. The agent drafts; a person sends.

Reading and investigating need no gate at all. The agent can look up invoices, POs, receipts and supplier history as much as it needs to, because reading changes nothing. That's why Part 2 made read-only tools the default.

Why the gate lives in the process layer

The approval check is in the process API, not in the prompt. In the reference architecture, that's layer 4.

The difference is simple. An instruction in a prompt such as "always ask before posting" is a request. The model usually follows it, but a strange invoice, a long conversation or a confusing tool result can lead it astray. A check in the process API is a rule. post_invoice_adjustment rejects any call without a valid approval_id, returning APPROVAL_MISSING, whatever the agent believed.

Series 1 made the same point in the human-in-the-loop post, for SAP change approvals. It applies unchanged here, and on all five platforms.

What a valid approval means

An approval_id is only useful if it can't be stretched. Four rules make it tight:

  1. Bound to one proposal. The approval covers one invoice, one action and one amount. If the agent changes the proposal after approval, for example a different price, the approval no longer matches and the post is rejected.
  2. Single use. Once used, it can't be replayed for another invoice.
  3. Expires. An approval that sits unused for days is stale, because the invoice, the PO or the period may have changed. Expired approvals are rejected, and the agent must ask again.
  4. Separation of duties. The agent can request an approval, but it can never grant one. The approver must be a person, and not the same identity that requested it.

None of these rules depend on the platform. They're checks in your process API against the approval record your workflow creates.

Who approves what

Approval tiers follow the risk quadrants from Part 2:

  • Low risk, such as a missing receipt or a near-duplicate: a quick approval from the AP team.
  • High risk, such as a price or quantity variance over tolerance: an approver with financial authority for that amount.
  • Tax mismatches: the tax team, with the agent providing evidence only.
  • Closed purchase orders: procurement decides; the agent summarises.

request_approval routes the task to the right group based on the exception type and amount. The routing is a rule, not an agent decision.

When nobody answers

Approvals sit in someone's inbox. The design has to say what happens next:

  • Reminder after a set time.
  • Escalation to a deputy or the next level if it's still unanswered.
  • Safe default: the invoice stays on hold. Nothing is posted and nothing is sent because a timer ran out.

A timeout should never turn into an approval. "No answer" means "not approved".

What the approver sees

The approval is only as good as the screen behind it. At minimum, the approver sees the exception type, the proposed action and amount, the evidence the agent used, and a link to the source documents. One click to approve or reject, with an optional comment that goes into the audit trail. Part 34 compares how each platform presents this.

How this shapes the builds

For each build, I'll check that the platform can:

  • Create an approval task with the proposal and evidence attached.
  • Pause the agent's work and resume it when the decision arrives.
  • Return an approval_id that the process API can verify.
  • Keep an audit trail of who approved what, and when.

These map directly to the human-in-the-loop criterion in the scorecard.

Where would you put the gate?


This series describes a reference build on a fictional company. Product capabilities are based on vendor documentation as of October 2026; check current docs before you build.

Top comments (0)