MeridiansMeridians

The pentad in the app — measurement, surfaces, post-hoc actions, roadmap

From the Meridians Wiki · Public · Maintained · human-contract

Status: step 3 shipped. Flags and composition diagnostics are shipped as derived projections; PostHoc settings, MDL-based Acting growth, debt reads, κ analytics, and the Maintain surface are built. Acting growth runs at the generation seams in the arc, world, futures, game, and program-merge operations, deliberately not during extraction or creation. This document is the argument and the sequence for shifting the UI, generation, and measurement of Meridians around the pentad. Every "today" cell below was verified against the code at the paths cited; every "plan" cell is proposal. Where a formula is given it is a shipped calculation or an explicitly labelled diagnostic. The reader-first white paper's claim — discover what your choice changed — is what this plan exists to make true in the product.

Grounding: src/lib/core/forces/domain-utils.ts (raw forces, snapshots, activity), force-grading.ts, theme-analysis.ts, thread-log.ts, thread-market.ts; the UI consumers ScorecardPill, ForceAnalytics, ForceTimeline, DomainReport, ArcDetail/SceneDetail, ThreadDetail, BranchGraphView; settings in src/types/domain/settings.ts and DomainSettingsModal; spatial ops in src/lib/server/ops/catalog.ts; Acting in EntityUnderstandingPanel.


1. Activity is not the world; it is the visible part of it

Today the engine measures activity: five raw per-scene quantities over the pentad, each rank-Gaussian normalised, then combined —

Fate_i   = Σ_threads v_t · D_KL(p⁺ ‖ p⁻)         belief moved on Threads this scene touched
World_i  = ΔN + √ΔE                              entities and edges added
System_i = Σ_rules −log p(topic)                 surprisal of newly binding rules
Theme_i  = Σ_signals |Δ salience|                 Theme movement in this Scene
Causality_i = Σ_flags w(stakes)·ln(1 + alternatives)  choice-space removed in this Scene
A_i      = Σ_c w_c · F_c,i                         the five-force activity curve

Every one of these is a per-scene increment: what this scene added to the record. That is exactly why they are the visible forces — a scene can be scored on its own. Theme is graded from structure breadth × depth over valid leaf slots, while recurrence (attention softmax over salience, entropy, coverage, grounding) remains a diagnostic across the whole selected prefix. Causality is graded from native Flag information against the prose-length density expectation for the selected interval.

The five channels are visible in activity, while their grade and diagnostics retain distinct currencies. Theme recurrence, Causality reach, and Fate's open mass remain longitudinal readings beside the scene-level curve. A reader can therefore see both what moved at a Scene and what that movement meant across the record.

So the measurement programme has two halves:

HalfForcesKind of numberToday
ActivityWorld, System, Fate, Theme, Causalityper-scene increment, rank-Gaussian normalisedshipped
CompositionTheme recurrence, Causality reach, Fate open massrelation over the record at a vantageshipped as diagnostics

The same five channels feed ForceSnapshot, Activity, and Signature. The scorecard still keeps grade currencies and longitudinal diagnostics legible rather than collapsing them into one number.

Flag. Causality now contributes a scene-local Flag information series to Activity and Signature, while its Flag-information grade and H_open / reach remain longitudinal diagnostics. Theme contributes its canonical signal-point series in the same way, while Theme recurrence and structure realisation remain available beside it. Extraction and generation are five-force.


2. Candidate formulas for the invisible forces

All three are computed at a vantage (branch, entry) over the resolved entry prefix, like scoreThemeSystem already is. None writes state. Each has a falsifier so it can be rejected.

2.1 Fate as weight (open mass)

H_open(v) = Σ_{Threads open at v} u_t · H(p_t(v))       u_t = log(1 + volume_t), H = Shannon entropy

What it says: how much unresolved, evidenced uncertainty the world carries right now. It falls when a question collapses and rises when a scene opens one. Reads: Thread.closeEntryId, Stance logits via stanceAsOf (thread-market.ts). Falsifier: if H_open does not drop at scenes readers name as resolutions, the weighting is wrong. Volume decay also lowers H_open during quiet stretches, so the closure-attributable drop (Σ collapse) is the discriminating quantity.

This is the number the current Fate increment cannot give: a scene of enormous belief movement (high Fate_i) may leave the world more certain (low H_open) — a payoff — or less — a twist that adds outcomes. Today the two are conflated in one line on the chart.

