Start Here

Personal Systems Platform

A backend for personal productivity apps—todos, budgets, fitness tracking—built on shared foundations where components compose and extend each other without tight coupling.

PSP System Architecture
01

Three Principles

  1. 01
    Identity is shared

    Person and Group entities live in a central kernel, so every component knows who owns what

  2. 02
    Domains are isolated

    Todos doesn't import from Budget; they communicate through events and hooks

  3. 03
    Composition replaces duplication

    Cross-cutting concerns live in platform primitives, not copied into each component

02

The Layers

System Architecture
%%{init: {"flowchart": {"useMaxWidth": false}}}%% graph TB APP["Application Layer
(Todos, Budget, Fitness)"] PLATFORM["Platform Primitives
(Clock, EventBus, Hooks)"] IDENTITY["Identity Kernel
(Person, Group)"] APP -->|owner_id| IDENTITY APP -->|uses| PLATFORM style APP fill:#ecfeff,stroke:#0891b2 style PLATFORM fill:#fef3c7,stroke:#d97706 style IDENTITY fill:#f3e8ff,stroke:#9333ea

What to notice: Components in the Application layer reference the Identity kernel through owner_id—a UUID that points to either a Person or Group. Platform primitives provide shared infrastructure: time, messaging, authorization, extensibility.

03

Non-Goals

PSP is deliberately constrained:

  • Not a monolith

    Components cannot share database tables or import each other's models

  • No cross-component joins

    You cannot JOIN tasks with budget_plans; use events and local projections instead

  • Eventual consistency by design

    Components react to events asynchronously—this is a feature, not a bug

04

Interaction Patterns

When components need to work together, choose the right mechanism:

Pattern When to Use Example
Hooks Synchronous interception, veto/patch, policy-like checks Budget vetoes task completion
Events Async side effects, fan-out, audit trails Recurrence triggers on TaskCompleted
Policies Authorization/permission centralization OwnerOnly policy on delete
Queries Discovery, export, reporting GDPR data export by owner_id

Full decision guide with anti-patterns →

05

Where to Go