Files
lore-engine/CONTEXT.md
Kaysser Kayyali 288ad4cb69 docs(slice 11): plan doc + ADR 0010 + CONTEXT cross-ref
* docs/plan/11-slice-mcp-http-docker.md: slice plan with AC + test
  plan, mirroring the 11 existing plan docs.
* docs/adr/0010-streamable-http-transport.md: captures Streamable
  HTTP vs legacy HTTP+SSE, Starlette vs FastAPI/mcp-lib, stateless
  v1 (no Mcp-Session-Id), one-shot JSON as common case, append to
  requirements vs split, baked graph + mount override.
* CONTEXT.md: new 'Transports' section under Operations documenting
  the transport-agnostic dispatcher + stdio + Streamable HTTP.
2026-06-18 14:32:22 -04:00

4.8 KiB
Raw Permalink Blame History

Lore Engine

A reasoning substrate for a high-fantasy world. Its single product: when an LLM asks a question about the world, it gets a precise, time-bound, contradiction-checked answer traceable to the document it came from. Built on Cognee (the substrate); the Lore Engine is the domain layer on top.

Language

Entities & structure

Lineage: A blood relationship — descent from a founding ancestor. A person has at most one Lineage. Avoid: family, house (a house is a Faction, not a Lineage)

Faction: An association — a House, Order, or Guild. A person can belong to many Factions over time. Avoid: house (when meaning blood — that's Lineage)

Region: A geographic concept — a continent, kingdom, forest, dungeon. Exists inside a Plane. PART_OF between Regions means "geographically contains." Avoid: plane (a plane is not geographic)

Plane: A mode of existence — Material, Shadow, Voldramir, the Feywild. Plane-relation edges (REFLECTS, LAYER_OF, ADJACENT_TO, ACCESSIBLE_VIA) are between Planes. Avoid: region, world

Setting: A top-level namespace — a campaign or world. Hosts one or more Planes. The v1.2 replacement for the flat world_id string. Avoid: world, world_id (deprecated)

LoreSource: A document ingested into the engine (prose, timeline YAML, dialogue log). Carries a reliability and is the unit of source attribution.

Confidence & conflict

extraction_confidence: Did we extract this triple correctly? A per-triple score (0.01.0) from the LLM extractor.

source_confidence: How reliable is the document a triple came from? Derived from LoreSource.reliability (canonical 1.0 → fanon 0.3).

aggregate_confidence: The floor — min(extraction_confidence × source_confidence) across every source on an edge. Not a mean or max. (ADR 0001.) Avoid: confidence (unqualified — say which dimension)

Disputed edge: When two sources produce the same (subject, relation, object) with conflicting time bounds. Kept as separate Relation records, both marked is_disputed: true, linked via disputed_with — not merged. (ADR 0002.)

Relation: A reified-edge node — the representation for any edge that carries time bounds or confidence (RULED, MEMBER_OF, PARTICIPATED_IN, …). Carries valid_from/valid_until/extraction_confidence/source_confidence/is_disputed/superseded_by. Native edges (Cognee field-nesting) are used only for structural edges that never need time (is_type, template-wiring). Promoted from v1.1 to v1 (ADR 0009).

Contradiction: A first-class node flagging incompatible claims between LoreSources. Built from scratch in slice 2 — Cognee ships no contradiction machinery.

Time

at_time / as_of: at_time scopes a query to an in-world moment. as_of scopes it to a retcon boundary — what the world-builder knew on a given date, before a retcon.

Retcon: A declared revision that supersedes — never deletes — an old fact. Old edges are marked superseded_by; both pre- and post-retcon states stay answerable.

Operations

ConsistencyRun: A record of one execution of the consistency engine (started_at, rules_run, violations_found). The LLM checks latest_run() before answering historical questions.

Cognee: The substrate — the MIT-licensed framework that owns extraction, embedding, and the remember/recall/forget API. Pinned at v1.1.2 (ADR 0006). Graph backend pinned to Neo4j, overriding Cognee's Kuzu default (ADR 0008).

Transports

MCP (Model Context Protocol): The wire protocol clients use to talk to the server. We implement MCP 2024-11-05 over two transports:

  • stdio (slice 2.6) — JSON-RPC 2.0 over stdin/stdout, stdlib only. Entry: scripts/05_mcp_server.py. Used by Claude Desktop, Continue, Cline, and any stdio-native MCP client.
  • Streamable HTTP (slice 11, ADR 0010) — single POST /mcp endpoint. The response body is either application/json (one-shot, the common case) or text/event-stream (SSE-upgraded via the client's Accept header). Entry: scripts/06_mcp_http_server.py. Container: lore-engine-mcp (Dockerfile + docker-compose.yml).

The dispatcher in lore_engine_poc.mcp_server.MCPServer is transport-agnostic — both transports are thin adapters over handle_message(msg) -> Optional[dict]. The 36-tool registry (TOOL_REGISTRY in mcp_tools.py) is shared verbatim between them.

Avoid list (global)

  • world_id — use setting_id.
  • "inherited from GraphMCP-Example" — the prior substrate; no longer used. Cognee is the substrate. GraphMCP-Example appears only in historical comparisons ("the original design," "cheaper than the prior stack").
  • confidence (unqualified) — say extraction_confidence, source_confidence, or aggregate_confidence.