Project structure
A Tarski app is a directory of text files interpreted by one binary — the manifest, ontology, mappers, helpers, queries, and fixtures, and what each is responsible for.
A Tarski app is a directory of text files — .ta ontology, Rhai mappers and helpers, a
TOML manifest, prompts, JSON schemas, and JSONL fixtures — interpreted directly by the
tarski binary. App developers never need Rust, Cargo, or a compile step, and the dev
loop hot-reloads every asset.
The layout
my-app/
tarski.toml # the manifest
ontology/
schema.ta # relation declarations
rules.ta # derivation rules, decisions
intents.ta # intent derivation, invariants
queries/
slot-overview.ta # declared worldview queries
pending-requests.ta
mappings/
inbound.rhai # observation → typed atoms
helpers/
normalize.rhai # pure helper functions
prompts/ # model/tool boundary prompts
schemas/ # JSON schemas for payloads
fixtures/
happy-path.jsonl # observation timeline
happy-path.expected.json # the exact expected world
README.md
.agents/skills/tarski-expert/ # agent guidance, version-matched
.claude/skills/tarski-expert/
Scaffolded apps also ship a tarski-expert skill in .agents/ and .claude/ — guidance
that teaches coding agents the platform’s authoring model, versioned to match your CLI.
See Authoring with agents.
What each asset owns
| Asset | Responsibility | Evidence it produces |
|---|---|---|
tarski.toml |
Paths, app identity, standard-library pin, capabilities, intent bindings, retry policies, schedules, plugins | Manifest diagnostics, verification report, package digest |
ontology/*.ta |
Relations, rules, decisions, invariants, intents | Parser/validator diagnostics, fixture fixed points, contradiction evidence |
queries/*.ta |
Declared, parameterized worldview reads with door exposure | Query catalog and digests, explain artifacts, relay fixtures |
mappings/*.rhai |
The observation-to-atom boundary — deterministic, structural | Mapper output digest, clean replay |
helpers/*.rhai |
Pure, capability-free domain helpers callable from rules | Helper digest, local/hosted parity |
prompts/, schemas/ |
Model and tool boundaries | Capture-envelope validation |
fixtures/ |
Golden timelines and exact expected worlds | tarski test, tarski verify, bless refusal or success |
The manifest
tarski.toml is where structure becomes explicit. The keys you will meet early:
[paths]
queries = ["queries/*.ta"]
[capabilities]
worldview_query = true # enable the agent read relay
[capabilities.intents."intent.query_execute"]
capability = "worldview.query"
identity_keys = ["session_id", "request_id"]
[schedules.hourly-refresh] # standing schedules (optional)
cron = "0 * * * ?"
[analysis.monotonicity] # declared CALM expectations (optional)
expect_monotone = ["workspace.open_task"]
Capabilities are the only route to the outside world — apps declare http.fetch,
llm.complete, blob.put/blob.get, timer.schedule, or log.dev bindings instead of
performing ambient I/O. Retry policies, review-routing markers (review_routing = true),
and model-consultation markers (model_consultation = true) also live on intent bindings.
See Effects.
The standard helper library
helper.std.* is a reserved, version-pinned platform helper namespace available to rules:
trimming, case folding and whitespace collapse, email normalization, URL host/path
extraction, slug and identifier normalization, fixed-offset ISO-8601 parsing, integer
duration arithmetic, and SHA-256 identity minting. The pinned version’s content digest
joins your evaluator identity, so helper behavior never changes under an existing pin.