Follow one disputed invoice through the boundaries that make a model useful in production.
A customer says an invoice is wrong. The model agrees, proposes a credit, and writes a reassuring reply. Which part of that sequence established that the customer owns the account, that the charge was actually duplicated, or that this workflow can move money? A fluent answer leaves those questions open. A production design needs somewhere specific to answer each one.
That is the useful meaning of an AI control plane: the application machinery that decides which work can proceed, under whose authority, with what evidence, and how the outcome becomes known. Here is a proposed reference architecture built around a hypothetical invoice-dispute service. It is a design exercise, not a report from a deployed system. The month’s decisions about routing, abstention, and execution meet at the boundaries between its components.
Start with an intake record, before asking a model anything. Give the request a durable identifier. Bind it to the authenticated account through application code. Store the customer’s message as customer-supplied content, alongside separately retrieved invoice records, their source identifiers, and retrieval times. Preserve those distinctions when constructing context. A sentence inside an uploaded invoice cannot become a policy instruction merely because retrieval placed it beside a trusted record.
The first decision is whether interpretation is needed at all. An exact invoice identifier can go through a deterministic lookup. Unstructured language may need a classifier to identify the request, followed by an extractor to propose the disputed line item. A long, contradictory explanation may justify a more capable model. The decision ladder selects the kind of operation; the router then selects an approved implementation for that operation, subject to data-access rules, latency budgets, and available capacity.
Keep the router’s output boring: a route identifier, an input reference, and a reason code. Its registry records which model, prompt, and schema belong to each route. An unavailable local model does not automatically justify sending an entire billing history to a cloud service. The fallback has to satisfy the same data rules. If no permitted route can handle the request, the workflow stops interpretation and creates a review item with the missing capability identified.
What comes back from inference is a proposal. In this example, it contains an invoice identifier, disputed line identifiers, an explanation, and evidence references. An evaluator checks required fields, whether the cited records exist, and whether they support the proposed duplicate-charge explanation. Arithmetic comes from code over the billing records. A second model might help flag contradictory explanations, but agreement between models is not a substitute for a matching transaction record. Unsupported proposals move to review.
Only then does the service ask whether the proposed action is allowed. Open Policy Agent describes this separation as decoupling policy decisions from policy enforcement. In this design, the policy decision uses trusted account identity, the specific action and amount, current account state, and any required approval. A tool gateway enforces the result. Credentials live there, outside model context. Supplying a convincing justification cannot mint a credential or change an account boundary.
For this hypothetical first release, every credit requires a billing reviewer’s approval of the exact account, amount, and invoice lines. The model can prepare that package without holding the permission to issue it. The approval is bound to those fields and expires if they change. The gateway checks current permissions again when execution starts. That follows OWASP’s guidance to deny by default and validate permissions on every request. A saved approval is evidence for a decision, not permanent permission to act.
The durable runtime owns the next transition. It records the authorized operation and its stable request identifier before invoking the billing adapter, then retains the provider’s receipt. This is where checkpointing and external effects must be considered together. A persisted workflow state does not, by itself, prove that a remote credit happened once. AWS’s discussion of idempotent APIs explains how caller-provided request identifiers let a service recognize retries of the same intent. The adapter must use the actual provider contract, including its retention limits.
Suppose the billing service accepts the credit, but the connection drops before the receipt arrives. The runtime records an unknown outcome. It must reconcile against the existing request, using a status lookup or a retry supported by the provider’s idempotency contract. Creating a fresh request identifier would describe another operation. If the provider offers no reliable reconciliation path, an operator owns the uncertainty. The customer-facing reply cannot announce that the credit succeeded while the execution record still says unknown.
After execution, a separate check compares the receipt with the approved proposal: same account, same amount, same invoice. The reply generator receives that verified result and the allowed explanation fields. It cannot turn a pending adjustment into a completed refund through optimistic wording. This gives evaluation two distinct jobs: checking the proposal before a side effect and checking the claimed outcome afterward. The evidence available to each check is different, so one generic quality score would hide too much.
Telemetry ties these transitions together through the request identifier. Record the route and its version, evidence references, policy decision and version, approval reference, execution attempt, provider receipt, and final disposition. Keep sensitive payloads in controlled storage with explicit retention; traces can carry references and redacted fields. Application services write the audit trail outside the model’s control. A generated explanation can be attached to it, but cannot rewrite whether a permission check failed or a payment result remained unresolved.
The feedback path runs more slowly than the request path. Reviewers label unsupported explanations and incorrect routing decisions. A calibration job evaluates the relevant classifier on labeled data rather than treating its self-description as confidence. Scikit-learn’s calibration documentation distinguishes estimated probabilities from observed class frequencies and requires care to keep fitting and calibration data separate. For this architecture, threshold changes become versioned release candidates, checked on held-out cases for error costs and reviewer demand before an owner promotes them. No threshold grants credit authority.
The human queue is also part of the design. Every abstention needs a reason, supporting evidence, a responsible team, and a deadline for the next decision. Missing documents, rejected authorization, and an unknown billing outcome require different handling. Queue capacity feeds admission control: when review demand exceeds capacity, the service can defer new work or narrow what it accepts. Silently loosening a confidence threshold would change the service’s risk without resolving its staffing constraint.
All of this can begin inside one application with a database, a worker, a policy module, and a tightly scoped billing adapter. Separate responsibilities do not demand a fleet of microservices. The important property is that each transition has an accountable owner and an inspectable record. Follow one dispute through the system and you should be able to explain why it took that route, why an action was allowed, what actually happened, and who owns anything still unknown. That is the control plane worth building around a model.
Subscribe to Signal Over Noise for practical analysis of AI agents and automation: what to test, which constraints matter, and when a tool is worth using. Bring the next idea to one bounded workflow and check the result before expanding it.
If this was useful, forward it to one engineer who needs less noise in their feed.


