MeridiansMeridians

Architecture — runtime boundaries, canonical state, and the one-writer model

From the Meridians Wiki · Public · Maintained · joint

Who this is for. A developer used to a backend/frontend split landing in this repo and asking "where's the server, where's the client, where's the database, and why is it shaped like this?" This is the map. It complements — doesn't replace — the specialized docs: API_PRINCIPLES.md (the reducer + tiers), PERSISTENCE.md (the store linkage + replication layer), and FRONTEND_CONVENTION.md (UI component names).


1. The three ideas that explain everything

Meridians looks unusual to a backend/frontend developer because it collapses three things most apps keep separate. Internalise these and the layout follows.

Idea 1 — One process is both the frontend AND the backend

There is one Next.js app. Its React tree is the frontend; its app/api/* route handlers are the backend; and a large shared core (the domain model + the reducer + pure derivations) runs in both — the same TypeScript executes in the browser and in the Node server. So "frontend" and "backend" here are runtime roles of one codebase, not separate deployables.

       ┌───────────────────────── one Next.js app ─────────────────────────┐
       │  FRONTEND (browser)            SHARED CORE            BACKEND (Node) │
       │  React components   ◀────────  domain model  ────────▶  api/ routes  │
       │  hooks · view state            the REDUCER              record + ops  │
       └────────────────────────────────────────────────────────────────────┘

Idea 2 — The reducer is the single writer of state

State changes only by dispatching a reducer Action through one deterministic write path. Not a component, not a service, not an operation — everything is a caller of that one door. This is what makes the system trustworthy: one place to reason about "how did state get here," one place to gate authority, one deterministic replay. (Full treatment: API_PRINCIPLES.md.)

Because the reducer is pure and clock-injected, the same action produces a byte-identical result in the browser (optimistic) and on the server (authoritative) — which is what lets the two stay in lockstep without a merge.

Idea 3 — Two data stores, one is canon, the other is a rebuildable projection

There is no per-user database on a server. Instead:

StoreWhatRole
The record — a folder on disk (.meridians-local/record/…), JSON + assetsThe source of truth (canon). Versioned, inspectable, the thing the daemon owns.write here, then read follows
IndexedDB — the browser's local DBA projection (cache) rebuilt from the record. Fast reads; never a co-authority.disposable, reconstructable

The rule (the projection model): the file advances before the cache. A write hits the record first (version bump), then the cache follows via an echo. If the two ever disagree, the record wins and the cache is re-derived. IndexedDB holding derived indexes (embeddings) that aren't in the record is fine — those are rebuildable by re-deriving.

Idea 4 — What the record holds is a maintained opinion, in three layers

The mechanics above (one process, one writer, one canon) exist to keep something alive: a domain artifact's opinion, carried across three time horizons over the three measured forces (System / World / Fate). This is the belief spine the whole app renders and steers:

LayerHorizonForceWhat it holds
ThreadslongFatesettled opinion about broad-world outcome questions
Streamspresent (memory)Worldevidence-driven priors that drive action + record model changes now
Positionsthe live read of where the world is heading (foresight)Fatea self-updating, priced Reading grounded in a Reasoning Graph, re-pricing as evidence lands

Their sum is the expert's opinion — what has settled · what to do now · where the world is heading. Keeping them distinct is the point; the record never collapses them into one score.

The ProgramResearch → Opinion → Merge → Position — is the daily maintainer that keeps all three current: it re-reads the world, moves open Streams, surfaces material belief movement, folds judgment into canon (a Merge), and re-prices active Positions (surfacing where the read moved for the user's review). It runs on a cadence (manual or autopilot) and emits Feeds — editorial, timestamped records of the expert and how its opinion evolved, consumable by other people. A Position repositions on evidence and stays live as long as its question is live; the read itself is never marked true or false and carries no Brier or resolve-at-close. What is graded is the committed consequence, and across many Positions the engine's Calibration. That historical verification direction no longer has an active mechanics specification and does not define the product. Current identity and migration state live in PIVOT.md. The value that survives is the maintained, inspectable, versioned model and the record it accrued. (The belief vocabulary is owned by LANGUAGE.md.)