Mappers & observations
The deterministic boundary where raw events become typed evidence — Rhai mappers, pure helpers, and deterministic effect providers.
Observations enter Tarski as raw evidence — a chat message, a webhook payload, a provider receipt, a schedule fire. Mappers are the deterministic structural boundary that turns each observation into typed atom batches: the ontology’s inbox.
Mappers
Mappers are written in Rhai (mappings/*.rhai) and are deliberately constrained:
- Deterministic and structural. A mapper sees one observation and emits typed atoms. Same observation, same atoms — the mapper output digest is part of replay identity.
- No I/O. Mappers cannot fetch, call models, or read ambient state.
- Atoms are not truth. A mapper may emit atom-origin
candidate.*orproposal.*evidence when the app declares those relations, but it can never write trusted facts, decisions, or executable intents — those are derived-only namespaces.
If a behavior is wrong and the observation is right, but the atom is wrong, the mapper is the thing to fix. That locality is the point.
Helpers
Helpers (helpers/*.rhai) are pure, capability-free functions callable from ontology
rules — normalization, parsing, identity minting. The platform’s own
helper.std.* standard library is
version-pinned, and app helper digests join the evaluator identity, so helper behavior is
part of the semantic contract, not an implementation detail.
Hiding I/O in a helper is one of the classic mistakes the loader and verifier are built to catch — helpers that do I/O would silently break replay.
Deterministic effect providers
Fixtures need to exercise external-effect shapes without the network. A deterministic effect provider is a Rhai script that stands in for a live provider (an HTTP API, an LLM) during fixture replay, with a documented contract: a named entrypoint, the capture envelope shape, and run-pinned values.
Pre-dispatch provider errors — a compile error, a missing entrypoint, an invalid
envelope — are classified as typed provider_config_failure. They are explicitly not
ambiguous effects: they never enter manual reconciliation, and fixing the script changes
its configuration digest and re-admits the intent.
Live and deterministic modes never blur: a live example missing its credential surfaces a
visible warning or a typed http.credential.unresolved block — never a silent fallback to
deterministic output.
Provider record/replay
For live providers, Tarski captures external-call envelopes with redaction and replay
identity. Recorded envelopes let tarski verify replay LLM-assisted behavior
deterministically — and because every model-context section digest joins the request
digest, a capture envelope proves byte-for-byte what a model saw. See
Model context & the agent relay.
Append envelope metadata and identifiers
The runtime appends one ordered batch to one lineage through a linearizable expected-head compare-and-set. A successful batch receives contiguous observation ids and advances the head only after the whole batch is durable. This is the boundary to use when an invariant would reject a transient prefix such as organization genesis.
The generated client currently contracts no batch idempotency, however. If the transport outcome is unknown, do not blindly retry the same batch: reconcile the head/receipt or use individually idempotent appends. Single-append idempotency is scoped by lineage, source, and key; a matching retry returns the original receipt and conflicting reuse fails closed.
Tarski owns the append envelope:
observation_idis the canonical per-lineage order and is assigned by the sequencer.observed_atis a canonical UTC millisecond instant assigned by the append authority. Live clients may not set it. Replay/import preserves its recorded value.- Rhai mappers read it as
obs.observed_at; rules can join a typed atom’satom_idtoatom.observed_at(atom_id, observed_at). - Trusted actor context is evaluated at write-policy admission and recorded by digest and
audit receipt. It is not an ambient mapper object. When actor identity is domain
evidence, bind a trusted
actor.*value into a session-start or admitted observation payload at the ingress contract. - Domain event time remains an ordinary payload field and must be mapped explicitly.
A mapper may ignore payload fields. The complete observation payload remains immutable raw evidence and provenance still reaches it, but ignored fields do not become atoms, cannot be queried as facts, and cannot affect the model. This is a safe place for an opaque provenance rider only while no rule or policy depends on it; promote a field into a typed atom as soon as it gains semantic meaning.
Rules and helpers have no random/ULID generator. Supply application ids in input evidence or derive a documented content identity from stable fields. Sha-derived ids are suitable only when equal semantic inputs are intentionally the same identity; do not use them to collapse equal but distinct events.