Skip to content

Trace records

designed · Phase 1 (#31) · PLAN §13.5, §10.1, §4.2

Every record carries tick, phase and an ordinal within the tick (resolution order). Sources are system:<name>, rule:<id>, player:<id>.

Record Fields Indexed by
IntentApplied ordinal, source, intent { type, target, key, value \| delta \| edge \| component }, inputs?, generation (the write's new generation), events[] (ids produced) ordinal; (node, attribute, generation); entity; source; time
IntentRejected as above + reason same
IntentConflict as above + rival (ordinal of the winner) same
Decision actor, winner: Option, runnersUp: Option[≤3], weights { family → factor } actor; time; need
Event id = (tick << 20) \| ordinal, type, source, location, data, producedBy (intent ordinal) id; entity (source and any node in data); type; time
Propagation ordinal, source, channel, hops[] { node, intensity } source node; time
NodeDestroyed ordinal, node, kind, template, name, components[] node
PlayerAction player, action (the queued JSON), ordinals[] (the intents it became) player; time
RuleFired (Phase 3) rule, trigger { node, attribute, generation } rule
OracleCall (Phase 5) requestType, oracleLogId, prompt (gap or dilemma) actor
TickDigest digest — stable hash over the tick's applied intents in order tick

Option as recorded: { actor, action, target, need, score, reason, inputs { "kira.hunger": 72, "kira.perceived_danger": 0.8 }, publisher }.

Storage format (warm)

One JSON object per line, one segment file per tick range: saves/{universeId}/trace/{from}-{to}.jsonl with a sidecar {from}-{to}.index.json listing the ids, entities, change keys and time range in the segment. Segments are append-only; the hot buffer rebuilds from the newest on load.

Prose rendering (viewer)

Each record kind has a prose template on the client, which is where engine vocabulary turns into words: a Decision → "{name} {verb} because {reason}"; an IntentApplied with inputs from FireSystem → "{target} caught fire because {source}'s heat crossed {ignition_point}"; a PlayerAction → "…was {verb} by you, on the {world time}". The trace itself carries no prose beyond Reason.