Write policies
Admit observations before append with explicit actor, payload, target, metadata, and idempotency bindings.
Write policies are Tarski’s pre-append security boundary. A policy decides whether one named writer may append one exact observation kind to one target. A denial leaves no observation or relay evidence behind, so unauthorized data never becomes canonical truth.
This reference describes the contract introduced with tarski 0.5.9-preview.8.
Bindings, selection, and extension
[write_policies.customer_message]
description = "A customer may write only to a session they can access."
writer_kind = "client"
append_target = "chat:{session_id}"
required_metadata = ["actor_id", "actor_kind", "session_id"]
on_denied = "reject_append"
[[write_policies.customer_message.direct_observations]]
kind = "chat.user_message"
allow = "access.chat_message_append_allowed"
args = ["actor.actor_id", "payload.session_id"]
[write_policies.customer_message.idempotency]
mode = "required"
key_field = "payload.message_id"
At append time the caller explicitly selects customer_message. Tarski evaluates only
that policy:
direct_observations[].kindis an exact string.contact.*globs are rejected.- A direct observation entry without
allowis a static, unconditional grant, but only after that named policy is selected. Required metadata, target, and idempotency still apply. - An
allowrelation succeeds when the current worldview contains the requested tuple. The tuple may come from a rule or a staticassert; its origin does not change policy semantics. actor.*values come from trusted ingress context. Nestedpayload.*values may be lookup arguments, but never become authority by themselves. Missing fields and wrong scalar types deny the append.- Delegated platform-builder contexts can bind
actor.tier,actor.issuing_authority.authority_id, andactor.delegation_chain.tenant_organization.
Two policies may name the same exact kind. This is useful for separate writer roles, but it never means “any policy may allow”: only the explicitly selected policy is evaluated.
Imported or package-owned policies are immutable. To extend one, declare a new complete policy containing the original and additional kinds, then rebind the interface or ingress to the new policy. Tarski does not merge policy fragments across packages.
Relay writers use writes for reserved candidate.* and proposal.* evidence; this is
the one write-policy surface where namespace globs are supported. contributes_to
documents what the ontology may eventually derive. Neither field lets a writer append a
trusted fact or executable intent directly.
Inspect the effective policy
Do not reverse-engineer package overlays. Tarski generates the selected policy contract:
tarski agent inspect support_agent --json
tarski agent interface inspect support_agent customer_chat --json
Read write_policy_contract for the effective policy id and digest, exact kinds,
conditional versus static entries, target, arguments, required metadata, idempotency,
relay writes, overlap semantics, and package-extension rules.
Actor context and expected denials in fixtures
JSONL fixtures can exercise the real pre-append boundary with a
fixture.write_policy_attempt control record:
{"kind":"fixture.write_policy_attempt","payload":{"lineage_id":"chat:s1","policy_id":"customer_message","observation":{"kind":"chat.user_message","payload":{"session_id":"s1","message_id":"m-denied","text":"must not enter truth"}},"actor":{"actor_id":"user:other","actor_kind":"human","session_id":"s1"},"expected_denial":{"code":"write_policy_denied","message_contains":"denied observation kind"}}}
The outer record is a test instruction, not an observation. During tarski verify, the
runner evaluates the named policy against the preceding fixture world and actor context.
The test passes only when the denial code and optional message fragment match. Neither
the control record nor the denied observation enters the replay timeline.
Put allowed and denied attempts in the same scenario when the boundary depends on ontology-derived access facts. This proves both the positive permission and the absence of leaked evidence under one deterministic world.