The Invariant
Production reality is recorded as immutable, append-only facts. A verified lot, an accepted order, an inspection verdict — each is written once and never mutated. Every read surface (dashboards, exports, verification) is computed on read from committed rows and the event stream, never trusted from cached counters.
The rule that must never be violated: the stream is the truth, everything else is a derived view. If a number cannot be rebuilt by replaying events, it does not belong in the system.
This is what makes the architecture replayable, auditable and debuggable — and it is the same pattern behind financial ledgers and serious event-sourced systems, applied to manufacturing.
The Contract
Canonical event envelope — the sync wire contract between edge and Control Plane:
interface ProductionEvent {
id: string; // uuid — GLOBAL dedup key (cp_event_dedup)
aggregate_type: string; // the biz_* table that produced it (e.g. BIZ_LOTTI)
aggregate_id: string; // uuid/id of the owning row
event_type: string; // INSERT_* | UPDATE_* — the data-link op that wrote it
payload: Record<string, unknown>; // the fact itself — never mutated after write
created_at?: string; // ISO-8601 UTC, edge-side wall clock
}
The Flow
producer (operator dashboard / machine integration / plugin)
→ POST /api/v1/actions/:trigger (edge, authenticated session)
→ pipeline validates: RBAC + constraint + FSM + data-link [one transaction]
→ row written to biz_* + audit row + ax_cdc_outbox entry
→ outbox drain → POST /sync/ingest (cloud, edge api_key, signed)
→ cp_events (dedup on id) → read models compute on read
Writes are local-first: the edge keeps working with the cloud down; the outbox flushes when connectivity returns. Duplicate delivery is a designed retry path, not an error.
Payload Example
# One production fact as submitted by the edge daemon
curl -X POST https://cp.axiom-trace.eu/api/v1/sync/ingest \
-H "Authorization: Bearer $EDGE_API_KEY" \
-H 'content-type: application/json' \
-d '{"events":[{
"id":"9f2c…","aggregate_type":"BIZ_COLLAUDI",
"aggregate_id":"<row-uuid>","event_type":"INSERT_BIZ_COLLAUDI",
"payload":{"pezzo":"PZ-001","misura":0.018,"esito":"CONFORME"},
"created_at":"2026-09-26T14:01:04Z"}]}'
# → 201 { processed_count: 1, duplicate_count: 0 }
# Re-send the same batch → 201 { processed_count: 0, duplicate_count: 1 }
Known Failures
| Violation | Result |
|---|---|
Same event id re-sent |
Silently deduplicated — duplicate_count grows, no error |
created_at in local time |
Audit corruption — timestamps must be UTC |
| Mutating an event after write | No code path exists — emit a corrective fact instead |
| >1000 events per ingest batch | 413 BATCH_TOO_LARGE — split the batch |
Normative text: spec/ in the Axiom-Trace repository. If this page and the spec disagree, the spec wins.