2.2 Theme as recurrence

Θ_i = Σ_{signals s in scene i} |Δsalience_s| · log(1 + n_θ(s), i)        n_θ = prior scenes carrying Theme θ

What it says: a Theme's first appearance is worth nothing to the force (it is not yet a pattern); each recurrence is worth more. This is recurrence, not development or growth: |Δsalience| counts rising and falling signals alike, and the logarithmic count is frequency-weighted. The total is length-dependent, so it should not be naively compared across Domains of different lengths. This is the rule that makes Theme invisible in a single scene and visible across the record, made numeric. It replaces the flat Σ|Δsalience| scene points that scoreThemeSystem currently caps at 25 rather than replacing them, while keeping attention, entropy, coverage, and grounding as diagnostics. Falsifier: in a Domain with one dominant Theme, Θ must rise monotonically with recurrence; in a Domain whose signals are all singletons, Θ must be ~0 even if salience is high.

2.3 Causality as entropy flow and reach

Causality is the transition structure over Fate: not a scalar force but a graph, with a flow measure attached. Three layers.

  1. A flag is a point event. Fate is a probability vector p_t over a Thread's outcomes, moving scene by scene. A flag is the scene where it stops moving: p⁻ → p⁺ ≈ δ_k, outcome k now fixed on this branch — concretely (thread, scene, k, p⁻, p⁺). World and System are counts of state; Fate is a distribution; a flag is a change of distribution. That is why it is the least visible force: it can only be seen between two scenes, never in one.

  2. Causality is the graph on flags. Edges are dependsOn: flag B needed flag A to be possible — a DAG whose vertices are collapses and whose edges are "A's answer was in the support of B's question". A branch is an assignment of values to a set of questions; two branches with the same rules and cast differ exactly in their flag vector. This branch-as-Flag-vector claim is now a computed comparison surface: diffFlags/diffBranchFlags retain the shared questions, mark divergent rows, and identify the first divergence without adding canonical state. "What can lead to what" is reachability in that DAG: divergent flags are vertices with high out-degree, conditional flags are vertices whose in-degree is what matters.

  3. The measure is a flow of uncertainty. With H_open = Σ_open ln(1+v_t)·H(p_t) the stock of weighted possibility still in play, a collapse is the flow out of it: v_t·(H(p⁻) − H(p⁺)). Fate measures information gained (KL — how far belief moved); Causality measures possibility spent (entropy drop — how much of the open space was closed off). Same currency (nats), different operator: Fate is the derivative of belief, Causality is the divergence of possibility. The flows at a scene must sum exactly to the closure-attributable drop in the stock — that is what makes it a measure rather than a plausible number.

Fate says where the world is leaning; Causality says which leanings became facts, in what order, and what each fact foreclosed. It is invisible per scene by construction because it is a difference operator across scenes — as Theme is an integral across scenes.

Status: layers 1–3 ship as derived projections; dependency edges are derived from the record (co-movement, attribution edges, opens) — a model-refined edge stage remains optional.

For the shipped projection, the scene aggregate and retrospective diagnostic are:

u_t          = log(1 + volume_t)
collapse_f  = u_t · (H(p⁻) − H(p⁺))                at the closure node
C_i         = Σ_{flags f collapsed at i} collapse_f                         atomic Causality at scene i
reach_f(v)  = |{ flags g at or before v : f ∈ dependsOn_g }| + |forecloses_f|  retrospective diagnostic

Here p⁻ is the belief at the previous trajectory node, p⁺ is the belief at the closure node, and H is unnormalised Shannon entropy in natural-log units. collapse_f is the closure-attributable flow of H_open: it is the open Fate mass that closure removed, weighted by the stance volume entering the scene. More outcomes open means more mass; normalizedEntropy is the rejected alternative because it would erase that option-set contribution. A flag that settled a 50/50 counts more than one that confirmed a 95. The dependency term is zero until step 4; the shipped projection is deliberately the direct collapse sum. reach cannot be known when the flag is minted — it is read at a later vantage and is the closest thing the engine will have to this is the choice that mattered. Falsifier: reach should rank the disclosure scene in the paper's worked example above the delegation scene, and both above filler; if hand-labelled turning points do not rise to the top of reach on the Harry Potter benchmark Domain, the dependency extraction is wrong, not the reader.

