11. Evidence, Audit, and Replay Records
An audit row says that something changed. An ActionRecord preserves the decision that produced the change: declaration revision, commands, rule results, evidence, snapshots, events, effects, results, and failures.
Declare evidence as a requirement
const releaseChecklist = Evidence(
name: 'area_release_checklist',
title: 'Area release checklist',
kind: EvidenceKind.checklist,
required: true,
source: EvidenceSourceRef('ops.checklist.area_release'),
retentionRef: 'gxp_10_years',
);
const activateArea = Action(
name: 'activate',
evidence: [releaseChecklist],
rules: [
Rule(
id: 'ops.area.activate.checklist',
kind: RuleKind.evidence,
condition: EvidencePresentCondition(
evidence: 'area_release_checklist',
),
),
],
audit: AuditEnvelope(
requireSignature: true,
requireReasonCode: true,
evidence: [releaseChecklist],
replayable: true,
),
);Required evidence blocks commit when absent. Evidence kinds include artifact, log, controlled document, photo, record, signature, checklist, generated report, and external reference.
Snapshot mutable decision inputs
capture: ActionCapture(
snapshot: ContextSnapshot(
targets: [
SnapshotTarget(
name: 'policy.area_release',
sourceRef: 'policy.ops.area_release',
),
SnapshotTarget(
name: 'master.area_category',
strategy: SnapshotStrategy.value,
sourceRef: 'ops.area.category',
),
],
),
)Use reference (the default) when the referenced revision is immutable and retained. Use value when the decision needs the exact resolved blob inside the record.
Read the durable envelope
ActionRecord
+ ActionReplayContext
+ ActionCommandRecord[]
+ ActionRuleRecord[]
+ ActionSnapshotRecord[]
+ ActionEvidenceRecord[]
+ ActionDomainEventRecord[]
+ ActionEffectRecord[]
+ ActionIntegrityRecord[]
+ ActionResult[]
+ ActionFailure[]| Question | Current durable facts |
|---|---|
| Who? | actor/scope request context and signer facts when supplied |
| When? | recorded time, scope action sequence, commit sequence, event sequence, stream sequence |
| What? | qualified commands, payload, results, failures, snapshots, and events |
| Where? | tenant/site scope and entity stream identity |
| Why? | reason, justification, rule records, policy snapshots, and integrity records |
| Under what definition? | Blueprint name:version and runtime version |
Denied and failed attempts return action records with typed failures instead of disappearing into UI-only error state.
Evidence is a structured record
ActionEvidenceRecord persists:
- declared evidence name, kind, and requiredness;
- action command lineage and capture time;
- source and retention ref;
- inline value or immutable object ref;
- digest, MIME type, size, and verification flag;
- additional typed metadata.
The object bytes may live outside PostgreSQL. The record links the accepted proof to the action that consumed it.
Ordering uses sequences, not only clocks
The PostgreSQL runtime schema stores:
scope_sequencefor actions inside a replay scope;commit_sequenceas the global action commit order;event_sequenceas the global event order;(stream_key, stream_sequence)as the per-entity event order;- request-local protocol frame sequences.
Timestamps remain useful for display, but equal or skewed clocks do not decide record order.
Declared events become committed facts
Action.emits defines the event. During execution, required payload fields are materialized and validated. A missing required value blocks the transaction. Committed events persist atomically in action_events with action/command, entity/facet, stream, payload, and sequence facts.
Events are projections of committed work. They do not replace current entity state or the action ledger.
Effects carry delivery state
Every planned runtime effect becomes an ActionEffectRecord with:
- kind and target;
- current state;
- idempotency key;
- attempt count;
- recorded, dispatched, and acknowledged times;
- failure payload and metadata.
Outbox workers update delivery state without applying the committed business mutation again.
Explain one request
final record = await runtime.execute(request);
final explanation = await runtime.explain(record.id);Use the record and explanation together:
- confirm the Blueprint revision and durable sequence;
- inspect commands and rule results;
- inspect snapshots and evidence;
- inspect results, failures, and integrity findings;
- follow domain event streams and effect lineage.
Studio renders human summaries from these records and preserves exact wire JSON in request/response inspectors.
Checkpoint
Execute area.activate once and verify:
- required checklist evidence is persisted;
- missing evidence blocks commit;
- the action record pins the Blueprint revision;
- action, global commit, event, and entity-stream ordering facts exist;
- emitted event and effect records point back to the action command;
- retrying with the same idempotency key returns the completed record.
Next: Extension points.
Reference: Execution Replay Contract.