Conclave Docs

Data model

Schema highlights and the load-bearing migrations.

Conclave persists everything in one SQLite file inside the TEE (relational + FTS5 + sqlite-vec vectors), managed by SQLAlchemy 2 + Alembic. Alembic auto-applies on boot. VFTE keeps its own sealed SQLite voiceprint store.

Key tables (conceptual)

  • transcript_sessions — the meeting: owner_user_id, recorder_user_id, owner_only, created_at, metadata (source/platform/origin), enrichment_state.
  • raw_diarization — write-once span-level truth {start, end, local_speaker}. Never mutated; edits and identity live in overlays.
  • transcript_v2 + vocab — the editable, span-annotated doc (draft → approved) + personal vocabulary.
  • live_segments — append-only live stream for the SSE view.
  • resolved_speakers — the identity overlay {label: {voiceprint_id, name, confidence}}.
  • chunks + FTS5 + embeddings; entities / facts / obligations — bi-temporal (valid_to / superseded_by).
  • workspaces / workspace_members / workspace_invites / meeting_workspace_shares — the membership + sharing graph.
  • magic_links, audio-store metadata, feedback, T&C acceptance.

Load-bearing migrations

MigrationWhat it introduced
0002workspaces / members / shares / magic_links
0007entities / facts / obligations
0012 → 0024share scope enum → per-artifact {transcript, insights, audio} flags
0013retention
0016live_segments
0018transcript_v2 + vocab
0022audio-store
0023in-person agenda
0025user T&C
0027workspace_invites + meeting_workspace_shares + recorder_user_id / owner_only (#32)

The raw / derived split is load-bearing: raw_diarization is immutable and never serialized unless authorized; everything else (overlays, v2, insights, KB) is derived and re-derivable.

Worked example: the sharing scopes (how to add one)

Sharing is per-artifact booleans, not an enum (that was the 0012 → 0024 change). Concretely:

  • Columns: share_transcript, share_insights, share_audio on the share record.
  • Model: ShareConfig in infra/workspaces.py is the single place a share's booleans are built.
  • Enforcement gates: can_see_transcript / can_see_insights / can_see_audio in api/transcripts_routes.py decide what a viewer's response includes (insights are independently withholdable).

To add a new scope (e.g. "share attachments"): add the boolean column via a new Alembic migration (mirror 0024), extend ShareConfig, add a can_see_attachments gate alongside the others, and surface it in the share UI. This is the #31 pattern end to end.

Source: FEATURE-SPEC.md §2.6 & §2.12, conclave-shape-rotator/alembic/, infra/workspaces.py, api/transcripts_routes.py.

On this page