C_i is the Causality channel in the five-force chart; reach remains a per-flag readout, not a series. ForceSnapshot carries all five rank-normalised channels. The grade uses native Flag information against the prose-length density expectation; signed collapse and reach remain separate diagnostics.

openMassSeries currently replays the resolved prefix once per scene, so its implementation is O(n²) over the timeline.

2.4 The scorecard

World    grade  deduction
System   grade  deduction
Fate     grade  deduction
Theme    grade  deduction  + coverage / competition / grounding diagnostics
Causality grade  deduction + open mass H_open at cursor, top flags by reach
overall  Σ grades (each an anchored logistic of realisation)

Rendered in the order of visibility — World, System, Fate, Theme, Causality — not the current Fate-first order, so the UI teaches the frame every time it is opened.


3. Where the pentad lives in the app

Principle: Causality is shown at the things it connects, not as a fifth blob. A flag is shown at the Thread it collapsed and on the entry where it happened; its dependencies are edges between flags; its reach is a number on the flag. This mirrors how Theme is already shown (purple attribution beside the triad, a tree, a rack of carriers) and avoids a competing canvas cohort.

SurfaceToday (verified)Plan
ScorecardPill (topbar)Fate, World, System, Theme rows; hard-coded coloursFive graded rows in visibility order; H_open at cursor; colours from tokens
ForceAnalytics / ForceTimelineFate/World/System series + Theme + activityadd Θ (replacing flat Theme points) and C_i series; a second "composition" pane: H_open line with flag markers at collapses
ThreadDetailoutcomes, stance, movement, replayFlag block when closed: value, vantage, collapse, dependsOn (linked), opens/forecloses, reach at cursor, nature chips (divergent · conditional · personal)
SceneDetail / ArcDetailforce sign readout, Theme moments"What this scene collapsed" list → flags; "what it depended on"
Inspector: new Thread closures panelbranch's closure ledger in entry order; filter by nature, Thread, seat; click → Thread/entry
Stage: Threads viewlifecycle replay at cursorcollapsed Threads drawn with their flag; dependency edges between collapsed Threads as a faint overlay
BranchGraphView / Branch Chat comparelineage columns, compareBranchIdsBranch diff over Thread closures: shared question set, rows = Threads, cells = collapsed value per branch; differing cells highlighted; "first divergence" marker
DomainReport / slidesforce table, arc gradesfive-force table; a "what led to what" page: top flags by reach with their dependency chains
Extraction job detailWorld/Fate/System/Theme countsa Causality phase card: flags minted, dependency edges, unresolved collapses
Tokens (globals.css)--color-fate/world/system, Theme violet; no fifth slotadd --color-causality + .category-color-causality; migrate the four hard-coded literal sites (report, scorecard, analytics) to tokens in the same change

Colour is an open decision (§7 of the README). The constraint: it must sit beside red/green/blue/violet and read as "between" rather than "another thing" — amber is the obvious candidate; decide on the canvas.


4. Post-hoc actions: settings and the Maintain surface

Today: postHoc persists automatic-maintenance policy for spatial mapping and Acting growth; spatial ops (generate-board-topology, drain-spatial-mapping-debt, rebuild-location-hierarchy) remain manual/MCP with buttons in SpatialSettingsModal. Acting growth is MDL-based (assessActingGrowthmaintainActingGrowth) with keep-evidence, interpret, reinterpret, and hold verdicts. It runs at the arc, world, futures, game, and program-merge generation seams, and deliberately does not run in extraction or creation, matching the acting-maintenance-invariants.test.ts ratchet. Post-hoc bindings are attributable and revisable: selectedBy: "post-hoc" may be maintained, while a Will-selected binding is held and never overwritten.

Step 3 status: shipped — the postHoc settings block, pure spatial/Acting debt read, κ composition analytics, Tier-0 read-post-hoc-debt, Maintain settings section, MDL-based Acting growth from #234 are built. Will bindings are held; post-hoc bindings are attributable to the maintenance pass.

Plan — one settings block and one surface:

