The audit trail
Every evaluation emits an : what
was asked, what was decided, and which rules fired. Current status, stated
plainly: the event shape is fixed and every decision emits one, but the
default sink is a no-op, so nothing is persisted until you (or a planned
release) wire a real sink via setAuditSink.
The shape
interface AuditEvent {
timestamp: string;
decisionId: string;
version: string; // the rule's constitution version
payload: unknown; // redacted first (see below)
result: InterceptionResult;
violations: Violation[];
decidedComponent: string | null;
}Because each violation can carry its standard, the record says which rule
blocked a request and where that rule comes from, not just that it was
blocked.
Redaction happens first
The payload is redacted before the event is emitted, per each rule's redaction config:
- Dropped: card security codes (CVV), PINs, second factors.
- Masked to the last four digits: card numbers (PAN).
- Hashed to a short fingerprint: account and IBAN numbers, and approver ids. Enough to correlate two events; the number itself is not stored.
Redaction runs inside emitAudit, not as a separate step a caller could
skip, so a hostile payload's sensitive fields don't reach the sink even when
the request is rejected.
Two honest caveats
The fingerprint is a non-cryptographic FNV-1a hash, planned to become a keyed hash when the durable sink lands. And until you set a sink, events are discarded: define your retention story before relying on the trail for compliance.
Next: For AI agents.