Data model

Reference shapes for the rows arbiter persists. Every endpoint that returns one of these types matches this schema; lists are arrays of these objects under named keys.

Tenant

FieldTypeNotes
idintegerAssigned at creation. Stable.
namestringDisplay-only; no uniqueness constraint.
disabledbooleantrue → all /v1/orchestrate calls return 401.
created_atintegerEpoch seconds.
last_used_atintegerEpoch seconds. 0 if the tenant has never made a call.

Conversation

FieldTypeNotes
idintegerStable per tenant.
tenant_idintegerFK into tenants. Always equals the caller's tenant.
titlestringDisplay title. May be empty.
agent_idstringWhich agent this thread talks to.
agent_defobject?Snapshot of the inline agent definition (if the conversation was created with one). Absent for stored / index agents.
created_atintegerEpoch seconds.
updated_atintegerEpoch seconds. Bumped on every message append.
message_countintegerTotal messages in the thread.
archivedbooleanHidden from default UI views; not deleted.
originstring"api" (HTTP) or "tui" (interactive sidebar). Defaults to "api".
cwdstringWorking directory at creation (TUI); empty for typical API threads.
deleted_atintegerSoft-delete epoch; 0 = visible. Soft-deleted rows are omitted from list endpoints.
total_tokensintegerCumulative billed tokens (TUI sidebar); 0 for API-only threads unless set.
titledbooleanTitle locked against auto-titling (TUI).
folder_idinteger?FK into conversation_folders, or null when unfiled.

TUI sessions also store a multi-agent session_json blob on the row (not exposed on the HTTP conversation resource today). HTTP turns continue to use the messages table.

ConversationFolder

Named grouping for conversations (TUI sidebar tree and HTTP folder_id filter).

FieldTypeNotes
idintegerStable per tenant.
tenant_idintegerFK into tenants.
namestringDisplay name.
positionintegerSort order among folders (ascending).
created_atintegerEpoch seconds.
updated_atintegerEpoch seconds.

Deleting a folder unfiles its conversations (folder_id cleared) rather than cascading deletes. TUI collapse state for folder headers lives in tui_prefs.folder_collapse_json (JSON array of folder ids), not on the folder row.

ConversationMessage

FieldTypeNotes
idintegerAppend-only, ordered.
conversation_idintegerFK into conversations.
rolestring"user" or "assistant".
contentstringFull message text.
input_tokensinteger0 for user messages; full request total for assistant messages.
output_tokensintegerSame.
created_atintegerEpoch seconds.
request_idstring?Correlates to the SSE stream that produced it.

Agent (catalog row)

FieldTypeNotes
idstringCaller-chosen identifier (typically a UUID), [A-Za-z0-9_-]{1,64}.
namestringDisplay name.
rolestringShort role descriptor.
modelstringRouted by arbiter's provider prefix table.
goalstringWhat this agent is trying to accomplish.
brevitystring"lite" \"full" \"ultra".
max_tokensintegerResponse cap per turn.
temperaturenumber0.0–2.0.
rulesarray<string>Behavioral constraints.
capabilitiesarray<string>Tools this agent uses (used by master for routing).
modestring?"standard" (default) or "writer".
advisorobject?Structured advisor config: {model, prompt?, mode?, max_redirects?, malformed_halts?}. mode: "consult" (default) makes /advise available; mode: "gate" additionally enforces a runtime gate at the executor's terminating turn. See advisor.
advisor_modelstring?Legacy shorthand for advisor.model with mode: "consult". New configs should use advisor.
personalitystring?Free-form personality overlay.
created_atintegerEpoch seconds. Stored agents only; absent for the built-in index.
updated_atintegerEpoch seconds. Stored agents only.

MemoryEntry

FieldTypeNotes
idintegerStable.
tenant_idintegerFK.
typestringuser \feedback \project \reference \learning \context.
titlestringNon-empty, ≤ 200 chars.
contentstring≤ 64 KiB.
sourcestringFree-form provenance, ≤ 200 chars.
tagsarray<string>0..32 tags, each 1–64 chars.
artifact_idint?Optional FK to tenant_artifacts. null when unlinked.
conversation_idint?Optional scope. null = unscoped (visible from every conversation). Positive = pinned to one conversation; conversation-local search ranks it above tenant-wide hits.
valid_fromintegerEpoch seconds. When the fact became true. Set automatically on insert (= created_at); not editable.
valid_toint?Epoch seconds when the entry was invalidated. null while active. Stamped by POST /v1/memory/entries/:id/invalidate; once set, the row is hidden from default reads but reachable via ?as_of=<epoch>. See Structured memory → Temporal model.
created_atintegerEpoch seconds.
updated_atintegerEpoch seconds.

MemoryRelation

FieldTypeNotes
idintegerStable.
tenant_idintegerFK.
source_idintegerFK to memory_entries.id.
target_idintegerFK to memory_entries.id. Different from source_id (no self-loops).
relationstringrelates_to \refines \contradicts \supersedes \supports.
created_atintegerEpoch seconds.

ArtifactRecord

FieldTypeNotes
idintegerStable.
tenant_idintegerFK.
conversation_idintegerFK.
pathstringSanitised, ≤ 256 chars total.
sha256stringHex digest of content.
mime_typestringFree-form; default application/octet-stream.
sizeintegerBytes.
created_atintegerEpoch seconds.
updated_atintegerEpoch seconds.

See also