// DomainSettings (flat, backward compatible; spatialAutoMaintain migrates in)
postHoc?: {
  spatial:   { autoMaintain: boolean; reorganizeAtBirth: boolean };          // from spatialAutoMaintain
  acting:    { autoMaintain: boolean };                                      // MDL growth; Will binding stays manual
  flags:     { detect: "off" | "on-extraction" | "on-commit"; };             // projection, never a write
  questions: { synthesise: "off" | "on-extraction" | "on-commit"; };         // ranked report, never a write
}

Maintain — a surface (inspector utility panel or Domain menu) that lists every post-hoc operation with its last run, what it read, and a run button, grouped by what it interprets:

Interpretations of System     Rebuild world · Map levels · Drain mapping debt · Maintain Acting growth
Invisible forces              Detect flags (Causality) · Re-score Theme recurrence
Synthesis                     Synthesise questions at cursor

Rules: interpretations and projections may run automatically; binding an Acting read, committing a synthesised question as a Thread, or overriding a detected flag's nature is Will and stays manual and attributable. Each op is an ordinary catalog entry (params, result, commits, engine) so MCP and the Program can call it; the Program's UPDATE_DOMAIN_PROGRAM_CONFIG gains optional post-hoc steps after Merge.


5. Flag detection integrated in extraction and generation

5.1 Extraction — a Causality phase

Insert after Fate re-extraction and Domain assembly (the thread log is priced by then) and before the topic-tree/spatial phases:

phase  Causality (flags)                                   projection-first
read   Threads (outcomes, closeEntryId, closeOutcome), ThreadLogNode{closed, infoGain, preVolume, updates},
       scene threadDeltas/worldDeltas/systemDeltas, attribution edges, branch entry sequence
step 1 deterministic: every closure node → candidate Flag{threadId, outcomeId, vantage, collapse}
step 2 deterministic: derive co-movement, attribution, and opens edges plus transitive reach from
       the record; model citation/refinement remains optional and is not built
emit   Thread closure ledger + dependency edges as a derived extraction artifact keyed by branch

Step 1 needs no model and can ship first; it makes the Flags panel and C_i (without the dependency term) real. Step 2 is the LLM stage and is where "effective extraction of flags from canonical text" lives. Its prompt joins the prompts/core/forces.ts family; the existing "never a fourth causal axis" locks are about Theme and stay.

5.2 Generation — flags as read-only context

generateScenes, scene-response, plan/prose/script generation get a <closures> block at the vantage: collapsed values, their natures, and the open Threads with highest H and reach-weighted dependents. Effect: continuation generation is constrained by what this timeline has already made certain and oriented toward what is load-bearing, which is the concrete meaning of "all five forces integrated into generation." Flags are input only; the reducer's typed deltas remain the only writer.

The ambient force reading is structured so each row remains inspectable at the generation boundary:

<forces read="World→System→Causality→Fate→Theme"
        hint="five forces; read = display order and derivation from the record; couplings = measured per work">
  <force id="World" is="what exists" carries="entities, places, artifacts, knowledge, state"/>
  <force id="System" is="what binds" carries="rules, permissions, institutions, economies"/>
  <force id="Fate" is="what is open" carries="p over each Thread's outcomes"/>
  <force id="Theme" is="what recurs" carries="propositions across scenes"/>
  <force id="Causality" is="Fate settling" carries="Flag = scene where a Thread becomes fact on this branch; forecloses the rest"/>
  <will is="not a force" carries="attributable authority from outside — reader, seat, Director, agent — settles a Thread"/>
  <generation serves="the world's recorded leaning" never="manufacture consequence | settle a Thread canon leaves open | disclose what a lens does not hold"/>
</forces>

Pulse also emits the record-specific Constitution and force-flow evidence:

<constitution source="fitted|unread">
  <coupling from="World" to="System" lag="1" r="0.410" n="20" t="2.31" />
</constitution>
<flow>
  <edge id="lag1:World&gt;System" relation="coupling" lag="1" verdict="readable"
        corr="0.410" pairs="20" t="2.31" />
</flow>

The <constitution> rows are emitted by src/lib/engine/ai/context-pulse.ts from fitted couplings in the current record. Flow IDs use lag1: and lag2:; lag 1 is not a generating ring and lag 2 is not a controlling star. read on the <forces> block is the symbolic display order only, while Constitution and Flow are unconstrained, record-specific measurements. An empty fitted Constitution means the forces read as independent; unread means the record is too short for a readable edge.

