Execution Layer for Odoo
How it works.
Every tool call, from a read to a destructive write, runs through one validated pipeline with no fast path around it. This is each stage in order, and the commit boundary that makes a verified write verifiable.
The Execution Layer has one job: make every AI action against Odoo provable. It does that by routing every tool call, a read or a write, through a single pipeline. There is no fast path, no bypass, and no “trusted” caller that skips a stage.
The pipeline, stage by stage
identity -> policy -> schema -> semantics -> preconditions -> approval -> idempotency -> atomic execution -> read-back -> audit -> response- Identity. The bearer token (an OAuth token or a scoped API key) resolves to a real Odoo user. There is no service account: the AI acts as that person, under Odoo’s own access rights and record rules.
- Policy. The user’s access bundle, the connection’s chosen level, and the tool policy decide whether this tool is even visible, and whether this model and these fields are in scope, read versus write versus full.
- Schema. A fail-closed sanitizer checks the arguments. Unknown, hidden, read-only, or out-of-scope fields refuse the whole call. Values are never silently dropped or coerced.
- Semantics. Meaning is injected, human references are resolved, and ambiguity is refused
(
AMBIGUOUS_TARGET) rather than guessed. - Preconditions. Your declarative business rules are evaluated server-side, for example “a sales order needs a customer reference before it is confirmed”.
- Approval. If the action is risk-classed, the call is refused with
APPROVAL_REQUIREDand a payload-bound approval request is opened for a person to decide. - Idempotency. The write’s idempotency key is checked. The same key and payload replays the
original receipt; the same key with a different payload returns
IDEMPOTENCY_CONFLICT. - Atomic execution. The change runs inside one transaction: execute, flush, invalidate caches.
- Read-back. Still inside the transaction, the record is read back and compared against the declared intent and any assertions. Then the layer commits, and reads the record once more after commit to confirm.
- Audit. The evidence row is written on an independent database cursor, so it survives even a
business rollback. In strict mode, a failed audit write fails the call (
AUDIT_UNAVAILABLE). - Response. The Action Receipt for a write, or the structured result or refusal for a read or a denial. Every response carries both structured content and a text mirror.
The commit boundary
The order around the commit is what makes “verified” mean something:
execute -> flush -> in-transaction read-back and compare -> COMMIT -> post-commit confirmation read -> receiptverified: true is only ever set when a fresh read after commit matches the intent. If
something committed but did not match, because an onchange or a compute altered it, the layer does
not silently accept it. It returns VERIFICATION_FAILED, records the evidence, and raises the
default alert.
Fail closed
Ambiguity resolves toward refusal with a structured code, never toward a silent success. There are no prose-only errors: every failure an agent sees is a machine-readable code it can act on. See the error codes reference.
Why one pipeline matters
A connector that has a “quick” path for simple writes has a path with no verification and no audit. The Execution Layer refuses that trade. Because every call runs the same stages, the guarantees hold for the boring writes as much as the dangerous ones, and there is no configuration that turns them off for a caller you trust.
Next: installation.