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

116 lines
4.8 KiB
Markdown

---
source: raw/schema.sql
content_hash: 71b47e47b483834c887de14c76d5b16506d90ad64198d76a92a7b3731132dab8
namespace: work
last_synced: 2026-05-30
confidence: 0.9
tags: [personal-os, postgres, schema, asana]
---
# Personal OS — Postgres Schema
The Personal OS Postgres database holds Asana sync state, agent annotations,
file references for wiki ingest, the LLM-synthesised wiki, and a semantic
memory store. Extensions required: `vector` (pgvector) and `pg_trgm`.
## Core Asana tables
### `tasks`
One row per Asana task GID; upserted on every sync. Tracks identity, due
dates, completion, assignee, project, and a `source` enum that records how
the task was discovered:
- `my_tasks` — assigned to me, lives in a My Tasks section
- `following` — I'm a follower (commented, CC'd)
- `delegated` — I created it, someone else owns it
- `project` — visible via a project I'm on, none of the above
Bookkeeping columns: `fetched_at`, `stories_fetched_before` (cursor used so
we only pull new stories), `raw_json` (fallback for unmodeled fields).
Indexes cover `modified_at`, `due_on` (partial — incomplete only),
`assignee_gid`, `source`, `completed`, and a trigram index on `name` for
fuzzy match.
### `stories`
Raw Asana event log per task. The key resource subtypes are
`comment_added`, `assigned`, `due_date_changed`, `section_changed`,
`dependency_added`, `attachment_added`, `marked_complete`. Both plain text
and raw HTML are stored — HTML is needed to extract embedded task GIDs.
### `task_edges`
Directed graph of relationships between tasks. `relation_type` covers
`subtask`, `dependency` (blocked by), `dependent` (blocking), `project_sibling`,
and `mention` (referenced inside a story). `related_gid` may not yet
exist in `tasks`, so it's not a FK.
### `task_annotations`
Agent-written notes about tasks. `annotation_type` is one of `irrelevant`,
`watching`, `needs_action`, `snoozed`. `annotated_by` is `agent` or `user`.
### `sync_state`
One row per logical sync stream (`my_tasks`, `following`, `delegated`,
`project:{gid}`, `workspace_events`). Stores `cursor` (ISO timestamp or
events `sync_token`) and `full_sync_at` so partial syncs can fall back to
a full pull when needed.
### `task_embeddings`
1024-dim Voyage embedding per task, indexed via HNSW with cosine ops.
### `active_tasks` view
Convenience view: non-completed tasks that aren't annotated `irrelevant`
or currently snoozed. Ordered by source priority (my_tasks → delegated →
following → project), then `due_on`, then `modified_at`.
## Phase 0 additions (April 2026)
All core tables gained a `namespace TEXT NOT NULL DEFAULT 'work'` column —
the three allowed values are `work`, `personal`, `family`. Applied via
ALTER TABLE; documented as commented-out statements at the bottom of the
file for fresh installs.
`tasks` also gained `possibly_deleted BOOLEAN` and `last_seen_in_full_sync
TIMESTAMPTZ` — used by `generate-status.js` to filter out tasks that have
disappeared from Asana between full syncs.
## Wiki + file ingest tables
### `file_references`
Tracks files and URLs that should be ingested into the wiki. Holds a macOS
security-scoped `bookmark_data` BYTEA, `last_known_path` (resolved
cache), optional `url`, `content_hash` (SHA256), `mime_type`, `title`, and
a `modification_log` JSONB of `{ts, hash_before, hash_after}` entries.
The `wiki_stale` flag drives whether the wiki-ingest prompt processes the
file on its next run.
### `wiki_pages`
LLM-synthesised wiki content (not raw copies). Columns: `namespace`,
`title`, `content` (markdown), `sources` JSONB pointing back at
`file_references`, `confidence`, `superseded_by` (chains old versions),
`stale`, `last_synced_hash`, and a 1536-dim `embedding`. Tagged for
ivfflat index but the index is held off until the table has 1000+ rows
for usable recall.
> Note: per Decision 8 in [[personal-os-state-2026-04-27]], the live
> Personal OS no longer uses these DB tables for wiki ingest — the vault
> is the source of truth and SHA256 lives in frontmatter. The tables
> remain in the schema for compatibility / future re-use.
### `memory_store`
Semantic memory accumulated from Discord, Claude sessions, and manual
entries. `type` ∈ {`fact`, `preference`, `decision`, `person`}; `source`
{`discord`, `claude`, `manual`}. Includes `entities` JSONB, `confidence`,
`embedding` (1536), and an optional `expires_at` (NULL = permanent).
## Key Points
- All namespaces gated to `work | personal | family` via CHECK constraints.
- pgvector embeddings live on three tables: `task_embeddings`, `wiki_pages`,
`memory_store`. Only `task_embeddings` ships with an HNSW index;
the wiki/memory ivfflat indexes are commented out until data volume
justifies them.
- The `active_tasks` view is the canonical "what should I look at" surface
for agents.
## Related
[[personal-os-state-2026-04-27]] [[personal-os-catchup-plan-2026-04-27]]
[[wiki-ingest-process]] [[ddg-asana-workflow]]