Audit
DesignThe audit log is how an operator answers “who changed this, and to what?” without trusting memory: every mutation is recorded once, at the source.
The model
Section titled “The model”audit_log is ground truth (not derived): one row per mutation, carrying actor, verb,
resource_kind, resource_id, and the old -> new diff.
- Write-time mandatory. Every API write emits one
audit_login the same transaction as the data write, a storage-layer responsibility, not per-handler discipline, so it cannot be forgotten or bypassed. - The actor is resolved by IAM (identity and access): the human, service, or node.
- An AI-accepted suggestion is one row. An AI tool acts via OAuth as a
humanorserviceprincipal, so the actor is that principal, attributed and audited like any caller; the AI-sourced marking rides alongside the row (AI). - Ground truth a backtest reads. Operator-driven transitions and config changes are not recomputable from collected data, so the audit log is what a rule backtest reads for them: alarm ack and snooze (alarms and actions), and every config change a reconcile consumes.
- Secret decrypts are always audited and never filterable. Every read of secret material
emits an
audit_log(a credential decrypt), and that subset cannot be filtered away. - Other reads are not audited at the storage layer. Optional read-audit is config-driven at the API layer (per-resource opt-in or a verbosity setting), off by default.
Retention and integrity
Section titled “Retention and integrity”Audit carries the longest retention of any ground-truth log (compliance), range-partitioned
by ts like the others. It is append-only by construction.
Who consumes it
Section titled “Who consumes it”- Backtest: a rule backtest reads operator transitions and config changes from here, since they are not recomputable.
- Reconcile: config changes arrive as
audit_logrows, so reconcile reacts to them. - The alarm projection: ack and snooze come from audit.