An agent that can post a bill, adjust a quantity, or release a payment is a different risk category than one that only answers questions. Oversight is the design work that decides, deliberately, which actions an agent can take unsupervised, which need a human to approve, and how every action — approved or not — gets recorded so an auditor (or a confused finance manager) can reconstruct exactly what happened and why.
Not every action deserves the same oversight
Treating "read a record" and "post a journal entry" identically is either too restrictive (nobody wants to approve every lookup) or too permissive (nobody wants an agent posting entries unsupervised). Classify actions by blast radius before writing any oversight logic: read-only lookups need none, reversible low-value actions (draft a message, tag a record) can run unsupervised with logging, and anything that moves money, changes a customer-facing document, or is hard to reverse needs a human in the loop before it executes, not after.
ACTION_TIERS = {
"get_invoice_status": "auto",
"draft_customer_email": "auto",
"apply_credit_memo": "approval_required",
"post_ap_bill": "approval_required",
"release_payment": "approval_required",
}
def execute(action_name: str, args: dict, requested_by: str):
tier = ACTION_TIERS.get(action_name, "approval_required") # default deny
log_action(action_name, args, requested_by, tier)
if tier == "auto":
return run_action(action_name, args)
return queue_for_approval(action_name, args, requested_by)
New tools get added over time. A new action that isn't explicitly in the "auto" list should require approval by default, not run unsupervised because someone forgot to classify it. Fail closed, not open.
The approval queue has to be fast enough to use
A human-in-the-loop step that takes a day to clear defeats the point of automating the task in the first place — people route around slow approval queues, which quietly reintroduces the risk you built oversight to prevent. Show the approver exactly what will happen in plain terms (amount, account, counterparty) rather than a raw JSON payload, and make approve/reject a single action, not a multi-click form. If approvals consistently take too long, that's a signal the tier classification is too conservative for that action, not that the queue needs to be bypassed.
The audit trail has to survive the agent being wrong
Every action — proposed, approved, rejected, or auto-executed — needs a durable record: what was proposed, what data it was based on, who or what approved it, and the actual result from the system of truth (not what the agent said would happen). This is not optional infrastructure you add later; it's what lets you answer "why did this happen" six months after the fact, and it's what most audit frameworks (SOX, internal controls) will explicitly require once an LLM is in the approval chain for financial transactions.
Explaining the agent's reasoning, not just its action
Logging "posted bill #4821 for $1,200" is necessary but not sufficient. Log the reasoning trace too — which tool calls informed the decision, what data was pulled from Acumatica, what the model's stated justification was. When something goes wrong, "the agent decided to do X" is a much smaller improvement over "the agent did X, based on Y and Z, when the actual PO was for a different amount" — the second version tells you exactly what to fix.
Review the tier boundaries periodically
Oversight isn't a one-time classification exercise. As an agent proves reliable on a given action class over months of approved-and-correct decisions, it's reasonable to reconsider whether that action still needs a human gate — moving it to auto-with-logging once the error rate has been low for a sustained period. Move in the other direction immediately if an action class produces even one incident; tightening oversight after a near-miss costs far less than the incident it prevents.
| Action class | Oversight level |
|---|---|
| Read-only lookup | None, log only |
| Reversible, low value | Auto-execute, log, sampled review |
| Financial write, hard to reverse | Human approval before execution |
| Unclassified / new tool | Approval required by default |
Wrapping up
Classify actions by blast radius, gate anything hard to reverse behind a fast human approval step, and log the reasoning as well as the outcome for every action the agent takes. The oversight layer is what makes it defensible to give an agent write access to ERP data at all — skip it and you're trusting prompt engineering to enforce controls that belong in code.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.