Skip to content

Project lifeos data spine

FINAL ARCHITECTURE (decided 2026-06-15, supersedes interim-tool notes below)

  • Surface = custom build, workspace.justinsforge.com. Justin is building the legit app himself (like finances.justinsforge.com), NOT adopting Directus/NocoDB. He explicitly rejected interim/ride-on tools and learning curves on software that won't be kept. Do NOT recommend Directus/NocoDB again as primary surface or admin backend.
  • Multi-tenancy = workspaces. One app with a workspace switcher (Notion-style). Workspaces: Personal, Nova, JustinWieb (single-user, his) + Gus Outdoor, Gus The Bass, Sip-N-Serve (multi-user). Michael scoped to Gus workspaces, Kristine to Sip.
  • Owner god-view: Justin is a member of EVERY workspace with an owner role that bypasses workspace scoping (sees all, like a Notion workspace owner). Others are scoped to theirs.
  • Permissions: Justin owns this himself. Foundation: Cloudflare Access (front door, already runs it) + Postgres Row-Level Security (enforces workspace walls at the DB level). Model is one workspace_id per row + a memberships table (user x workspace x role).
  • Build-vs-adopt rule (Justin's): build it yourself UNLESS an outside authority dictates the structure. Tasks/habits/docs/projects/CRM/customers = build. Books/tax = adopt (ERPNext stays), because tax law is the outside authority. AI lowers build cost but NOT the cost of being wrong on tax.
  • Personal finance: finances.justinsforge.com already won; Firefly III/Actual Budget are own-copy downgrades, never adopt them, only steal features (e.g. auto-categorization rules).
  • Working method for custom build: Justin supplies the product opinions (he knows Notion well enough); Claude surfaces each product fork + how mature tools chose and why (as rationale reference, not adoption), Justin decides, Claude builds.

Decision reached 2026-06-15: build forge-data LXC hosting one lifeos Postgres + pgvector. All structured life data lives there in domain schemas: finance, commerce, tasks, fitness, health, food, home, content, contacts. Existing finance.db, datalayer.db, context.db migrate in as first drawers. Redis sits beside for scratch/caching. Words (notes, docs, memory/*.md) stay in Git/AppFlowy. ERPNext stays as accounting engine and feeds the spine rather than being replaced by it. Notion gets demoted to optional window, eventually retired once a self-hosted UI (Directus or NocoDB for rows, AppFlowy for notes) proves out.

Phasing logged in memory/daily/2026-06-15.md: 1. Stand up forge-data + Postgres + pgvector, offsite backup first 2. Migrate finance.db (lowest risk) 3. Move LifeOS off Notion-direct; brain writes Postgres, n8n proxy retires 4. Move /recall onto pgvector 5. UI bake-off: Directus/NocoDB/Grist for rows, AppFlowy/Anytype for notes 6. Cut Notion sync once replacement proves out

Inventory journal for Justin to fill: memory/plans/lifeos-data-inventory-journal-2026-06-15.md + Drive doc.

Why: Notion is rented storage with a limited API and brittle property-name contracts. finance.db/datalayer.db/context.db are already local-first but siloed and can't cross-reference. One Postgres makes all life data cross-queryable (fitness vs food vs finance vs tasks).

How to apply: Before designing any new data storage for tasks/habits/fitness/food/contacts, assume it lands in the lifeos Postgres. Check if the spine plan has moved forward before building new SQLite files.

[auto-memory session e6a507d7-a10a-468c-812b-333c77bb093a, confidence 0.85, mode direct]


Auto-memory addendum 2026-06-15T13:18:22.619786

Justin decided (2026-06-15) to build forge-data, a dedicated LXC running Postgres + pgvector, as the canonical data spine for all structured life data under the database name lifeos.

Decision: One Postgres, one backup, one connection for AI. Domains are organized as schemas: finance, tasks, fitness, food, home, commerce, inbox, contacts. Existing SQLite files (finance.db, datalayer.db, context.db) migrate in as first drawers.

ERPNext relationship: ERPNext stays as the books/tax engine, fed from the spine via the existing forge_erpnext_daily_post.py posting engine. ERPNext is a downstream copy, never the source of truth.

Notion: Demoted to an optional view. Tasks, habits, inbox, projects migrate off Notion-direct writes once the spine + a ride-on UI (Directus or NocoDB) proves out.

Tool split: - Ride-on tools (Directus/NocoDB) for domains with no outside authority (tasks, habits, contacts, food) - Custom apps (like finances.justinsforge.com) for domains Justin cares about deeply - ERPNext stays for accounting (tax law = outside authority, don't rebuild) - Sharing via Cloudflare Access + Directus/NocoDB built-in roles; no Notion needed

Words vs rows boundary: AppFlowy or Anytype for notes/docs; Postgres spine only for row data.

Why: Justin has been building toward this for months (finance.db, datalayer.db, context.db are three partial implementations of the same instinct). Postgres unifies them and enables cross-domain queries that no SaaS can answer.

How to apply: When building any new structured data store, default to the lifeos Postgres spine rather than a new SQLite file or Notion DB. Check forge/data/finance/COORDINATION.md before touching finance schema. The data inventory journal lives at memory/plans/lifeos-data-inventory-journal-2026-06-15.md and in Drive.

[auto-memory session e6a507d7-a10a-468c-812b-333c77bb093a, confidence 0.85]