Building a World Model
Most AI systems can read the world. Few can remember it.
They parse language. They embed text. They generate responses. Neural world models go further — they learn to simulate how the world evolves under actions, anticipating futures from petabytes of sensor data. But when the question is "Where was that entity 30 seconds ago? What does the sensor data say? How confident are we, and which instrument produced that reading?" — prediction is not the answer. Persistence is.
The AI infrastructure stack has a missing middle tier. Foundation models handle language and perception. Neural world models handle generative prediction. But the layer where actual world state persists — spatially precise, temporally versioned, confidence-scored — has no standard infrastructure. That gap is a database problem.
An operational world model is the solution: a persistent, queryable store of what actually happened — what entities exist, where they are, how they relate, how confident we are in each fact, and how all of this has evolved over time. Neural world models write their predictions into it (_observation_class: 'predicted'). Sensors write observations. ArcFlow remembers everything, queryable at any sequence checkpoint.
This guide builds one from scratch. By the end you'll have:
- 20 entities in 3D space, with velocities and epistemic states
- Spatial proximity and frustum queries (ArcFlow Spatial Index backed, ≥ 2000/s)
- Temporal memory — query the world at any previous moment
- Confidence-filtered decision making
- Graph algorithms over the world structure
- Live monitoring — standing queries keep the model always current
This is the foundation for robotics perception, autonomous fleets, digital twins, game AI, and any system that needs to act on a continuously updated model of its environment.
1. Entities in space#
Space is not a column. A longitude/latitude pair stored as a float is not spatial infrastructure — it's a number. Spatial infrastructure means the database understands position natively: indexes it with a spatial tree, answers proximity queries without full scans, and composes distance predicates with graph traversal in a single query.
In ArcFlow, every entity has a position. The _observation_class field records the epistemic status of the entity — how it was detected and how much to trust it.
-- Observed entities: directly detected by sensors
CREATE (d1:Entity {
name: 'Drone-Alpha',
type: 'aerial',
x: 34.2, y: 67.1, z: 12.0,
vx: 2.1, vy: -0.8, vz: 0.0,
energy: 87.5,
_observation_class: 'observed',
_confidence: 0.97
})
CREATE (d2:Entity {
name: 'Drone-Beta',
type: 'aerial',
x: 41.0, y: 52.3, z: 15.5,
vx: -1.3, vy: 2.0, vz: -0.5,
energy: 62.0,
_observation_class: 'observed',
_confidence: 0.94
})
CREATE (v1:Entity {
name: 'Rover-01',
type: 'ground',
x: 20.0, y: 30.0, z: 0.0,
vx: 1.5, vy: 0.3, vz: 0.0,
energy: 94.0,
_observation_class: 'observed',
_confidence: 0.99
})
CREATE (v2:Entity {
name: 'Rover-02',
type: 'ground',
x: 55.0, y: 70.0, z: 0.0,
vx: -0.5, vy: 1.2, vz: 0.0,
energy: 45.0,
_observation_class: 'observed',
_confidence: 0.98
})
-- Predicted entity: inferred from radar, not directly visible
CREATE (u1:Entity {
name: 'Unknown-Contact',
type: 'unknown',
x: 80.0, y: 90.0, z: 5.0,
vx: 0.0, vy: 0.0, vz: 0.0,
energy: -1,
_observation_class: 'predicted',
_confidence: 0.35
})Three epistemic states — not binary true/false, but a spectrum that maps to operational decisions:
| State | Meaning | Operational consequence |
|---|---|---|
observed | Directly measured — sensor contact, confirmed event | Trust it. Act on it. |
inferred | Derived from observed facts by reasoning | Verify before high-stakes action. |
predicted | Model output, statistical projection | Plan around it. Do not rely on it alone. |
The unknown contact has _confidence: 0.35. That number matters. Safety systems need thresholds, not flags.
2. Relationships — the structure of the world#
Physical reality is relational. Entities communicate, belong to formations, are detected by instruments, occupy zones, and interact along paths. A world model that stores only entity properties misses the structure that makes reasoning possible.
ArcFlow stores relationships as first-class objects with their own properties, direction, and confidence. The detection edge carries provenance: which sensor, what range, what confidence, when.
-- Communication topology
CREATE (d1)-[:COMMS_WITH {latency_ms: 12, signal_strength: 0.95}]->(d2)
CREATE (d1)-[:COMMS_WITH {latency_ms: 45, signal_strength: 0.72}]->(v1)
-- Formation structure
CREATE (f:Formation {name: 'Alpha-Squad', pattern: 'diamond'})
CREATE (d1)-[:MEMBER_OF {position: 'lead'}]->(f)
CREATE (d2)-[:MEMBER_OF {position: 'wing'}]->(f)
CREATE (v1)-[:MEMBER_OF {position: 'tail'}]->(f)
-- Sensor detection edge — provenance built in
CREATE (d1)-[:DETECTS {
confidence: 0.35,
sensor: 'radar',
range: 120.0,
at: timestamp()
}]->(u1)The detection edge is not a log entry. It is a first-class fact in the graph — queryable, traversable, confidence-filtered. When you ask "which sensor detected this contact and with what certainty?", the answer is already in the model.
3. Querying space#
Once entities exist in space, proximity becomes a native query — not a computed join, not a spatial extension, not an external GIS call.
-- K-nearest: 5 entities closest to a point (ArcFlow Spatial Index backed, ≥ 2000/s at 11K entities)
CALL algo.nearestNodes(point({x: 40.0, y: 60.0}), 'Entity', 5)
YIELD node, distance
RETURN node.name, node.type, distance
ORDER BY distance
-- Radius: all entities within 30 units
MATCH (e:Entity)
WHERE distance(e.position, point({x: 40.0, y: 60.0})) < 30.0
RETURN e.name, e.type, e.x, e.y
-- Bounding box
MATCH (e:Entity)
WHERE e.x >= 20 AND e.x <= 60
AND e.y >= 40 AND e.y <= 80
RETURN e.name, e.typeSpatial predicates compose with graph traversal in the same query:
-- Entities within 50 units of the origin AND in Alpha-Squad
CALL algo.nearestNodes(point({x: 0, y: 0}), 'Entity', 20)
YIELD node AS e, distance
WHERE distance < 50
MATCH (e)-[:MEMBER_OF]->(f:Formation {name: 'Alpha-Squad'})
RETURN e.name, distance, f.patternA query that combines spatial proximity, graph structure, and property filters — in a single statement, hitting a single system. No joins across databases. No pipeline between spatial and relational stores.
4. Time — the world remembers#
A world model that forgets is not a world model. It is a current-state cache.
Every mutation in ArcFlow is versioned. The graph at any previous point in time is fully queryable — not from an audit log or a separate history table, but from the same graph, the same query language, with AS OF seq N.
-- Advance the world: update positions by one time step
MATCH (e:Entity)
SET e.x = e.x + e.vx,
e.y = e.y + e.vy,
e.z = e.z + e.vzNow query the past:
-- Where was Drone-Alpha at the previous sequence checkpoint?
MATCH (d:Entity {name: 'Drone-Alpha'}) AS OF seq 100
RETURN d.x, d.y, d.z
-- Replay the entire world at a recent sequence checkpoint
MATCH (e:Entity) AS OF seq 2000
RETURN e.name, e.x, e.y, e.z, e._observation_class
-- Reconstruct the world at the moment of an incident
MATCH (e:Entity) AS OF seq 4821
RETURN e.name, e.type, e.x, e.y, e._observation_class, e._confidenceIncident reconstruction is a real operational requirement: something happened, you need to know exactly what the world looked like at that moment. Not approximate state inferred from logs — exact state, same query language, from the same graph.
5. Confidence — what you know versus what you believe#
Not all knowledge is equal. The unknown contact has a _confidence of 0.35. Drone-Alpha's position is _confidence: 0.97. These are not decorative metadata — they are operational filters.
-- Trusted entities only: high-confidence, directly observed
MATCH (e:Entity)
WHERE e._observation_class = 'observed'
AND e._confidence > 0.85
RETURN e.name, e.type, e.x, e.y
-- Only high-confidence detection edges
MATCH (a)-[r:DETECTS]->(b)
WHERE r.confidence >= 0.7
RETURN a.name, b.name, r.confidence, r.sensor
-- Flag low-confidence predictions for verification
MATCH ()-[r:DETECTS]->(contact:Entity)
WHERE contact._observation_class = 'predicted'
AND r.confidence < 0.5
RETURN contact.name, r.sensor, r.confidence
ORDER BY r.confidence ASC
-- Confidence-weighted centrality: most trusted entities rank highest
CALL algo.confidencePageRank()
YIELD nodeId, score
RETURN nodeId, score ORDER BY score DESC LIMIT 10As more sensors detect the unknown contact and confidence rises above the threshold, it automatically enters trusted result sets. No application logic. No polling. The model maintains this.
6. Structure the world doesn't show you#
Individual entity properties tell you what something is. Graph algorithms tell you where it sits in the world's structure: which entities are critical to communication, whether the fleet is cohesive or fragmented, what the shortest path through the navigable network is.
-- Which entities are most central to the communication network?
CALL algo.pageRank()
YIELD nodeId, score
RETURN nodeId, score ORDER BY score DESC LIMIT 5
-- Is the fleet in one connected piece, or fragmented?
CALL algo.connectedComponents()
YIELD componentId, nodeCount
ORDER BY nodeCount DESC
-- How tightly clustered is the formation?
CALL algo.clusteringCoefficient()
YIELD nodeId, coefficient
-- Shortest communication path between two entities
MATCH p = shortestPath(
(a:Entity {name: 'Drone-Alpha'}),
(b:Entity {name: 'Rover-02'})
)
RETURN length(p), nodes(p)A fleet that appears healthy in individual status checks may have a fragmented communication graph. A formation that looks cohesive in position data may have a low clustering coefficient. These are structural facts about the world that only graph algorithms can surface.
7. Live monitoring — the world is always current#
Polling is not a world model. It is a sampling strategy — and it introduces latency proportional to the polling interval.
LIVE MATCH inverts this: declare what you care about, and the model maintains the answer continuously. You receive the delta the moment the graph changes.
import { open } from 'arcflow'
const db = open('./data/world-model')
// Emergency: any observed entity within 5 units (fires on every mutation that changes the result)
const safetyMonitor = db.subscribe(
`CALL algo.nearestNodes(point({x: 0, y: 0}), 'Entity', 10)
YIELD node AS e, distance
WHERE distance < 5.0
AND e._observation_class = 'observed'
AND e._confidence > 0.8
RETURN e.name, e.type, distance`,
(event) => {
if (event.added.length > 0) {
triggerEmergencyStop(event.added[0].get('e.name'))
}
}
)
// Track new predicted contacts — schedule verification
const contactMonitor = db.subscribe(
`MATCH ()-[r:DETECTS]->(contact:Entity)
WHERE contact._observation_class = 'predicted'
AND r.confidence < 0.5
RETURN contact.name, r.sensor, r.confidence`,
(event) => {
for (const row of event.added) {
scheduleVerification({
entity: row.get('contact.name'),
sensor: row.get('r.sensor'),
confidence: row.get('r.confidence')
})
}
}
)
// Live view: fleet health maintained continuously (zero-cost reads)
db.mutate(`
CREATE LIVE VIEW fleet_health AS
MATCH (e:Entity)
WHERE e._observation_class = 'observed'
RETURN e.name, e.type, e.energy, e._confidence
ORDER BY e.energy ASC
`)
const health = db.query("MATCH (row) FROM VIEW fleet_health RETURN row")The standing queries fire on every relevant mutation. The live view is maintained incrementally — reads are free. No scheduler, no polling loop, no batch job.
8. Semantic search across the world#
Add embeddings to entities for semantic search — find by what something means, not just what its properties say. Useful when entities have descriptions, behavioral histories, or text-derived features.
CREATE VECTOR INDEX entity_embeddings
ON :Entity(embedding)
DIMENSIONS 128
SIMILARITY cosine
-- Add embedding (from your model)
MATCH (e:Entity {name: 'Drone-Alpha'})
SET e.embedding = [0.12, -0.34, 0.56, ...]
-- Find entities semantically similar to a description
CALL algo.vectorSearch('entity_embeddings', 3, queryVector)
YIELD node, score
RETURN node.name, node.type, scoreVector search composes with all other query types — filter by label, confidence, observation class, then rank by similarity.
9. USD scene export and physics queries#
For world models representing USD stages (USD-based simulators, simulation platforms, game engines, digital twin platforms), ArcFlow exports and queries using USD semantics directly:
-- Export the world model as USD ASCII
CALL arcflow.scene.toUsda() YIELD usda
-- Resolve a USD prim path to a graph node
CALL arcflow.scene.primId('/World/Drones/Drone-Alpha') YIELD prim_path, prim_id
-- Frustum query — what does this camera see?
CALL arcflow.scene.frustumQuery(0, 0, 15, 0, 1, 0, 90, 1, 200)
YIELD node_id, label, x, y, z
-- Line-of-sight between two nodes
CALL arcflow.scene.lineOfSight(drone_id, rover_id)
YIELD has_los, note
-- Collision contacts from physics simulation
CALL arcflow.scene.collisions(rover_id)
YIELD from_id, to_id, impulse, at_time
-- Neighborhood in a node's local coordinate space
CALL arcflow.scene.queryInLocalSpace(drone_id, 50.0)
YIELD node_id, local_x, local_y, local_zThe compound effect#
Each capability above is useful on its own. The compound effect is what makes a world model different from a database.
-- A query no other single system can answer:
-- In the last 10 seconds, which high-confidence observed entities
-- were within 30 units of the formation lead — but are now gone?
MATCH (lead:Entity {name: 'Drone-Alpha'}) AS OF seq 4800
CALL algo.nearestNodes(point({x: lead.x, y: lead.y}), 'Entity', 20)
YIELD node AS e_past, distance AS d_past
WHERE d_past < 30.0
AND e_past._observation_class = 'observed'
AND e_past._confidence > 0.85
WITH e_past
MATCH (e_current:Entity {name: e_past.name})
WHERE NOT EXISTS {
CALL algo.nearestNodes(point({x: 0, y: 0}), 'Entity', 20)
YIELD node AS nearby, distance
WHERE nearby.name = e_current.name AND distance < 30.0
}
RETURN e_past.name, e_past.type, e_past.x AS x_then, e_past.y AS y_thenSpatial + temporal + confidence + graph traversal — in a single GQL statement. The alternative is writing a join across four systems with no consistency guarantee between them.
What you've built#
| Capability | What it gives you |
|---|---|
| Spatial entities (ArcFlow Spatial Index) | Proximity queries at ≥ 2000/s — no external spatial system |
| Three epistemic states | Operational trust levels — not boolean, not decorative |
| Confidence scores | Safety thresholds that compose with any query |
| Sensor provenance | Every edge knows its source, range, and time |
| Temporal memory | Replay any past state — AS OF seq N on the same graph |
| Standing live queries | Zero-latency notification — no polling, no scheduler |
| Live materialized views | Fleet health at zero read cost, maintained incrementally |
| Graph algorithms | Network structure visible, not just entity properties |
| Vector search | Semantic similarity composing with everything else |
| USD integration | The world model IS the scene graph — export or query natively |
This is the infrastructure layer the AI stack has been missing. Foundation models handle language. Vector databases handle similarity. ArcFlow handles what the world is, was, and will be — with spatial precision measured in coordinates, temporal fidelity measured in sequence numbers, and epistemic honesty tracked on every fact.
Next steps#
- Autonomous Systems — robot fleets and UAV coordination on a shared world model
- Digital Twins — live spatial replicas of physical facilities
- Robotics & Perception — sensor fusion pipeline and ROS integration
- Live Queries — standing queries and live views in depth
- Temporal Queries —
AS OF seq Nand temporal comparison - Spatial Queries — ArcFlow Spatial Index, frustum, line-of-sight reference
- Confidence & Provenance — scoring and tracing every fact