Story pipeline — events → a legible feed [Flow]
From the Meridians Wiki · Public · Maintained · joint
Every Program task (program-loop) emits a canonical DomainProgramEvent. Turning those into an expert-forward feed is a pure pipeline: registry → editorial → projection → surfaces. Stories are a projection, never a second source of truth.
flowchart TB
Event["**DomainProgramEvent**<br/>kind · artifactRefs · salience · summary"]
Event --> Reg["**Registry** — STORY_KIND_REGISTRY<br/>channel · mode · queueClass · title · consequence"]
subgraph Ed["Editorial — two layers"]
direction TB
Floor["**voice floor** (deterministic)<br/>every kind gets a real headline"]
AI["**AI craft** (best-effort)<br/>verbatim quotes or dropped whole"]
Floor --> AI
end
Reg --> Floor
subgraph Proj["Projection — pure + deterministic"]
direction TB
Order["projectStories<br/>order: class → salience → time"]
Dedup["dedupStoryQueue<br/>collapse echoes"]
Readout["resolveStoryReadout<br/>sparklines · check dots · diffs"]
Order --> Dedup --> Readout
end
AI --> Order
Readout --> Surf(["Surfaces — StoryReader · Timeline · Deck<br/>+ mobile Stories bars"])
Surf -->|"act card → stage a Directive<br/>reminder → answer in place<br/>mark-read → caught-up"| Human(["the human judges"])
Invariants
- The registry is the single source of per-kind facts.
STORY_KIND_REGISTRY(exhaustive overProgramEventKind) fixes each kind's channel, mode, queueClass, title eyebrow, and consequence class;storyChannel/storyTitleread from it. Channels ≠ tasks: 4 tasks, but 7 channels (reminder · research · monitor · opinion · tutor · project · canon). - Editorial guarantees a voice. The core floor (
VOICE_REGISTER) means every card has a real headline at birth. The AI pass verifies quotes verbatim against source markdown and is dropped whole if nothing survives (the card keeps its floor). Only Research / Opinion / Merge get AI enrichment; Position cards carry the floor. - Projection is pure. One projection + one receipt hook (
useProgramStories) feed every surface, so ordering / filtering / read-tracking can't drift between desktop and mobile. Cards segment into Act (pending decisions, importance-ranked) and Read (the broadcast, grouped by run); read receipts are per-member and durable.
Where it lives: lib/core/program/stories/ (registry · projection · dedup · readout · channels), lib/core/program/editorial/voice-floors.ts (floor), lib/server/program/editorial-orchestration.ts + lib/engine/program/editorial.ts (AI), features/program/ + shell/mobile/ (surfaces).
Not yet shipped: durable ProgramJournals (audit beyond the rolling caps) and the newsletter delivery layer.