MeridiansMeridians

Engine pipeline — data · AI · persistence [Flow]

Source path: knowledge-base/diagrams/flows/engine-pipeline.md

# Engine pipeline — data · AI · persistence `[Flow]`

How a change flows from the UI through the deterministic engine and AI, and how state lands in the **canonical record** and mirrors to the browser cache. The load-bearing rule: **the on-disk record is canonical; IndexedDB is a rebuildable projection.**

```mermaid
flowchart TB
    UI(["UI — views · panels · hooks"])
    Store["**Store** — useStore() · AppState · ~110 actions"]

    UI <--> Store
    Store -->|"derive"| Engine["**Deterministic engine** (lib/core)<br/>forces · thread-log · streams · merges ·<br/>graphs · game-theory · curriculum · search"]
    UI -->|"context → prompt"| AI["**AI** (lib/engine)<br/>build → callGenerate → parse/repair"]
    Operator["operatorProfileStore (core)<br/>signed-in member's name + bio"] -->|"&lt;operator&gt; block prepended<br/>by EVERY context builder"| AI
    AI --> Routes["server provider boundaries<br/>modelFor(category) · named budgets"] --> Ext(["fleet-selected inference<br/>research · embeddings · media"])

    Headless(["Program · MCP · Pilot · loops"]) -->|"same queries / actions / ops"| Rec

    Store -->|"optimistic apply,<br/>then persist"| Rec
    subgraph Rec["**CANONICAL RECORD** — master daemon owns it"]
        direction TB
        Mut["/mutate — applyLocalMutation:<br/>gate → reduce → persist → attribute → echo"]
        FS["fs-store — atomic write · version bump"]
        SSE["/stream — SSE echo"]
        Mut --> FS --> SSE
    end
    SSE -->|"use-record-stream:<br/>adopt + saveProjection (echo-suppressed)"| Store
    Store -.->|"shadow-write<br/>(debounced)"| IDB[("IndexedDB<br/>rebuildable projection")]
```

**Invariants**

- **One writer.** State changes only through reducer actions; server writes go through `applyLocalMutation` (`gate → reduce → persist → attribute → echo`). Components, ops, loops, and MCP tools are callers, not alternate writers.
- **Record wins.** If record and cache disagree, the record wins. Boot `reconcileRecord` compares by `updatedAt`: cache ahead → **adopt** to fs, record ahead → **hydrate** to cache ([cache-coherence](cache-coherence.md)).
- **The reducer is deterministic**, clock pinned to the caller's `now`, so optimistic and authoritative applies are byte-identical. Headless commits (MCP, the Program) reach the UI through the same SSE echo.
- **Forces are derived from deltas, never authored.** Never re-parse generated prose to recover canonical state.
- **Every LLM call funnels through `callGenerate`** and is logged with its resolved actor/caller; model selection and token budgets come from the fleet profile rather than hardcoded call sites.
- **Every generation context is grounded in the operator's identity.** An ambient `operatorProfileStore` (the third parallel of `identityStore` / `directorMemberStore`) carries the signed-in member's name + self-authored bio — pushed by the client, resolved per-op by the master — and a pure `operatorContextBlock()` prepends one `<operator>` block in every context builder. Zero call-site changes; an empty profile stays silent. This is what stops a first-person prompt (a health log) from inventing an author.

**Where it lives:** engine = `lib/core/{forces,graph,program,learning,...}`; AI = `lib/engine/{ai,prompts}`; record = `src/app/api/local/*` + `lib/server/record/`; cache = `lib/client/cache/` + IndexedDB `meridians-instance`. Full store/action detail in [PERSISTENCE.md](../../knowledge/architecture/PERSISTENCE.md).
Open on GitHub

Raw Markdown source