Tarski/ docsJoin the waitlist

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.* or proposal.* 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_id is the canonical per-lineage order and is assigned by the sequencer.
  • observed_at is 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’s atom_id to atom.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.