Document type: Normative.
Scope: iAuditLog, AuditRow, and user-facing history reads through iCommandService.
1. Purpose¶
The audit log is the append-only record of gated operations. It is distinct from broker queue history:
iCommandBrokerstores, orders, and yields pending commands for the tick-deferred path.iAuditLogrecords accepted-and-applied gated operations for user-facing history and accountability.
Runtime history reads call iCommandService.get_audit_history(...), which delegates to iAuditLog.query(...). The runtime does not keep a separate history.
2. Append-only invariant¶
iAuditLog has no drop_* or delete_* methods. Implementations MUST NOT delete audit rows.
Destroying a world does not delete audit rows. Fork cleanup after a rollout does not delete audit rows. Audit rows remain queryable after the live world object has been removed from the registry.
3. Audit unit¶
Every gated call emits one audit row.
Multi-step gate methods still emit exactly one audit row:
destroy_worldrecords one row for the lifecycle cleanup.run_rolloutrecords one row for the rollout call, not one row per fork.- Runtime activation emits one row per gated activation step: create world, each staged processor, each staged resource, and each staged hook.
The row payload captures sub-operation outcomes when one gated method performs multiple internal actions.
4. Row Schema¶
AuditRow is defined in app/models.py.
Required identity and operation fields:
audit_idcommand_idworld_idactor_idcommand_typestatuspayload_jsonaccepted_atapplied_at
Nullable fields:
idempotency_key
5. Query Contract¶
iAuditLog.query(...) is read-only and supports filters for:
world_idtick_rangeactor_ididempotency_keylimit
External callers do not call iAuditLog directly. They use iCommandService.get_audit_history(ctx, ...), which applies the read permission check before delegating.