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.
An action record connects the decision, evidence, and outcome.
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',
);
final activateArea = Action(
name: 'activate',
rules: [
Rule(
id: 'ops.area.activate.checklist',
kind: RuleKind.evidence,
test: Facts.evidencePresent('area_release_checklist'),
),
],
capture: ActionCapture(
evidence: [releaseChecklist],
snapshot: ContextSnapshot.none,
replayable: true,
),
);Required evidence blocks commit when absent. Evidence kinds include artifact, log, controlled document, photo, record, signature, checklist, generated report, external reference, and reason. For the common regulated mutation, use ActionCapture.signed(evidence: [releaseChecklist]); this adds required actor signature and reason evidence without a second audit declaration.
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.
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.
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.
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.
The portable definition behind the record uses vyuh.blueprint.definition/v2. It captures controls, ordered effects, host-evaluator references, composition provenance, and a reference index. Replay binds durable facts to that definition identity; it does not reconstruct meaning from whichever declaration happens to be running now.
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.