MeridiansMeridians

Forces — deterministic derivations [Concept]

From the Meridians Wiki · Public · Maintained · joint

Half of what an expert "knows" is never stored. Forces are pure, stateless computations recovered on read from the domain's deltas — the inverse of generation. Storing them would create a second source of truth that drifts from the spine, so the domain computes them every time instead.

flowchart TB
    subgraph Stored["STORED — the canonical spine (deltas)"]
        direction LR
        Sc["scenes"] & En["entities"] & Th["threads"] & St["streams"] & Br["branches"]
    end

    Stored -->|"pure derivation<br/>(no I/O, no clock, no randomness)"| Forces

    subgraph Forces["DERIVED — src/lib/core/forces/ (recovered on read)"]
        direction TB
        F1["**attribution** — lift entity/thread ids from structural fields"]
        F2["**branch-resolution** — version + entry lineage across forks"]
        F3["**stream-stance** — softmax stance · logit updates · category"]
        F4["**thread-market** — multi-agent valences · narrator price · volatility"]
        F5["**thread-log** — narrative primitives → logit mapping"]
        F6["**force-grading** — five-force measures → pentad sign"]
        F7["**positions · time-deltas** — cumulative from relationship deltas"]
    end

    Forces --> Read(["UI · Program · MCP<br/>all read the same derived values"])

Invariants

  • Never authored, always recovered. A force is a function of the deltas, not a field on the record. If you find yourself writing a force value into state, you have created a drift bug — the spine is the only source.
  • Pure by construction. No network, no IndexedDB, no LLM, no Date.now(), no Math.random() — time is injected. This is what makes forces trivially unit-testable (vitest, no mocks) and byte-identical between optimistic and authoritative applies.
  • Deterministic dependency order. Forces read the spine; a few read each other (thread market reads stances and log nodes; branch resolution feeds timeline selection; maturity reads stream stance). The order is fixed and acyclic — no force reads a stored derivation.
  • The reducer is the writer; forces are the reader. State changes only through reducer actions (engine-pipeline); forces observe the result. The two never cross.

Where it lives: src/lib/core/forces/ (attribution · branch-resolution · stream-stance · thread-market · thread-category · thread-log · thread-alluvial · force-grading · positions · time-deltas · domain-utils), src/lib/core/graph/ (network · entity-tree · scene-filter), src/lib/core/merging.ts (stream maturity). Grounds the domain-spine; the craft discipline is owned by the testable-backend skill.