diff --git a/wiki/personal-os-schema.md b/wiki/personal-os-schema.md new file mode 100644 index 00000000..e55e65db --- /dev/null +++ b/wiki/personal-os-schema.md @@ -0,0 +1,74 @@ +--- +source: raw/schema.sql +content_hash: 71b47e47b483834c887de14c76d5b16506d90ad64198d76a92a7b3731132dab8 +namespace: work +last_synced: 2026-05-29 +confidence: 0.9 +tags: [schema, postgres, personal-os, database] +--- + +# Personal OS — PostgreSQL Schema + +The `personal_os` Postgres database is the durable backbone of Alex's Personal OS. It stores Asana state, agent annotations, file references, wiki content, and semantic memory. Extensions used: `vector` (pgvector) and `pg_trgm`. + +## Core tables + +### `tasks` +One row per Asana task GID. Upserted on every sync. Tracks name, notes (text + html), due/start dates, completion state, section, assignee, creator, project, source, timestamps, sync cursors, and raw JSON. Indexed on modified_at, due_on (partial), section, assignee, source, completed, plus a trigram index on name for fuzzy search. + +**`source` values** — discovery channel: +- `my_tasks` — assigned to Alex, in My Tasks sections +- `following` — Alex is a follower +- `delegated` — Alex created it, someone else owns +- `project` — project membership, otherwise uncovered + +### `stories` +Raw Asana event log per task — comments, assignments, due-date changes, etc. `resource_subtype` is Asana's event type. Stores plain and HTML body (HTML retains embedded task references). Indexed on task_gid, created_at, subtype, creator. + +### `task_edges` +Directed graph of inter-task relationships. `relation_type` covers `subtask`, `dependency`, `dependent`, `project_sibling`, `mention`. Primary key `(task_gid, related_gid, relation_type)`. + +### `task_annotations` +Agent or user-written metadata. Types: `irrelevant`, `watching`, `needs_action`, `snoozed`. Includes reasoning note, snooze date, and `annotated_by` (`agent` | `user`). + +### `sync_state` +One row per logical sync stream (`my_tasks`, `following`, `delegated`, `project:{gid}`, `workspace_events`). Holds last sync time, incremental cursor, and last full-sync time. + +### `task_embeddings` +pgvector 1024-dim embeddings (Voyage AI text-embedding-3 dims). HNSW cosine index. + +## Convenience view + +`active_tasks` — non-completed, non-irrelevant, non-snoozed tasks. Ordered by `source` priority (`my_tasks` → `delegated` → `following` → `project`), then due date, then modified. + +## Wiki / memory tables + +### `file_references` +Sources for wiki ingest. Includes a macOS security-scoped `bookmark_data` BYTEA, cached path, optional URL, SHA256 `content_hash`, MIME, title, tags, JSONB `modification_log`, and `wiki_stale` flag that triggers next ingest run. Namespace constrained to `work`/`personal`/`family`. + +### `wiki_pages` +LLM-synthesized markdown (not verbatim copies). Tracks sources JSONB, `confidence` (default 0.8), `superseded_by` chain for versioning, `stale` flag, `last_synced_hash`, and 1536-dim embedding. ivfflat index recommended once row count > 1000. See [[wiki-ingest-process]] for the current file-based replacement that supersedes this table. + +### `memory_store` +Semantic memory from Discord, Claude sessions, manual entries. `type` ∈ `fact|preference|decision|person`. `source` ∈ `discord|claude|manual`. JSONB entities array, confidence, optional `expires_at` for non-permanent facts, 1536-dim embedding. + +## Phase 0 additions (2026-04-27) + +- `namespace TEXT NOT NULL DEFAULT 'work'` added to all core tables — supports work/personal/family separation. +- `possibly_deleted BOOLEAN` and `last_seen_in_full_sync TIMESTAMPTZ` added to `tasks` so sync can detect Asana deletions. + +## Notes on usage + +- Stories are fetched after `tasks.stories_fetched_before` cursor — incremental. +- `task_annotations` is the only table the agent writes to from inference — `tasks` and `stories` are sync-owned. +- The `wiki_pages` table is effectively superseded by Obsidian + frontmatter `content_hash` (see [[personal-os-state-2026-04-27]] Decision 8). Schema retained for now. + +## Key Points +- Source-of-truth for Asana state is this DB, not the Asana API at query time. +- `source` column on `tasks` drives prioritization in `active_tasks` view. +- `namespace` column enables future Phase 2-family without schema churn. +- pgvector tables are provisioned but not yet populated — Phase 2 work. +- File-references / wiki-pages tables exist but Obsidian vault replaced them in practice. + +## Related +[[personal-os-state-2026-04-27]] [[personal-os-catchup-plan-2026-04-27]] [[wiki-ingest-process]]