Phone:

Hidden from the page source until you click: friction against scrapers, not a guarantee.

Email:

[email protected]

Noema documentation

Snapshots, forks, replay and experiments

Capturing state, branching minds, re-running cognition under a recorded runtime identity, and comparing forks that differ in one thing, including the model.

These four tools share one idea: a mind's state is data that can be captured, branched, re-run and compared. They are what make Noema a place to study cognition rather than merely run it. Since 0.2 every capture and every re-run also records the runtime identity it happened under, so a comparison says up front whether it could have been exact; and an experiment can fork one snapshot into variants that differ in exactly one declared thing, including which model serves each role.

On this page

Snapshots and forks (spec §42)

A snapshot is a JSON archive of a mind's state at a point in its history: identity, personality, configuration, workspace and working memory, drives and affect, goals, beliefs (with evidence, versions, alternatives, links), memories (with relationships), predictions, entities, corrections, policy rules, conversations, and wants, want conflicts, commitments, intentions, plans, plan steps and the volition decision ledger. It records the event sequence number at capture and a SHA-256 checksum. Cognitive events are not copied.

A fork restores a snapshot into a new mind. Every row id is remapped, so the fork never shares mutable rows with its source; references to events keep pointing at the source's immutable history, which is how the past before the fork is shared by reference (forked_from_mind, forked_from_snapshot, snapshot event_seq). After the fork the two minds diverge freely.

Authority is not inherited. A fork receives no policy rules unless the operator asks for them explicitly (inherit_policies, audited), and an import never restores them. Work inherited mid-flight is stopped in the restore transaction: open plan steps are blocked with their approval and request ids cleared, open plans blocked and live intentions suspended. Approvals, grants and executions stay with the source mind.

Compare (/minds/{a}/compare?with={b}, noemactl compare) is deterministic: counts, mean confidence, belief-by-belief differences keyed on the normalised proposition, personality and configuration field diffs, and the event-type mix.

Export / import (spec §43)

Export produces the same archive (kind: noema.mind-archive, version: 1, checksum). Nothing secret is included: provider keys, integration secret references, API tokens and sessions are not mind state and are never in an archive. Import treats the archive as hostile: size cap (32 MiB), unknown top-level fields rejected, allow-listed tables only, row caps, column-name validation, checksum must match, every id remapped, mind_id forced. Text inside an archive is data; a prompt-injection string in a memory is imported as a memory, never executed.

Replay (spec §41)

Replay rebuilds a mind from a snapshot into a disabled sandbox mind, then re-injects the source's recorded stimuli (perception and operator events after the snapshot) one at a time, stepping the real cycle code synchronously until the mind settles. Each step compares the events the source produced after that stimulus with the events the sandbox produced, ignoring bookkeeping types and normalising ids and numbers:

Label Meaning
exact same events, and every model call was served from a recording
approximate a live model call was needed; the recorded response did not match the request hash
diverged no live model call, yet the deterministic code produced different events

Divergence is reported, not hidden. Its usual causes are honest ones: the working memory changed between snapshot and stimulus, retrieval scores depend on wall-clock recency, or the code changed since the recording.

Runtime identity and compatibility

Every snapshot, replay and experiment records the runtime identity it ran under: build (module version, VCS commit, whether the tree was modified, commit time, Go version, OS and architecture), schema version (highest applied migration), a digest of the non-secret configuration (secrets and credentials never enter it; it changes only when behaviour-affecting settings change), the mind's personality version, a digest of the policies in force, the LLM role routing (including per-mind overrides), the current version of every prompt, the versions of the deterministic subsystems whose output is compared, and the timezone.

A replay compares its identity with the snapshot's and labels itself:

Compatibility Meaning
exact-candidate same build, schema, configuration, routing, prompts, policy and subsystem versions: differences can only come from state, timing or a model
different-build the schema matches but something else differs; the differences are listed. Exact steps are still exact; a diverged step may be a code change
incompatible the schema differs. The sandbox could not be a faithful reconstruction, so the replay stops before running rather than produce a misleading comparison

Snapshots taken before identities were recorded are labelled as such.

Divergence analysis

The first non-exact step is analysed: which event digests appear only in the recording, which only in the replay, and which components those events belong to (retrieval, attention, encoding, beliefs, association, predictions, goals, response, narrative, motivation, metacognition, capabilities). Components are inferred from event types and labelled as inferred: they point at where to look, not at a proven cause. Live model calls are named as a component of their own, because provider nondeterminism is a real and measurable source of difference, not one to be hidden.

The replaying router serves recorded responses by request hash (llm_calls.request_hash) and records the replayed call with replayed=true. Replays run under a forbidden capability context; no action can execute.

Cognitive forks per model

