Files
obsidian-vault/wiki/personal-os-schema.md
T

4.0 KiB

source, content_hash, namespace, last_synced, confidence, tags
source content_hash namespace last_synced confidence tags
raw/schema.sql 71b47e47b483834c887de14c76d5b16506d90ad64198d76a92a7b3731132dab8 work 2026-04-27 0.9
schema
postgres
database
asana
wiki

Personal OS Database Schema

Postgres schema (personal_os) backing the Asana mirror, agent annotations, file ingestion pipeline, semantic wiki, and memory store. Requires the vector (pgvector) and pg_trgm extensions. Bootstrap with psql -U admin -d personal_os -f schema.sql.

Asana mirror

  • tasks — one row per Asana task GID, upserted on each sync. Stores due/start dates, completion, My Tasks section, assignee/creator, primary project, timestamps, full raw_json, plus a source enum: my_tasks (assigned to me) > delegated (I created, others assigned)

    following (CC'd) > project (project member, fallback). Sync bookkeeping: fetched_at, stories_fetched_before cursor.

  • stories — raw event log per task, keyed by Asana story GID. resource_subtype covers comments, assignment changes, due-date edits, section moves, dependency edits, attachments, completion, etc.
  • task_edges — directed graph between tasks. relation_type: subtask, dependency (blocked-by), dependent (blocking), project_sibling, mention (referenced in a story). related_gid may not yet exist in tasks.
  • task_annotations — agent or user notes per (task, annotation_type). Types: irrelevant, watching, needs_action, snoozed (with snoozed_until). Never written by the fetcher.
  • sync_state — one row per sync stream (my_tasks, following, delegated, project:{gid}, workspace_events). Tracks cursor, last sync, last full sync.
  • task_embeddings — pgvector(1024) per task, HNSW index with cosine ops; populated separately from sync.

The active_tasks view filters out completed and irrelevant tasks and tasks snoozed past today, ordered by source priority then due date then modified-at. Starting point for daily review.

Phase 0 additions (2026-04-27)

All core tables gain namespace TEXT NOT NULL DEFAULT 'work' so a single DB can serve work/personal/family contexts. tasks also gets possibly_deleted and last_seen_in_full_sync to track tasks that disappear between full syncs without explicit deletion events.

File ingestion → wiki

  • file_references — files (via macOS security-scoped bookmark_data + cached last_known_path) and web URLs queued for wiki ingestion. Tracks content_hash (SHA256), mime_type, tags, a modification_log JSONB, and a wiki_stale flag the wiki-ingest-process consumes. Namespace-checked (work/personal/family).
  • wiki_pages — LLM-synthesised markdown, never a raw copy. Has sources JSONB (file_ref/url/title), confidence float, superseded_by self-FK for version chains, stale flag, last_synced_hash, and a pgvector(1536) embedding for semantic search. The optional ivfflat index is left commented; rebuild once the table has 1000+ rows.

Memory store

memory_store — semantic memory from Discord, Claude sessions, and manual entries. type ∈ {fact, preference, decision, person}, source ∈ {discord, claude, manual}, with entities JSONB, confidence, optional expires_at (null = permanent), and a pgvector(1536) embedding. Used by Hermes for cross-session context.

Indexing notes

  • Trigram GIN on tasks.name enables fuzzy task search.
  • tasks_due_on is partial (only non-completed tasks).
  • pgvector embedding indexes for wiki_pages and memory_store are deferred until the tables have meaningful row counts.
  • task_embeddings uses HNSW; the wiki/memory stores use ivfflat (commented) — different recall/build trade-off per workload.

Key constraints

  • All namespace columns are CHECK-constrained to ('work','personal','family') on the new (Phase 0+) tables.
  • Cascade deletes flow from tasksstories, task_edges, task_annotations, task_embeddings.

personal-os-architecture wiki-ingest-process