4. The layer map — src/lib/ is role-first
From the Meridians Wiki · Public · Maintained · joint
src/lib/ is organised into four role buckets, so "is this browser-safe? does it serve the
record?" is answered by the path. Import as @/lib/<role>/<folder>. The UI above it has its own
three-tier stack (shell → features → ui); both stacks and the lint-enforced import matrix are owned by
STRUCTURE.md.
🔵 lib/core/ — SHARED: the reducer + pure derivations (runs browser AND node)
| Path | Role |
|---|---|
core/reducer/ | The central reducer — the single writer. actions.ts (the Action union), domain-reducer/ + app-reducer/ (the pure reducers), reducer-core, initial-state, domain-registry. |
core/forces/ core/graph/ core/game-theory/ core/pacing/ core/futures/ core/search/ core/map/ core/analysis/ core/learning/ core/economics/ | Pure derivations over the domain model — no IO, no React. |
core/program/ core/position/ | The Program's pure half — cadence/loop logic, constellation program composition, Position schedule presets and re-price math. |
core/access/ | The can permission lattice, action-policy, identity. |
core/io/ | Import/export (epub, package, graph/scene/belief). |
core/kernel/ | Low-level infra (api-logger, api-headers, system-logger, key-store, resolve-api-key). |
core/constants/ | The constant registry, split by concern (ai-models, ai-pricing, generation, forces, time, …). |
core/{ai-profiles,model-resolver,merges,onboarding,tutoring,…}.ts · core/utils/ | Shared modules + helpers. |
../../types/domain/ | The domain model — DomainState, split per slice. Kept at @/types/domain (the conventional types location). |
🟢 lib/server/ — BACKEND: Node-only, serves the record (never in the browser bundle)
| Path | Role |
|---|---|
server/record/ | The record + projection layer. fs-store (read/write the canonical files), mutation (applyLocalMutation — the one write path), server (route helpers + the local-only gate), record-events/record-client/record-mirror (the change stream + client write-through), reconcile/catch-up (keep the cache honest). |
server/ops/ | The service / API-surface layer. Tier-0 queries, Tier-2 operation handlers, the command bus. What the /api/local/{query,op,mutate} routes call. |
server/program/ | The Program's scheduler + run infrastructure — what fires Research, Opinion, Merge, and Position on a cadence. |
server/sync/ · server/tunnel-manager.ts | Master↔client replication (broker, protocol, tunnel, roles). |
server/gateway/ | The control-plane boundary — Supabase session, directors, entitlements, Stripe, instance + device registries. Gateway build only. |
server/deployment/ | Route policy for the instance/gateway deployment split (GATEWAY.md 🔒 §10). |
🟣 lib/engine/ — the AI generation layer (provider calls + prompts; browser or node)
| Path | Role |
|---|---|
engine/ai/ | Every LLM call + the generation pipeline (scenes, prose, world, graphs, variables, surveys, review, …). |
engine/prompts/ | All prompt text + output schemas, scoped by domain. |
engine/extraction/ | Text → domain pipeline. |
engine/research/ | The living-loop engine (firecrawl, ingest, ticker, constellation runs). Feeds Streams (research) and Position Signals (monitor) off one fanout. |
engine/program/ | The Program's generative stages — Opinion selection, Tutor proposals, Position composition. |
engine/audio/ · engine/image/ | The non-text providers (speech, cover/entity imagery). |
Two evidence boundaries, one engine. A Public Domain is prepared from an explicit research scenario and current, cited web evidence. A Private Domain is prepared from context a Director deliberately supplies through an interview and is not sent through public-web research. Both use the same record, reducer, extraction pipeline, and Program. Public Domains are maintained by Research cycles; Private Domains return to the Director through scheduled Reminders into Notes. Passive private tracking remains product direction and is not implied by the Private boundary.
🟠 lib/client/ — FRONTEND-only (React, IndexedDB)
| Path | Role |
|---|---|
client/store/ | The renderer's binding to the reducer — store.tsx (the useStore hook), contexts/, hooks/. |
client/cache/ | IndexedDB — db/idb/persistence (the projection cache), asset-manager, encryption (at-rest). |
client/ops/ | The browser's transport to Tier-0 queries and Tier-2 operations — how UI reaches server capability without importing lib/server. |
client/game/ | The Scenario live-game state machine (browser-master reducer). |
client/program/ · client/gateway/ · client/voice/ | Client-side Program bindings, the gateway session client, and the dictation surface. |
../../ui/ · ../../features/ · ../../shell/ · ../../hooks/ · ../../app/ | React UI (three composition tiers), hooks, Next routes. |
The AI provider routes (
app/api/ai/generate,/embeddings,/firecrawl, …) are adapters, not the provider implementation or record control-plane. Shared provider services live underengine/; browser/remote callers reach them through the HTTP adapters, while the generic operation runner binds typed direct capabilities throughengine/ai/runtime.tsfor MCP, scheduled, and other headless work. Per-call metering stays in engine callers; provider-service diagnostics stay server-side. Engine code must never introduce a privatefetch("/api/…")path.