- Add llm_moderation_check() — async call to LiteLLM /moderations endpoint
(routes to OpenAI Moderation API, free) for hate/sexual/violence detection.
Fails open: if LiteLLM is unreachable, message is allowed through with a
warning log so core chat is never broken by a network hiccup.
- Add spawn_guard_log() — fire-and-forget tokio task that persists every
guard rejection (keyword AND moderation) to ai_guard_violations table.
- Wire both guards into ai_chat_message, ai_chat_ask, and ai_chat_stream.
- Add migration: ai_guard_violations(id, user_id, message_excerpt,
guard_type, reason, categories JSONB, created_at).
- Add GET /api/admin/ai/guard-events with filter by guard_type, pagination.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>