Life OS
A system for running a life, with two surfaces over one data model: a private application where everything is recorded, and this public site. A fact is written once and appears wherever it belongs — the portfolio you are reading is not a copy of a résumé, it is the same records rendered for a different reader.
The design rests on one decision. There is a single entities table with tags, links and events beside it, rather than a schema for each feature. A module is a type registered against that spine — it declares its own shape and its own rules, and inherits routing, visibility, search indexing, publishing and the weekly review from having declared them. That is what makes cost-per-wear, a backlink between two unrelated modules, and the weekly roll-up a query rather than an impossibility. It is also what keeps the thirty-eighth module as cheap as the second.
The two surfaces are two separate Postgres databases, and the separation is the point. The private one is the source of truth. The public one holds only what an explicit owner action promoted into it, and this site holds no credential that reaches the private database — so a mistake in a visibility filter here cannot expose a private record, because the record is not in the database being queried. Publication is deliberately not automatable: no agent, webhook or scheduled job can perform it. It is enforced in the grants rather than in code — service_role has no SELECT on entities at all.
The rules the system is not allowed to break are written as tests rather than as intentions. Events are append-only, enforced by row-level security for the application and by a trigger for anything privileged. Unpublishing purges rather than hides. A module marked never-public is refused at three separate layers, one of them a trigger inside the public database itself. And a snapshot alone has to be able to rebuild a working instance — which was not taken on trust: it was executed live in September 2026 into a scratch project created for the drill and deleted afterwards.
What does not exist yet is as much a part of an honest description as what does. Lenses — named curations over the spine — can be planned and published by the core library, and no screen anywhere calls either function, so the only publishing possible today is one record at a time. The public pages fall back to reading the store directly because of it. That gap is the next thing.
Built with
- TypeScript
- Next.js
- React
- Tailwind CSS
- PostgreSQL
- Supabase
- Row Level Security
- Zod
- Vitest
- Model Context Protocol
- WebGL
- Vercel