Reference
Local database schema
Everything OOMU stores, and how. All of it lives on your Mac.
| File | oomu-beta2.sqlite |
| Engine | SQLite via SQLCipher |
| Schema version | 1 |
| Namespace | ai.eldris.oomu.gpd.beta2 |
1. Encryption
The database is encrypted with SQLCipher. Every connection opens with:
PRAGMA key='<key>';
PRAGMA cipher_memory_security=ON;
PRAGMA foreign_keys=ON;
PRAGMA secure_delete=ON;
- The key is held in the macOS Keychain, under a service namespace specific to Beta 2. It is never written to disk in plain text and never transmitted.
cipher_memory_securitywipes sensitive pages from memory.secure_deleteoverwrites deleted content rather than merely unlinking it.- After opening, OOMU verifies the database is actually encrypted before proceeding. Failure raises
data_encryption_failedrather than continuing against a readable file.
A copied database file is not enough to read your data. The key is bound to your Keychain, on this Mac.
What is not in here
Secrets. API keys, OAuth refresh tokens, and channel bot tokens live in the Keychain. The database stores only an opaque reference (credential_ref, account_binding_digest) plus non-secret metadata.
2. Schema conventions
Every table is written with constraints rather than trusting the caller.
| Convention | Example |
|---|---|
Prefixed identifiers, enforced by GLOB | project_id GLOB 'project_*', turn_id GLOB 'turn_*' |
Enumerations as CHECK constraints | data_policy IN ('local_only','cloud_permitted') |
| Digests as exactly 64 characters | CHECK (length(sha256) = 64) |
| JSON validated on write | CHECK (json_valid(metadata_json)) |
| Millisecond timestamps, ordered | CHECK (updated_at_ms >= created_at_ms) |
| Cross-field consistency | A completed activity must have receipts; a failed one must not |
The last is worth dwelling on. Illegal states are rejected by the database, not just avoided by the code above it.
3. Projects
| Table | Holds |
|---|---|
projects | Name, description, data_policy (local_only or cloud_permitted), instructions up to 32,000 characters, archive timestamp. |
project_documents | Imported files. Format is pdf, xlsx, xls, docx, or csv; up to 8 MB each; SHA-256; extracted markdown up to 256 KB. Unique per (project_id, sha256). |
project_document_chunks | Indexed passages with ordinal, page number, heading, content up to 4 KB, content digest, and precomputed lexical and semantic term sets. |
project_scratchpads | The Notes markdown, up to 256 KB, with a revision counter. |
project_artifacts | Links artifacts to projects, maintained by triggers on artifacts. |
recoverable_project_deletions | Staged deletions with a purge deadline. |
4. Chat
| Table | Holds |
|---|---|
chat_sessions | Title and title source, project, provider and model, context limit (2,048 – 2,000,000). |
chat_messages | Role (user, assistant, system, tool), content up to 1 MB, provider and model, metadata JSON, content digest. |
chat_attachments | Attached files with source path, source identity digest, private copy, media type, extracted text and its digest, and extraction state (complete, truncated, not_text). |
completed_turns | One row per committed turn: request digest, result JSON, result digest. |
accepted_turn_routing | The routing decision for a turn, with its digest. |
recoverable_chat_deletions | Staged deletions with a purge deadline. |
completed_turns and accepted_turn_routing are keyed by turn_id and store a request digest, which is what makes a turn replay-safe.
5. Activity and evidence
activity_records is one row per turn, with a state of queued, routing, running, verifying, completed, failed, or recovery_required.
Its constraint is the interesting part:
- completed requires
receipt_count > 0, anevidence_digest, and no failure category. - failed requires
receipt_count = 0, no evidence digest, and a failure category fromrouting,local_model,cloud_service,native_execution,persistence,setup, orunknown. - Any other state requires no receipts, no evidence, and no failure category.
A turn cannot be recorded as completed without evidence behind it. The database refuses the row.
6. Ledger
| Table | Holds |
|---|---|
model_usage_ledger | One row per turn: execution_kind (local or cloud), provider, model, and input/output token counts. |
Token counts are nullable, but only together: a row cannot have input tokens without output tokens. Where a cloud provider did not return usage, the interface reports it: "{count} cloud responses did not include token totals." It does not estimate.
7. Agents
| Table | Holds |
|---|---|
agents | Name, description, instructions, routing mode, provider and model, favorited, archived. |
agent_profiles | Personality: template, identity, communication style, traits, values, boundaries. |
agent_model_policies | Per-agent context limit (2,048 – 1,000,000) and max output (256 – 8,192). |
agent_mod_policies | Whether the agent uses all enabled Mods. |
agent_mod_bindings | Specific Mod bindings. |
chat_session_agents | Which agent is bound to which chat. |
8. Workflows and schedules
| Table | Holds |
|---|---|
workflows | Name, project, version, state, graph digest, last run. |
workflow_graphs | The compiled graph per version, with its digest, origin turn, decision digest, and capability manifest version. |
workflow_authoring_definitions | The authored definition per version. |
workflow_execution_contexts | The snapshot and envelope a version runs against. |
workflow_instances | Runs, with run_key, state, current step, output, pause reason, and error code. Unique per (workflow_id, workflow_version, run_key). |
workflow_step_runs | Per-step state, effect JSON and digest, arguments and digest, missing fields, and receipt JSON and digest. |
workflow_routines | Schedule JSON, missed-run policy and cap (1–12), required connections, controlled destinations, active flag, next run, and a lease token with expiry. |
workflow_routine_occurrences | One row per scheduled slot, unique per (routine_id, scheduled_for_ms). |
schedules | Source and normalized expression, and kind (cron or interval). |
schedule_runs | Result state and notification state per occurrence. |
recoverable_workflow_deletions | Staged deletions with a purge deadline. |
The uniqueness constraint on (routine_id, scheduled_for_ms) is what makes scheduled execution exactly-once across restarts. The lease token is what stops two processes claiming the same routine.
workflow_instances references workflow_graphs with ON DELETE RESTRICT: a graph version with runs against it cannot be deleted, so history never dangles.
9. Documents produced
| Table | Holds |
|---|---|
artifacts | Kind, display name, canonical path, byte length, SHA-256, and verification state (verified, missing, changed). |
artifact_inspections | Page, sheet, slide, and formula counts; preview key, digest, byte length, and dimensions; renderer identifier and its SHA-256. |
artifact_inspections deliberately holds no filesystem path. The preview is addressed by content key, so a preview record cannot leak where a file lives.
10. Connections
| Table | Holds |
|---|---|
connections | The unified view. Kind is apple, mcp, connector, or channel; state is configured, connected, degraded, expired, unavailable, or disconnected. |
remote_connections · remote_operations · remote_oauth_attempts | OAuth connectors and their cataloged operations. |
remote_channel_accounts | Telegram or Discord accounts, with a credential_ref of the form channel-secret:* and an account binding digest. Unique per (provider, account_binding_digest). |
remote_channel_destinations | Verified destinations per account. |
local_mcp_servers | Executables you selected, with per-tool read-only flags. |
mcp_setup_manifests · mcp_setup_connections · mcp_setup_secret_bindings · mcp_setup_secret_cleanup_obligations · mcp_setup_operations | Manifest-configured MCP connections. |
mcp_setup_secret_cleanup_obligations exists so that a secret whose connection is removed is recorded as needing removal from the Keychain, and cannot be forgotten because the delete happened between two failures.
11. Models and providers
| Table | Holds |
|---|---|
local_models | Display name, architecture, canonical path, byte length, SHA-256, device, inode, and modification time, and default flag. |
cloud_model_connections | Provider, verified model, and an account digest. |
custom_cloud_providers | Display name, origin, endpoint path, and model IDs. |
remote_model_catalog | A signed catalog snapshot with version, ETag, and a 128-character signature. |
Recording device, inode, and modification time alongside the hash means OOMU can tell a model file that moved from one that was replaced.
12. Mods
| Table | Holds |
|---|---|
installed_mods | Name, description, version, author, category, enabled flag, integrity state (verified, invalid, missing), package digest, declared capability IDs, and declared endpoint hosts. |
installed_mod_packages | Installed root, entry point, canonical manifest JSON, trust state, file count, byte count. |
Trust state and integrity state are separate columns because they answer different questions: who signed it, and do the files still match.
13. Memory and profile
| Table | Holds |
|---|---|
internal_memory_records | Content up to 16,000 characters, scope (global or project), and the session, turn, and goal it came from. Forgetting sets four fields together or none. A unique partial index prevents duplicate active memories with the same content in the same scope. |
profile_settings | Display name, locale, appearance (cool, creme, dark, system), cloud permitted, default provider and model. |
profile_personalization | Pronouns, role, background, timezone, languages, expertise, interests, priorities, current projects, context, response guidance, tone, length, formatting, boundaries. |
enterprise_security_settings | air_gap_mode. Seeded on creation. |
daily_briefings | One row per date, keyed YYYY-MM-DD, with the synthesized content. |
Every memory record carries its provenance. A saved fact can always be traced to the turn that produced it.
14. Mutation journal
data_mutations records one row per durable change:
| Column | |
|---|---|
operation_id | Primary key, supplied by the caller. |
operation | What was requested. |
request_digest | SHA-256 of the request. |
entity_kind, entity_id | What changed. |
result_json, result_digest | What the result was. |
committed_at_ms | When. |
This is what makes the bridge idempotent. Replaying an operation_id returns the recorded result rather than repeating the change.
15. What is stored outside the database
| Where | |
|---|---|
| Secrets | macOS Keychain, service ai.eldris.oomu.gpd.beta2.credentials |
| Audit signing key | The Secure Enclave. Non-extractable. |
| Model files | Wherever you chose them, referenced by canonical path and hash |
| Private document and attachment copies | The application data root |
| Effect journal | execution/effect-journal-v1.json in the application data root |
| Artifacts | Where they were written, referenced by canonical path and hash |
Related
- Application Bridge API: the commands that read and write this.
- Privacy & security: the reasoning behind the layout.
- Enterprise security: exporting the audit ledger.