Tarski/ docsJoin the waitlist

Declared queries

The named, typed, parameterized read surface over your derived worldview — authoring, exposure, validation, and the query engine underneath.

Declared queries are Tarski’s read surface: each queries/*.ta file declares one named, typed, parameterized query over the app’s derived worldview. They are validated at load time against relation declarations, projections, and decision-rule coverage — and they are the only query form agent models may request. Free-form Datalog stays reserved for authorized humans and dev surfaces.

Authoring a query

query "impacted-services"
description "Services inside one root cause's blast radius, joined with whether each service is itself reporting degraded health."
parameter root_service: text "The root-cause service whose blast radius to read."
expose agent, studio

head (service_id: text, health: text)

relation radius_member(service_id: text)

rule radius_member(service_id) :-
  triage.blast_radius(service_id, root_service).

rule result(service_id, "degraded") :-
  radius_member(service_id),
  infra.degraded(service_id).
  • query "name" — quoted kebab-case, mapped to a snake_case relation name; collisions fail the load.
  • description and parameter doc strings flow verbatim to discovery surfaces — Studio’s schema browser, MCP tool descriptions, GET /v1/queries. They are not part of query identity.
  • parameter — typed binding sites; executions with missing, unknown, or mis-typed bindings are rejected before evaluation.
  • expose — which doors can reach the query: agent, api, studio, mcp. No exposure means private: loadable and validated, reachable from nowhere.
  • head and result — the typed result signature and the reserved relation your rules derive into.

Queries are full Datalog programs, so chained lookups collapse into one pre-joined compound query — the preferred pattern over multiple round trips. Manifest wiring: [paths] queries = ["queries/*.ta"]. Load-time validation uses stable diagnostics (E1040E1047 parse, E2601E2611 validation), and edits hot-reload under tarski dev.

Agent exposure requires decision coverage

An agent-exposed query is a read a model can request — so it needs an explicit policy: a decision.approved.* rule with a positive dependency on the query’s typed proposal relation (proposal.query_requested.<mapped_name>). A deny-only policy must be acknowledged in the manifest ([queries."name"] deny_only = true). The full read loop — budgets, denials, result gating — is on the agent query relay.

The engine underneath

Every query — declared or ad-hoc — compiles into an isolated micro-program that runs against an immutable snapshot of committed facts at a pinned head, reusing the evaluator’s own compilation and rule machinery. Query semantics match ontology semantics by construction.

  • Projection-scoped reads. Scoping happens by constructing the query’s input database: rows outside the caller’s projection are absent, not redacted in place. Negation cannot probe hidden rows, and explain output never reveals hidden counts.
  • Pinned heads. The default is the current committed head; historical committed heads re-materialize deterministically; a never-committed head fails closed with a typed diagnostic — never a silently different head.
  • Deterministic envelopes. Results carry canonical rows in a stable order plus the full identity stamp: snapshot identity, projection identity, and query, binding, and result digests. Row provenance is drillable — positive supports as committed fact ids, aggregates with input-set witnesses, negation-dependent rows with re-checkable absence witnesses.
  • Explain. A deterministic artifact naming strata, per-rule plans, join order, index selection, and relation row counts — digest-stable for the same query at the same head.
  • Bounds. Result rows, evaluation steps, memory, and wall-clock all fail closed with typed diagnostics; windowed pagination uses continuation tokens bound to execution identity, disjoint and exhaustive at a pinned head.

Running queries

tarski query booking-status --bindings '{"date":"2026-07-22"}'
tarski query impacted-services --bindings '{"root_service":"payments"}' --explain
tarski query --adhoc-file exploration.ta --head 41

The CLI door runs audited, unpaginated, complete canonical results. Over HTTP, tarski serve exposes GET /v1/queries (discovery), POST /v1/queries/{name}/execute, POST /v1/queries/{name}/explain, and scope-gated POST /v1/queries/adhoc. For coding agents, tarski mcp serves a read-only MCP server over stdio — it refuses to start without --actor-id and --projection. Every door, its authorization ladder, and the access-audit plane are documented in Identity & tenancy and the CLI reference.

Identity discipline

Full query files join the package digest, but only an agent-exposed query’s result relation signature (name, head columns, parameters) joins the evaluator digest — result observations must be interpreted into atoms, so their shape is semantic. Body and description edits never rotate the evaluator identity, and spectator-only queries never touch it at all. See Worldviews & lineages.