An experiment may declare variants: named sets of overrides, each of which becomes its own fork of the same snapshot and receives the same stimuli. A variant can override configuration, personality and, through llm_roles (role → model id), the model used for each role for that fork only; the router honours a mind's own routing and fails closed if the named model is missing or disabled, so a comparison between providers can never silently fall back to the default. Every fork starts from identical cognitive state, which is exactly what makes the model a replaceable service rather than the identity.

The results carry one entry per variant (subject, routing in force, produced-event digests per stimulus, beliefs, memory and goal counts, expectations, model calls, tokens, cost, capability requests, cycles) and a deterministic comparison: the first stimulus at which any two variants produced different event digests, belief-set overlap and mean score difference on shared propositions, attention overlap (selected-thought digests), and the ranges of memory counts, goal counts, cost and capability requests. Every subject mind stays for the two-mind comparison page. With live models the differences include provider nondeterminism, which is measured rather than hidden.

Experiments (spec §57)

An experiment is a snapshot, optional configuration and personality overrides, a stimulus script, expectations, a seed and a duration cap. Running it forks the snapshot into a disabled subject mind, applies overrides, feeds the stimuli and records: events by type, produced-event digests per stimulus, subject beliefs, memory and goal counts, expectation outcomes, model-call counts (live/replayed), the LLM role routing in force, duration and cycles. Results are stored and exportable (/api/v1/experiments/{id}/export includes an archive of the subject). The subject stays for comparison with the baseline.

Different models are compared by changing role routing between runs; the routing in force is recorded in each result.

Research experiments add protocols (global workspace, ablation, self-model, counterfactual, model comparison, conflict), ablations and workspace overrides in forks, self-model overrides, counterfactual replays that omit recorded events, per-variant volition, plan, downstream and introspection measures, and reproducibility against the previous run; see cognitive-research.md. The seed is recorded with every stimulus for provenance; deterministic code needs no seed, and model providers do not honour one reliably.

Operating

  • UI: mind → Snapshots (take, fork, download, compare, import on the minds page), mind → Replay, top-level Experiments.
  • API: /api/v1/minds/{mind}/snapshots, /api/v1/snapshots/{id}[/archive|/fork], /api/v1/minds/{mind}/export, /api/v1/minds/import-archive, /api/v1/minds/{mind}/compare/{other}, /api/v1/minds/{mind}/replays, /api/v1/replays/{id}, /api/v1/experiments[...].
  • CLI: noemactl snapshots, noemactl compare, noemactl replay, noemactl experiments.

Reading a replay

Each step of a replay shows the stimulus, the events the source mind produced after it, and the events the sandbox produced. Digests normalise identifiers and numbers so that two minds' outputs compare. Read the labels as follows:

  • exact: the deterministic code did the same thing and any model calls were served from recordings. This is the common case for perception, retrieval, belief updates and workspace admission.
  • approximate: a model was called live because no recording matched the request hash (a prompt version changed, or the sandbox's state produced a different request). The step is still valid; it is simply not a reproduction.
  • diverged: no live model call, yet the outcome differed. The usual causes are honest: retrieval scoring depends on wall-clock recency, working memory carried something into the original that the snapshot did not, or the code changed since the recording. Divergence is a finding, not a failure.
  • redacted: the stimulus was redacted after the recording; it is skipped and labelled rather than reconstructed.

Above the steps, the replay states its compatibility with the snapshot: an exact candidate ran under the same build, schema, configuration, routing, prompts and policy, so differences can only come from state, timing or a model; a different build lists what differs; an incompatible replay has a different schema and stops before running rather than produce a misleading comparison. The first non-exact step is analysed into the event digests only the recording produced, those only the replay produced, and the components they belong to, with live model calls named as a component of their own.

Designing an experiment

An experiment definition is JSON with five parts: config (cognitive configuration overrides by field name), personality (section-by-section overrides), stimuli (a list of observations with text, optional source and salience), expected (event types that should or should not appear, optionally containing a phrase) and a seed and duration_seconds for provenance and bounding. The run forks the baseline snapshot into a disabled subject mind, applies overrides, feeds the stimuli one at a time until the mind settles after each, and records events by type, produced-event digests per stimulus, the subject's beliefs, memory and goal counts, expectation outcomes, model-call counts and the LLM role routing in force. Results are stored, shown in the interface, exportable with an archive of the subject, and the subject stays for comparison with the baseline.

An experiment may instead declare variants: named override sets, each becoming its own fork of the same snapshot and receiving the same stimuli. A variant can change configuration, personality and, through llm_roles, the model used for each role for that fork only; a missing or disabled model fails the variant rather than falling back silently. The results hold one entry per variant and a deterministic comparison: the first stimulus at which any two diverged, belief overlap and mean score difference on shared propositions, attention overlap, and the ranges of memory, goal, cost and capability-request counts.

Typical experiments: memory decay on and off, dreaming on and off, two personalities on the same stimuli, different attention weights, and the same mind under two providers.