Part 19 · One Agent, Five Platforms
Parts 17 and 18 showed how tempting it is, on SAP, to put everything inside the ERP: the tools, the agent, the approval. That's a reasonable choice for the approval. For everything else, this part argues the opposite.
The ERP should accept or reject. The cleverness belongs before it.
This is a design part, not a build, so it applies to all five platforms.
What "boring" means
A boring system of record does three things:
- It accepts a valid posting and returns an identifier, such as a
posting_id. - It rejects an invalid one with a clear reason.
- It keeps the record: who posted what, when, and against which approval.
It doesn't reason, guess or make exceptions. It has no logic that exists only because an agent is calling it. If you removed the agent tomorrow, the ERP would work exactly the same.
The cleverness lives one layer up, in the process API from Part 3's reference architecture. That's where the four checks below run, on every platform.
Four checks before the write
Every call to post_invoice_adjustment passes through these, in this order. Each one has a named error from Part 8.
1. Validation. Does the request make sense? The schema from Part 7 already rejects missing fields and invented ones. The process API adds the business checks: the invoice exists, the amount and currency match, the accounting period is open. A closed period returns PERIOD_CLOSED.
2. Approval. Is there a valid approval_id for this exact invoice, action and amount? Part 6 set the rules: single use, and it expires. Anything else returns APPROVAL_MISSING.
3. Duplicates. Has this invoice, or one very like it, already been posted? check_duplicate_invoice runs again here, not just at the start, because things change between the agent's investigation and the approval. A match returns DUPLICATE_INVOICE.
4. Idempotency. Is this a retry of a posting that already happened? More on that next.
Only when all four pass does the process API call the ERP. And the ERP still runs its own checks: tolerances, blocks, authorisations. Don't switch any of them off because "the agent already checked".
Idempotent posting
Writes get retried. Part 8 gave transient failures, such as timeouts, to the integration layer: the process API retries them with backoff. That's right, but a retried write is how invoices get posted twice. The request timed out, but did the ERP post it or not?
The fix is an idempotency key: one key per intended posting, sent with every attempt. An IETF draft for an Idempotency-Key header describes the behaviour well, even though it's still a draft, not a standard:
- A repeat of a completed request gets the original result, success or error.
- A repeat that arrives while the original is still running gets 409 Conflict.
- The same key with a different payload gets 422.
For this agent, the key is tied to the approval. One approval allows one posting. A retry of the same posting, with the same key and the same payload, gets back the original posting_id, so the agent sees success and moves on. Anything else that tries to reuse the approval gets APPROVAL_MISSING, as Part 6 required.
The agent doesn't need to know any of this. It calls the tool once. The process API makes sure that "once" is true, however many times the network says otherwise.
The agent is never the last check
The agent proposes. The process API decides whether the proposal is allowed. The ERP decides whether the posting is valid. Three layers, and the agent is only ever the first.
That holds even when the agent has done everything right. If it read the invoice, matched the PO and found no duplicate, the process API still checks again before the write. The agent's checks are useful for investigating and explaining; they aren't controls.
It also holds when the approval lives in the ERP, as in Part 18's SAP design. The flexible workflow records the approval, and the process layer still checks it before posting.
The same rule on every platform
- MuleSoft: the four checks are Mule flows behind the process API.
- Boomi: they're Boomi processes behind the API Product.
- SAP: they're integration flows or API artifacts in front of S/4HANA, with the approval read from the flexible workflow.
- Azure and AWS: the same, in whatever runs the process APIs there.
Wherever the agent is built, the process layer is ordinary integration. That's the point: it's code your integration team already knows how to test, version and support.
Four things to avoid
- The agent calling the ERP's own APIs directly. That's a system API, with none of the four checks.
- A model in the posting path. Reasoning before the write, yes. Inside it, no.
- Relaxing ERP validations for agent traffic. The ERP's rules are the last line, not a duplicate to remove.
- Retries without a key. The second posting always happens on the worst day.
Part 20 asks the question this all leads to: would you let an agent post to your ERP?
Where does your last check live?
This series describes a reference build on a fictional company. This part is a design guide; no hands-on build has been run yet. Views are my own.

Top comments (0)