Flags make visible how Causality and Fate moved in this record: a settled Thread is the collapse that shapes this scene's branch. Questions make visible the Fate → Theme edge: what hangs on a question is what the scene must make legible. Reader-facing anticipation questions ship as a deterministic projection from settling Flags; they are never model-generated and remain ordinary scene question-bank records with optional provenance.

5.3 Question synthesis operation

synthesise-questions (catalog op, Tier-0): reads the five forces at a vantage; emits ranked open questions with candidates and the forces that make each open. This is a deterministic read: the five forces already carry the answer, and a model layer would only paraphrase it. Output is a report/projection the Director can promote to Threads by an explicit commit. This is distinct from the existing scene question-bank operation, which stays.


6. Roadmap — six steps, each with a falsifier

#StepShipsFalsifier / exit
1Thread closure projection (deterministic) — closure nodes → Thread closure ledger; ThreadDetail closure block; Thread closures panel; --color-causality tokenCausality visible for the first time — shipped (derived; ForceSnapshot unchanged)every closed Thread on a benchmark Domain shows a Thread closure with the right value and entry
2Composition measuresH_open, Θ recurrence, collapse; scorecard in visibility orderTheme and Fate-as-weight numerically distinct from activity — shipped (derived diagnostics; Theme recurrence and entropy flow graded; ForceSnapshot unchanged)§2 falsifiers hold; Theme singleton-Domain ≈ 0
3Post-hoc settings + MaintainpostHoc block, Maintain surface, spatial/Acting/flags/questions ops registeredone place that keeps the interpretations of System current — shipped; MDL Acting growth (#234) runs at the arc/world/futures/game/program-merge generation seams, with post-hoc bindings attributable and Will bindings heldoperators can run and audit every post-hoc op without losing manual authority
4Dependency extraction (deterministic)dependsOn/opens/forecloses/nature; reachCausality as a force that can be understoodshipped (deterministic edges + reach; model refinement optional)hand-labelled turning points rank top by reach
5aCausality alluvial — Thread closure collapse bands in Influenceshipped (projection-only)settled Thread closures render by nature and collapse
5bCausality topic-tree leaves — native Flags plus surviving Thread closures under owning Thread topicsshippedcanonical Flags and legacy Thread closures remain inspectable without duplication
5cCausality extraction tab — assembled-Domain Flag summary and open massshippedcompleted extraction exposes Flags and H_open
5Branch diff over Thread closures — compare view; "first divergence"parallel worlds differ in their Thread closures becomes a screen — shipped (diffClosures, diffBranchClosures, read-closure-diff, and the ThreadsView comparison surface)two benchmark branches diff to exactly the Threads that differ
6Synthesis + generation reads Flagssynthesise-questions; anticipation questions; <closures> context; conditioned questions → script pipeline; Script lens knowledge and descriptive force readingdeterministic synthesis, anticipation questions, and the conditioned generation reads — shipped; the reconfigurable pipeline configuration record in README §4.3 remains unbuiltthe three configurations in README §4.3 run from one config record

Steps 1–2 are pure/core work with vitest coverage and touch no reducer action. Step 3 adds one settings field group, MDL Acting maintenance, catalog entries, and a panel. Steps 4 and 6 add LLM stages behind callGenerate. Step 5 is UI over a pure diffFlags(a, b).


7. Why this is the right path — the case, and how to reject it

  • It builds on what measures well. The original per-scene activity math remains intact for Fate, World, and System while Theme and Causality now join the same five-force aggregate; longitudinal composition diagnostics remain beside it. No existing chart, grade, or test changes meaning.
  • It makes the paper's claim testable. Discover what your choice changed is reach on a flag and a branch diff. If step 4's falsifier fails, the claim fails visibly rather than rhetorically.
  • It respects the writer boundary. Every new quantity is a projection; every new op is interpretation or synthesis; every promotion to canon is an attributable commit.
  • It teaches the frame by use. Visibility order in the scorecard, flags at Threads, dependencies as edges: the UI shows a reader why the invisible forces are invisible — you have to have read the whole record to see them.
  • It is cheap to abandon. Steps 1–3 are worth having even if Causality never earns a grade.

Reject it if: closure nodes are too sparse on real Domains for flags to be interesting (measure on the benchmark set first); or reach and hand-labelled turning points do not agree after one round of prompt work — in which case Causality stays a named, unmeasured force and the paper's Appendix A sentence stands.