Tarski/ docsJoin the waitlist

Agents, interfaces & models

Declare agent roles, typed session starts, model resources, review routing, and headless model consultations.

An agent declaration is a product role over ordinary Tarski primitives: a projection it may read, a write policy for evidence it may append, and capabilities it may request. Models are tools used by that role. Their output re-enters as recorded evidence or proposals and cannot bypass ontology decisions.

The manifest surface below is supported on the 0.5.9-preview release line. Run tarski agent inspect <agent> --json to inspect the effective package contract after imports and overlays.

Interfaces and session start

[agents.member_support]
description = "Answers questions inside account-gated sessions."
reads = "member_portal"
write_policy = "member_chat_message"
proposers = ["assistant_reply_generator"]
contributes_to = ["chat.assistant_message"]
capabilities = ["llm.complete"]

[agents.member_support.interfaces.member_chat]
type = "chat"
append_target = "request"
lineage_policy = "shared"
session_key = "session_id"
input_observation = "chat.user_message"
output_relation = "chat.assistant_message"
terminal_predicate = "chat.message_answered"
terminal_key = ["session_id", "message_id"]
projection = "member_portal"
write_policy = "member_chat_message"
run = "until_quiescent"
streaming = "state_events"

[agents.member_support.interfaces.member_chat.ambient_context]
projection = "member_portal"

[agents.member_support.interfaces.member_chat.session_start]
observation_kind = "access.grant"
append_target = "request"
create_lineage = true
source = "agent-interface-session-start"
required_actor_context = ["actor_id", "actor_kind"]
start_write_policy = "member_session_start"
payload_bindings = [
  { field = "actor_id", value = "actor.actor_id" },
  { field = "session_id", value = "session.session_id" },
]

[agents.member_support.interfaces.member_chat.session_start.idempotency]
mode = "required"
key_fields = ["agent_id", "interface_id", "actor.actor_id", "session.session_id"]

session_start is a typed append, not a hidden session-row mutation. Trusted actor bindings come from verified ingress context; client payloads cannot assert them. Declare session_authentication when every subsequent request must re-check a current access.* fact.

Every model-bound interface or proposer must declare ambient_context or the explicit full_worldview = true grant. The resulting context manifest records the prompt, schema, projection, world-slice, query-result, actor-context, and request digests—the exact evidence of what the model saw.

Model resources and result observations

The resource namespace is [resources.model.*], not [resources.llm.*]:

[capabilities]
models = ["assistant_model"]

[capabilities.intents]
"intent.assistant_reply_requested" = {
  capability = "llm.complete",
  resource = "assistant_model",
  result_kind = "llm.assistant_reply_result",
  identity_keys = ["session_id", "message_id"],
  interface = "member_chat"
}

[resources.model.assistant_model]
provider = "openai"
model = "gpt-5.4-mini-2026-03-17"
schema = "schemas/assistant-reply.json"
credential_ref = "OPENAI_API_KEY"
replay = "record"

The provider result is validated against the named schema and appended under result_kind with source capability:llm.complete. It carries the effect request identity, attempt and capture metadata, and the correlation fields you placed in the intent contract. A mapper turns that recorded payload into candidate.* or proposal.*; rules ratify it before trusted facts or world-facing intents exist.

Put domain correlation such as session_id, message_id, or consultation_id in the intent tuple and include stable identity fields in identity_keys. Do not depend on ambient runtime timestamps or an undocumented provider field.

Review routing and headless consultation

decision.requires_review.<domain>.<action> is an ontology outcome. A review-opening intent derived from it must be explicitly tagged on the capability binding:

[capabilities.intents]
"intent.agent_review_open_requested" = {
  capability = "http.fetch",
  resource = "review_api",
  review_routing = true
}

This tag authorizes only the review-routing effect. It never authorizes the reviewed world-facing action.

For an interface-less agent turn that consults the model, use an llm.complete binding with model_consultation = true, stable identity_keys, and an application correlation id in the intent. If the turn uses governed worldview queries, also declare worldview_query = true and bind intent.query_execute. Query results re-enter as observations and reserved queryresult.* rows before the next consultation turn.

"intent.impact_assessment_requested" = {
  capability = "llm.complete",
  resource = "assessment_model",
  result_kind = "llm.impact_assessment_result",
  identity_keys = ["consultation_id", "phase"],
  model_consultation = true
}

model_consultation is valid only for llm.complete; other capabilities fail package load. It allows the consultation loop to continue from settled query-relay lifecycle evidence without pretending that an LLM response is an approved external action.