"""Small audit interface shared by backends and integrations.""" from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime, timezone from typing import Any, Protocol from uuid import uuid4 def utc_now() -> str: return datetime.now(timezone.utc).replace(microsecond=0).isoformat() @dataclass(frozen=True) class AuditEvent: """Minimal event envelope for the first Audit Core implementation.""" source: str action: str resource: str outcome: str tenant: str = "platform" scope: str = "platform-control-plane" actor: str | None = None reason: str | None = None details: dict[str, Any] = field(default_factory=dict) event_id: str = field(default_factory=lambda: str(uuid4())) observed_at: str = field(default_factory=utc_now) schema_version: str = "audit-core.event.v1alpha1" def as_record(self) -> dict[str, Any]: return { "schema_version": self.schema_version, "event_id": self.event_id, "observed_at": self.observed_at, "tenant": self.tenant, "scope": self.scope, "source": self.source, "actor": self.actor, "action": self.action, "resource": self.resource, "outcome": self.outcome, "reason": self.reason, "details": self.details, } class AuditBackend(Protocol): """Protocol implemented by audit sinks.""" def emit(self, event: AuditEvent) -> str: """Persist an event and return a backend-specific reference."""