Sessions & Threads
The word "session" means two different things in the codebase. One is an auth session — a refresh-token tracking row. The other is a memory query session — an optional context handle on /memory/query. There is also the Conversation model for long-lived chat threads. This page distinguishes all three and lists what does not exist.
Three "session" shapes in the codebase
| Shape | Purpose | Persisted? |
|---|---|---|
| Auth Session | Tracks a refresh token and the device it lives on. | Yes — sessions table. |
| Memory query session | Carries query-time context across follow-up calls. | Not by default — handled by the session engine in process state. |
| Conversation | A long-lived chat thread. | Yes — conversations table. |
Auth Session fields
| Field | Notes |
|---|---|
id | Internal id. |
user_id | FK to User. |
device_id | FK to Device. Tracks IP, fingerprint, location. |
refresh_token_hash | HMAC-SHA256 hash of the refresh token. The plaintext is never stored. |
family_id | Token rotation chain identifier. |
session_type | web, api, mobile, cli. |
is_active, is_current | State flags. |
expires_at | Absolute 14-day expiration. |
The memory-query <code>session_id</code>
POST /memory/query accepts an optional session_id on the request body. The recall engine uses it to enrich follow-up queries with context from previous turns. By default this is held in the in-process session engine; persistence is opt-in.
session_id is not a scope key. It does not affect ownership or isolation. It is a hint to the recall engine.Conversation — the chat thread model
Conversation rows represent long-lived chat threads. Each row carries a UUID, a user_id, and references to the messages that belong to it. Conversations are separate from memory scoping — the same memory can be referenced across many conversations.
What does not exist
- No
thread_idcolumn onMemory. Memories are not bound to a chat thread. - No
session_idcolumn onMemory. Memories are scoped to(tenant, project, user), not to a session. - No Thread model. The chat-thread concept is the Conversation model.
How to model a chat app on top of MemorySync
- 1Use Conversations for the thread itself — message order, message bodies.
- 2Write memories from messages that contain durable knowledge — preferences, facts, decisions.
- 3Pass a stable
session_idto/memory/queryacross the same chat turn so the engine can carry context. - 4Do not embed the conversation id into the memory's scope keys — keep them clean for cross-conversation recall.
Refresh and rotation
POST /auth/refreshrotates the refresh token; the old token'sfamily_idis reused but its hash is invalidated.POST /auth/logoutrevokes the active session.- Reusing an old refresh token from the same family triggers a security event and invalidates the entire family.