4. The layer map — src/lib/ is role-first
Source path: knowledge-base/knowledge/architecture/overview/runtime-roles.md
# 4. The layer map — `src/lib/` is role-first
`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](../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](../../operations/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 under
> `engine/`; browser/remote callers reach them through the HTTP adapters, while the generic
> operation runner binds typed direct capabilities through `engine/ai/runtime.ts` for 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 private `fetch("/api/…")` path.
---
Open on GitHubRaw Markdown source