chat_conversations— one header per conversation (title, turn count, token totals, last activity, expiry). The history list reads this.chat_logs— one record per turn (message, reply, model, latency, guard outcome). The transcript detail.
agent_checkpoints, keyed by conversation_id. When a student resumes, the transcript is for display; the checkpoint is what the model replays — so the context is preserved, not just the rendered text.
Retention
Conversations carry a sliding expiry:expires_at is set to 30 days after the most recent turn (configurable via MIND_CONVERSATION_TTL_DAYS). A MongoDB TTL index purges the header and its chat_logs once that passes — there’s no cron to run.
Conversations from the console / command center (channel set to console, with an admin role) never expire: expires_at is null, which the TTL index skips.
Endpoints
List conversations
GET — history, newest first
Get a conversation
GET — header + full transcript
Stop a stream
POST — cancel an in-flight reply