Concepts
The action layer
The single write path every actor uses — human, AI, integration, workflow. Why it exists, what it guarantees, and how to think about it.
The action layer is the single write path in Servanex. Every state change — booking a job, capturing a payment, merging a customer, sending an SMS, posting a ledger entry — happens through a tool defined in the action layer. There is no direct database write. There is no “back door.”
What runs in a tool
Every tool, when invoked, runs through the same pipeline:
- Validation. The input is parsed and validated against a Zod schema. Invalid input fails before any work is done.
- Permission check. The actor (human, AI, integration, or workflow) is checked against the tool’s required permission and any applicable approval policy.
- Idempotency lookup. If the tool is configured as idempotent, the request’s idempotency key is checked. Duplicate requests return the original result without re-executing.
- Tenant context. The Postgres connection sets
app.tenant_idto the actor’s tenant — this is what RLS reads from to enforce isolation. - Execute. The tool body runs: reads from this module’s repositories, calls other modules’ tools as needed, emits domain events via the outbox.
- Audit. The action log records actor, source, reason, input, output, outcome, latency, and (for AI calls) model, prompt version, tokens, and cost.
- Publish. Domain events flow from the Postgres outbox to EventBridge, where consumers (workflows, AI agents, integrations) react.
What this guarantees
- No bypass. Nothing writes to the database without going through this pipeline. There is no service-account script, no integration shortcut, no ORM raw write.
- Symmetric AI safety. The AI is constrained by the same rules as humans. If a CSR can’t refund over $1k without manager approval, neither can the AI.
- Auditability. Every action is in the log. You can answer “who changed this, when, and why” for every record in the platform.
- Event replay. Because every state change emits an event, you can replay history for analytics, debugging, or rebuilding caches.
How to think about it
If you’re coming from a traditional CRM or FSM, the closest mental model is: “every action is a function call, and every function call is logged.” If you’re coming from event-sourced systems, the closest model is: “the action log and event log are the source of truth, and the database is a projection.”
The platform was built this way from the first commit. It isn’t an audit feature bolted on later — it’s the foundation everything else depends on.