A persistent, queryable, evolving graph of entities, contexts, and relationships. Domain-agnostic. Append-friendly. Idempotent.
A world model is a persistent, queryable, evolving representation of things, the contexts they appear in, and the relationships between them.
This repository documents the architecture in domain-agnostic terms. The same architecture runs across very different domains:
| Domain | Entity | Context | Relationship |
|---|---|---|---|
| Narrative tools | Characters, props, locations | Scenes, snapshots | Appears with, conflicts with |
| News aggregators | Articles, publishers, figures | Stories, topics, hashtags | Cited by, contradicts |
| Knowledge bases | Documents, claims, authors | Topics, citations | Supports, refutes |
| Agent platforms | Tasks, tools, observations | Sessions, world state | Depends on, blocks |
| Games and simulations | Actors, items, regions | Events, ticks | Owns, faction-aligned |
| Product analytics | Users, features, sessions | Cohorts, releases | Used by, derived from |
| CRM and sales | Companies, contacts, deals | Quarters, signals | Reports to, won by |
| Scientific bases | Molecules, papers, experiments | Studies, citations | Cites, builds on |
| IoT and monitoring | Devices, streams, incidents | Regions, time windows | Located at, triggered by |
| Compliance and risk | Entities, transactions, alerts | Lists, periods | Sanctioned by, related to |
If your product needs to remember things, reason about them, and display them, this architecture applies.
A canonical store for the entities, contexts, and relationships your agents need to share. Idempotent ingest, stable IDs, schema-versioned storage, derived views that can be rebuilt from the log, and an operator surface for inspecting and repairing the model.
That's the mechanics. The reason it matters is bigger.
Most AI systems today are amnesiac. They re-discover the same accounts, the same characters, the same world every conversation. Memory is per-session; understanding is shallow; nothing accumulates. You can scale parameters all you want — without a shared world, the system never becomes situated in anything.
World Model is the substrate for agents that know where they are. A persistent, queryable, evolving picture of the world the system operates in — the people in it, the histories they carry, the relationships they hold, the situations they're inside. Once that exists, agents stop guessing and start reasoning from grounded state. Continuity replaces context-stuffing. Identity replaces inference. Behavior gets uncannier — not because the model got smarter, but because for the first time it has somewhere to stand.
That's the unlock. The mechanics are how you build it. The world is what you get.
This repo is the implementation spec, not a runtime library. You can download the AGENTS.md alone. Or clone the repo, open it in your coding agent, and let AGENTS.md guide the build into your stack.
gh repo clone meterless/world-model
cd world-model
# Open in Claude Code, Cursor, Codex, or any AGENTS.md-aware agentThen prompt your agent: "Implement the World Model engine in this project following AGENTS.md."
The agent will pick your aggregate shape (timeline or stream), help you define entity types, scaffold the pipeline, build the read surface, and wire up the control plane. Architectural reference in /docs.
flowchart LR
A[Raw input<br/>narrative · stream · observation] --> B[Pipeline<br/>derive entities and contexts]
B --> C[Stable Hash IDs<br/>content-derived, not autoincrement]
C --> D[(Canonical Store<br/>versioned schema)]
D --> E[Derived Views<br/>latest-version · canonical merged · sparklines]
D --> F[Read Surface<br/>queries · projections · context builders]
D --> G[Enrichment Pipelines<br/>per entity, bounded blast radius]
F --> H[Downstream<br/>UI · ranking · retrieval · generation]
D --> I[Control Plane<br/>operator UI]
The store is the source of truth. Every derived view can be rebuilt. Failures in one entity's enrichment do not poison the rest of the world.
Most production world models are one of these or a hybrid.
World
├─ id, name
├─ snapshots: Snapshot[]
│ ├─ timestamp
│ ├─ context (config, location, scene)
│ └─ entities: Entity[]
Suits narrative tools, simulations, agent traces, game state. Each snapshot is a complete view. Entities exist within the snapshot.
World
├─ id, name
├─ stream: Observation[]
├─ aggregates: Aggregate[] // stories, topics, incidents
└─ canonical_entities: Entity[]
Suits research, news, monitoring, intelligence. A stream of incoming items is clustered into higher-order aggregates. Canonical entities are recomputed from the stream.
Pick the one that matches how your domain accumulates state.
Every ingest path runs the same ordered steps:
- Normalize input. Canonical text, language, timestamps, source provenance.
- Derive entities. Type, name, attributes, candidate IDs.
- Resolve to canonical IDs. Hash-based, deterministic.
- Append observation. New snapshot or stream entry.
- Enrich. Bounded per-entity workers. One failure does not block others.
- Recompute derived views. Latest-version maps, canonical merged entities, sparklines.
Re-running on the same input produces the same world. Idempotent by construction.
Consumers do not query the canonical store directly. They go through a read surface that provides:
- Lookups. Single-entity, single-context, single-relationship.
- Projections. Latest version, merged canonical view, sparkline over time.
- Context builders. Pack entities, contexts, and relationships into prompts or UI views with a token or row budget.
- Provenance. Every read can trace back to the rows that contributed.
Generation, retrieval, ranking, and the UI all call into the same read surface. There is one source of truth and one access pattern.
Append-friendly storage tolerates concurrent writes naturally. The model recommends:
- Single-writer per entity for enrichment, multiple readers anywhere.
- Queue enrichment work. Worker pools per entity type. Backpressure on bursts.
- Eventual consistency on derived views. Reads against the canonical store are strongly consistent. Reads against derived views are typically rebuilt within seconds.
- Schema-versioned storage. Migrations are explicit and inspectable.
A world model needs a control plane, not just an API.
Operators inspect entities, contexts, and relationships. They merge duplicates. They split conflated entities. They mark canonical preferences. They trigger re-enrichment.
The control plane writes back into the canonical store the same way the pipeline does. There is no privileged path.
That is how the model stays trustworthy.
- Idempotent ingestion. Re-run, backfill, repair without duplication.
- Stable cross-process identity. Hash IDs let any worker resolve any entity.
- Bounded blast radius. One bad entity does not break the world.
- Schema versioning. Migrations are inspectable and reversible.
- Provenance. Every derived value traces back to the rows that produced it.
- Portable storage. The same architecture runs client-side on IndexedDB, server-side on Postgres, or distributed across workers and queues.
- Not a graph database. It uses one (or doesn't) underneath.
- Not a vector store. It uses one for enrichment if you want.
- Not domain-specific. Characters and articles and devices use the same shape.
- Not a chat memory. Pair it with H-MEM if you want both.
If you only adopt three things from this repo:
- Hash-based stable IDs. Stop using autoincrement for entities.
- Append-only canonical store. Recomputed derived views. No silent mutations.
- Bounded blast radius on enrichment. One worker per entity. Failures isolated.
Those three principles take a system from "works in demo" to "survives production."
Be honest about the costs:
- Idempotency requires deterministic enrichment. LLM calls inside the pipeline must be re-runnable or cached.
- Derived views can lag. Reads against them are eventually consistent. Plan for that in your UI.
- Hash IDs need name normalization. Get casing, whitespace, and diacritics right, or you create silent duplicates.
- Append-only stores grow. Plan retention policies per entity type up front.
See docs/trade-offs.md.
Implement as composable services or one binary. The contracts are the same:
IngestPipelinefor normalize, derive, resolve, appendEntityResolverfor stable ID generation and dedupEnrichmentWorkersper entity type, bounded blast radiusDerivedViewBuilderfor projections and materialized viewsReadSurfacefor queries, projections, context buildersControlPlanefor operator actionsMigrationServicefor schema versioning
Open an issue with the domain and the aggregate shape before opening a PR. For new entity resolution heuristics, include the test corpus you used to validate (especially edge cases on naming and diacritics).
See CONTRIBUTING.md.
MIT. Use it. Fork it. Ship it.


