# Audit log

Read-only view of `audit.events` per ADR-0013. Every query run on this page emits its own `admin.audit.query` row — read access is itself auditable.

## Filters

Event type Actor id hash Audience
Outcome
Subject prefix From To Page size
@if (tab() === 'table') { @if (loading()) { Loading… } @else if (error(); as msg) { {{ msg }} } @else if (page(); as p) { {{ resultRange() }} } } @else { @if (statsLoading()) { Loading statistics… } @else if (statsError(); as msg) { {{ msg }} } @else if (stats(); as s) { {{ s.total }} matching event(s) aggregated } }
@if (stats(); as s) { @if (hasChartData()) {

Aggregations are computed across the full filtered set (server-side), not just the events on the current page. Results are cached for 5 minutes per filter combination.

} @else {

No audit events match the current filters.

} } @else if (!statsLoading() && !statsError()) {

Switch to this tab to load statistics.

}
@if (page(); as p) { @if (p.items.length === 0) {

No audit events match the current filters.

} @else {

Timestamp | Event | Audience / outcome | Actor / subject | Trace | Payload
--- | --- | --- | --- | --- | ---
@for (event of p.items; track event.id) {

{{ formatTimestamp(event.createdAt) }}

{{ event.eventType }}

{{ event.audience }} {{ event.outcome }}

@if (event.actorIdHash; as hash) {
} @else {
(anonymous)
} @if (event.subject; as subject) {
{{ subject }}
}

@if (event.traceId; as traceId) { {{ traceId }} } @else { — }

@if (event.payload) {
view

    {{ formatPayload(event.payload) }}

} @else { — }

}

} }