Home / Outcome & policy

Did the task happen, or just get claimed?

Whether it happened is a question for the trace and the system of record.

The evidence checklist

Eleven deterministic ways to prove a task ran.

Every outcome kind is regex, checksum, or a span or state lookup. Each reads a source of record; each carries deterministic: true, including when it returns INCONCLUSIVE.

outcome & workflow assertion kinds
kindwhat it readsexample verdict
outcomea composite over the sub-predicates below, as a met / of fractionmet 3 / of 3 → pass
tool_callthe ingested trace spans, never the transcriptissue_refund span present → pass
tool_resulta tool’s returned value, from the tracerefund result ok → pass
tool_errora tool’s raised error, from the tracecharge raised timeout → fail
statea state adapter snapshot: the system of recordbalance shows the credit → pass
state_changea before / after delta (mock adapter)balance moved by the refund → pass
handoffa transfer span in the traceescalated to a human → pass
dtmfa keypad-tone span in the trace1-2-3-4 collected → pass
terminationhow the call ended, from the traceended by caller hang-up → pass
sequencean ordered set of steps across toolslookup before refund → pass
counta bounded number of occurrencesat most one refund → pass
Eleven of the seventeen deterministic kinds carry the Outcome dimension. Policy carries two more.
Missing input is never a guessed fail A tool_call with no trace at all reports INCONCLUSIVE. A tool_call against a trace that was ingested and holds zero spans is a grounded FAIL. The distinction is structural.
score one call against the file
$ hotato test run conversation-test.yaml --agent support-bot
Authority 1 · trace spans

What the agent did.

tool_result and tool_error read the authenticated voice_trace. The span is the evidence a tool ran.

Authority 2 · system of record

What your data shows.

state and state_change query a post-call state adapter: your DB or API. Absent adapter → INCONCLUSIVE.

Authority 3 · human-verified

What a person confirmed.

An Ed25519-signed human label record. The final word for the call a machine cannot settle on its own.

Where a verdict comes from

Three authorities: the trace, your data, a human.

An outcome is only as good as what it reads. Hotato grounds each verdict in one of three sources, and structurally cannot read a fourth.

A state query has three outcomes: the record matches (PASS), the record was read and holds no such row (a grounded FAIL), or the record could not be reached (INCONCLUSIVE, with a reason). Hotato never invents a verdict from a state it could not observe.

The wall

A model’s opinion never wears Authority 1 or 2.

The evaluators read the trace and the state adapter by construction. A model verdict lives only in the advisory rubric lane, marked deterministic:false: it describes how a call sounded, and leaves certifying that the refund posted to the deterministic lane.

When the state adapter is missing, the Outcome dimension stays INCONCLUSIVE and visible on the page.

The advisory lane in full →

conversation-test.v1 · agent support-bot · call 8f2a
Outcomerefund posted · state adapterAuthority 2pass
tool_resultissue_refund returned ok · traceAuthority 1pass
stateno adapter suppliedAuthority 2inconclusive
Model judge“sounded confident it refunded”advisoryadvisory
The judge reads words. Authority 1 and 2 read the trace and the record. The lanes never cross.
assertions.yamldeterministic
version: 1
assertions:
  - id: disclosure-and-language
    kind: policy        # banned language + required disclosures
    dimension: policy   # a named, versioned, offline pack
  - id: workflow-order
    kind: tool_call     # from the ingested trace
    require_order: [verify_identity, lookup_account, issue_refund]
    never_before: {tool: issue_refund, until: verify_identity}
  • policy pack · versioned
  • tool_call · required order
  • value never echoed
Policy

Did it follow the rules? Same evidence, same lane.

Policy rides with Outcome. A named, versioned, offline policy pack checks banned language and required disclosures; a tool_call assertion holds the workflow to its required order and its “never before” constraints.

It is checked by the same deterministic machinery that grounds every outcome. No model runs; the result is byte-stable on a fixed version.

Outcome answers whether the task happened. Conversation checks whether it listened; Speech checks what was said.